From 9e636855b582d1499a87fb73f55d85102ce95a58 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 12 Dec 2023 20:28:40 -0800 Subject: [PATCH 001/553] [Parser] Parse the remaining array operations (#6158) Parse `array.new_elem`, `array.init_data`, and `array.init_elem`. Accidentally also includes: * [Parser] Parse string types and operations (#6161) --- src/parser/contexts.h | 115 +++++- src/parser/input-impl.h | 4 +- src/parser/input.h | 2 +- src/parser/parsers.h | 93 ++++- src/wasm-ir-builder.h | 32 +- src/wasm.h | 15 + src/wasm/wasm-ir-builder.cpp | 186 +++++++++- test/lit/wat-kitchen-sink.wast | 639 ++++++++++++++++++++++++++++----- 8 files changed, 941 insertions(+), 145 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 15b82fe646f..620d10d6093 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -104,6 +104,10 @@ struct NullTypeParserCtx { HeapTypeT makeI31() { return Ok{}; } HeapTypeT makeStructType() { return Ok{}; } HeapTypeT makeArrayType() { return Ok{}; } + HeapTypeT makeStringType() { return Ok{}; } + HeapTypeT makeStringViewWTF8Type() { return Ok{}; } + HeapTypeT makeStringViewWTF16Type() { return Ok{}; } + HeapTypeT makeStringViewIterType() { return Ok{}; } TypeT makeI32() { return Ok{}; } TypeT makeI64() { return Ok{}; } @@ -190,6 +194,10 @@ template struct TypeParserCtx { HeapTypeT makeI31() { return HeapType::i31; } HeapTypeT makeStructType() { return HeapType::struct_; } HeapTypeT makeArrayType() { return HeapType::array; } + HeapTypeT makeStringType() { return HeapType::string; } + HeapTypeT makeStringViewWTF8Type() { return HeapType::stringview_wtf8; } + HeapTypeT makeStringViewWTF16Type() { return HeapType::stringview_wtf16; } + HeapTypeT makeStringViewIterType() { return HeapType::stringview_iter; } TypeT makeI32() { return Type::i32; } TypeT makeI64() { return Type::i64; } @@ -284,8 +292,9 @@ struct NullInstrParserCtx { using FuncIdxT = Ok; using LocalIdxT = Ok; using TableIdxT = Ok; - using GlobalIdxT = Ok; using MemoryIdxT = Ok; + using GlobalIdxT = Ok; + using ElemIdxT = Ok; using DataIdxT = Ok; using LabelIdxT = Ok; using TagIdxT = Ok; @@ -310,6 +319,8 @@ struct NullInstrParserCtx { TableIdxT getTableFromName(Name) { return Ok{}; } MemoryIdxT getMemoryFromIdx(uint32_t) { return Ok{}; } MemoryIdxT getMemoryFromName(Name) { return Ok{}; } + ElemIdxT getElemFromIdx(uint32_t) { return Ok{}; } + ElemIdxT getElemFromName(Name) { return Ok{}; } DataIdxT getDataFromIdx(uint32_t) { return Ok{}; } DataIdxT getDataFromName(Name) { return Ok{}; } LabelIdxT getLabelFromIdx(uint32_t, bool) { return Ok{}; } @@ -458,7 +469,7 @@ struct NullInstrParserCtx { return Ok{}; } template - Result<> makeArrayNewElem(Index, HeapTypeT, DataIdxT) { + Result<> makeArrayNewElem(Index, HeapTypeT, ElemIdxT) { return Ok{}; } template @@ -479,7 +490,28 @@ struct NullInstrParserCtx { template Result<> makeArrayFill(Index, HeapTypeT) { return Ok{}; } + template + Result<> makeArrayInitData(Index, HeapTypeT, DataIdxT) { + return Ok{}; + } + template + Result<> makeArrayInitElem(Index, HeapTypeT, ElemIdxT) { + return Ok{}; + } Result<> makeRefAs(Index, RefAsOp) { return Ok{}; } + Result<> makeStringNew(Index, StringNewOp, bool, MemoryIdxT*) { return Ok{}; } + Result<> makeStringConst(Index, std::string_view) { return Ok{}; } + Result<> makeStringMeasure(Index, StringMeasureOp) { return Ok{}; } + Result<> makeStringEncode(Index, StringEncodeOp, MemoryIdxT*) { return Ok{}; } + Result<> makeStringConcat(Index) { return Ok{}; } + Result<> makeStringEq(Index, StringEqOp) { return Ok{}; } + Result<> makeStringAs(Index, StringAsOp) { return Ok{}; } + Result<> makeStringWTF8Advance(Index) { return Ok{}; } + Result<> makeStringWTF16Get(Index) { return Ok{}; } + Result<> makeStringIterNext(Index) { return Ok{}; } + Result<> makeStringIterMove(Index, StringIterMoveOp) { return Ok{}; } + Result<> makeStringSliceWTF(Index, StringSliceWTFOp) { return Ok{}; } + Result<> makeStringSliceIter(Index) { return Ok{}; } }; // Phase 1: Parse definition spans for top-level module elements and determine @@ -968,6 +1000,7 @@ struct ParseDefsCtx : TypeParserCtx { using GlobalIdxT = Name; using TableIdxT = Name; using MemoryIdxT = Name; + using ElemIdxT = Name; using DataIdxT = Name; using TagIdxT = Name; @@ -1141,6 +1174,20 @@ struct ParseDefsCtx : TypeParserCtx { return name; } + Result getElemFromIdx(uint32_t idx) { + if (idx >= wasm.elementSegments.size()) { + return in.err("elem index out of bounds"); + } + return wasm.elementSegments[idx]->name; + } + + Result getElemFromName(Name name) { + if (!wasm.getElementSegmentOrNull(name)) { + return in.err("elem $" + name.toString() + " does not exist"); + } + return name; + } + Result getDataFromIdx(uint32_t idx) { if (idx >= wasm.dataSegments.size()) { return in.err("data index out of bounds"); @@ -1658,9 +1705,73 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeArrayFill(type)); } + Result<> makeArrayInitData(Index pos, HeapType type, Name data) { + return withLoc(pos, irBuilder.makeArrayInitData(type, data)); + } + + Result<> makeArrayInitElem(Index pos, HeapType type, Name elem) { + return withLoc(pos, irBuilder.makeArrayInitElem(type, elem)); + } + Result<> makeRefAs(Index pos, RefAsOp op) { return withLoc(pos, irBuilder.makeRefAs(op)); } + + Result<> makeStringNew(Index pos, StringNewOp op, bool try_, Name* mem) { + auto m = getMemory(pos, mem); + CHECK_ERR(m); + return withLoc(pos, irBuilder.makeStringNew(op, try_, *m)); + } + + Result<> makeStringConst(Index pos, std::string_view str) { + return withLoc(pos, irBuilder.makeStringConst(Name(str))); + } + + Result<> makeStringMeasure(Index pos, StringMeasureOp op) { + return withLoc(pos, irBuilder.makeStringMeasure(op)); + } + + Result<> makeStringEncode(Index pos, StringEncodeOp op, Name* mem) { + auto m = getMemory(pos, mem); + CHECK_ERR(m); + return withLoc(pos, irBuilder.makeStringEncode(op, *m)); + } + + Result<> makeStringConcat(Index pos) { + return withLoc(pos, irBuilder.makeStringConcat()); + } + + Result<> makeStringEq(Index pos, StringEqOp op) { + return withLoc(pos, irBuilder.makeStringEq(op)); + } + + Result<> makeStringAs(Index pos, StringAsOp op) { + return withLoc(pos, irBuilder.makeStringAs(op)); + } + + Result<> makeStringWTF8Advance(Index pos) { + return withLoc(pos, irBuilder.makeStringWTF8Advance()); + } + + Result<> makeStringWTF16Get(Index pos) { + return withLoc(pos, irBuilder.makeStringWTF16Get()); + } + + Result<> makeStringIterNext(Index pos) { + return withLoc(pos, irBuilder.makeStringIterNext()); + } + + Result<> makeStringIterMove(Index pos, StringIterMoveOp op) { + return withLoc(pos, irBuilder.makeStringIterMove(op)); + } + + Result<> makeStringSliceWTF(Index pos, StringSliceWTFOp op) { + return withLoc(pos, irBuilder.makeStringSliceWTF(op)); + } + + Result<> makeStringSliceIter(Index pos) { + return withLoc(pos, irBuilder.makeStringSliceIter()); + } }; } // namespace wasm::WATParser diff --git a/src/parser/input-impl.h b/src/parser/input-impl.h index 7ee358f128c..0f8fc2e86d4 100644 --- a/src/parser/input-impl.h +++ b/src/parser/input-impl.h @@ -226,11 +226,11 @@ inline std::optional ParseInput::takeF32() { return std::nullopt; } -inline std::optional ParseInput::takeString() { +inline std::optional ParseInput::takeString() { if (auto t = peek()) { if (auto s = t->getString()) { ++lexer; - return s; + return std::string(*s); } } return {}; diff --git a/src/parser/input.h b/src/parser/input.h index 5cb2bd4717f..dbf3e486857 100644 --- a/src/parser/input.h +++ b/src/parser/input.h @@ -59,7 +59,7 @@ struct ParseInput { std::optional takeU8(); std::optional takeF64(); std::optional takeF32(); - std::optional takeString(); + std::optional takeString(); std::optional takeName(); bool takeSExprStart(std::string_view expected); bool peekSExprStart(std::string_view expected); diff --git a/src/parser/parsers.h b/src/parser/parsers.h index be8db49a96f..4909ad05751 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -176,6 +176,8 @@ template MaybeResult maybeMemidx(Ctx&); template Result memidx(Ctx&); template MaybeResult maybeMemuse(Ctx&); template Result globalidx(Ctx&); +template Result elemidx(Ctx&); +template Result dataidx(Ctx&); template Result localidx(Ctx&); template Result labelidx(Ctx&, bool inDelegate = false); @@ -249,6 +251,18 @@ template Result heaptype(Ctx& ctx) { if (ctx.in.takeKeyword("array"sv)) { return ctx.makeArrayType(); } + if (ctx.in.takeKeyword("string"sv)) { + return ctx.makeStringType(); + } + if (ctx.in.takeKeyword("stringview_wtf8"sv)) { + return ctx.makeStringViewWTF8Type(); + } + if (ctx.in.takeKeyword("stringview_wtf16"sv)) { + return ctx.makeStringViewWTF16Type(); + } + if (ctx.in.takeKeyword("stringview_iter"sv)) { + return ctx.makeStringViewIterType(); + } auto type = typeidx(ctx); CHECK_ERR(type); return *type; @@ -282,7 +296,19 @@ template MaybeResult reftype(Ctx& ctx) { return ctx.makeRefType(ctx.makeStructType(), Nullable); } if (ctx.in.takeKeyword("arrayref"sv)) { - return ctx.in.err("arrayref not yet supported"); + return ctx.makeRefType(ctx.makeArrayType(), Nullable); + } + if (ctx.in.takeKeyword("stringref"sv)) { + return ctx.makeRefType(ctx.makeStringType(), Nullable); + } + if (ctx.in.takeKeyword("stringview_wtf8"sv)) { + return ctx.makeRefType(ctx.makeStringViewWTF8Type(), Nullable); + } + if (ctx.in.takeKeyword("stringview_wtf16"sv)) { + return ctx.makeRefType(ctx.makeStringViewWTF16Type(), Nullable); + } + if (ctx.in.takeKeyword("stringview_iter"sv)) { + return ctx.makeRefType(ctx.makeStringViewIterType(), Nullable); } if (!ctx.in.takeSExprStart("ref"sv)) { @@ -1584,7 +1610,11 @@ template Result<> makeArrayNewData(Ctx& ctx, Index pos) { } template Result<> makeArrayNewElem(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto type = typeidx(ctx); + CHECK_ERR(type); + auto elem = elemidx(ctx); + CHECK_ERR(elem); + return ctx.makeArrayNewElem(pos, *type, *elem); } template Result<> makeArrayNewFixed(Ctx& ctx, Index pos) { @@ -1629,11 +1659,18 @@ template Result<> makeArrayFill(Ctx& ctx, Index pos) { } template Result<> makeArrayInitData(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto type = typeidx(ctx); + CHECK_ERR(type); + auto data = dataidx(ctx); + CHECK_ERR(data); + return ctx.makeArrayInitData(pos, *type, *data); } template Result<> makeArrayInitElem(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto type = typeidx(ctx); + CHECK_ERR(type); + auto elem = elemidx(ctx); + return ctx.makeArrayInitElem(pos, *type, *elem); } template Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { @@ -1642,61 +1679,69 @@ template Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { template Result<> makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) { - return ctx.in.err("unimplemented instruction"); + auto mem = maybeMemidx(ctx); + CHECK_ERR(mem); + return ctx.makeStringNew(pos, op, try_, mem.getPtr()); } template Result<> makeStringConst(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto str = ctx.in.takeString(); + if (!str) { + return ctx.in.err("expected string"); + } + return ctx.makeStringConst(pos, *str); } template Result<> makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringMeasure(pos, op); } template Result<> makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { - return ctx.in.err("unimplemented instruction"); + auto mem = maybeMemidx(ctx); + CHECK_ERR(mem); + return ctx.makeStringEncode(pos, op, mem.getPtr()); } template Result<> makeStringConcat(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringConcat(pos); } template Result<> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringEq(pos, op); } template Result<> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringAs(pos, op); } template Result<> makeStringWTF8Advance(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringWTF8Advance(pos); } template Result<> makeStringWTF16Get(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringWTF16Get(pos); } template Result<> makeStringIterNext(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringIterNext(pos); } template Result<> makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringIterMove(pos, op); } template Result<> makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringSliceWTF(pos, op); } template Result<> makeStringSliceIter(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeStringSliceIter(pos); } // ======= @@ -1843,8 +1888,20 @@ template Result globalidx(Ctx& ctx) { return ctx.in.err("expected global index or identifier"); } +// elemidx ::= x:u32 => x +// | v:id => x (if elems[x] = v) +template Result elemidx(Ctx& ctx) { + if (auto x = ctx.in.takeU32()) { + return ctx.getElemFromIdx(*x); + } + if (auto id = ctx.in.takeID()) { + return ctx.getElemFromName(*id); + } + return ctx.in.err("expected elem index or identifier"); +} + // dataidx ::= x:u32 => x -// | v:id => x (if data[x] = v) +// | v:id => x (if datas[x] = v) template Result dataidx(Ctx& ctx) { if (auto x = ctx.in.takeU32()) { return ctx.getDataFromIdx(*x); diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index a7e36bd1060..8b01977be3a 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -181,22 +181,22 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeArrayLen(); [[nodiscard]] Result<> makeArrayCopy(HeapType destType, HeapType srcType); [[nodiscard]] Result<> makeArrayFill(HeapType type); - // [[nodiscard]] Result<> makeArrayInitData(); - // [[nodiscard]] Result<> makeArrayInitElem(); + [[nodiscard]] Result<> makeArrayInitData(HeapType type, Name data); + [[nodiscard]] Result<> makeArrayInitElem(HeapType type, Name elem); [[nodiscard]] Result<> makeRefAs(RefAsOp op); - // [[nodiscard]] Result<> makeStringNew(); - // [[nodiscard]] Result<> makeStringConst(); - // [[nodiscard]] Result<> makeStringMeasure(); - // [[nodiscard]] Result<> makeStringEncode(); - // [[nodiscard]] Result<> makeStringConcat(); - // [[nodiscard]] Result<> makeStringEq(); - // [[nodiscard]] Result<> makeStringAs(); - // [[nodiscard]] Result<> makeStringWTF8Advance(); - // [[nodiscard]] Result<> makeStringWTF16Get(); - // [[nodiscard]] Result<> makeStringIterNext(); - // [[nodiscard]] Result<> makeStringIterMove(); - // [[nodiscard]] Result<> makeStringSliceWTF(); - // [[nodiscard]] Result<> makeStringSliceIter(); + [[nodiscard]] Result<> makeStringNew(StringNewOp op, bool try_, Name mem); + [[nodiscard]] Result<> makeStringConst(Name string); + [[nodiscard]] Result<> makeStringMeasure(StringMeasureOp op); + [[nodiscard]] Result<> makeStringEncode(StringEncodeOp op, Name mem); + [[nodiscard]] Result<> makeStringConcat(); + [[nodiscard]] Result<> makeStringEq(StringEqOp op); + [[nodiscard]] Result<> makeStringAs(StringAsOp op); + [[nodiscard]] Result<> makeStringWTF8Advance(); + [[nodiscard]] Result<> makeStringWTF16Get(); + [[nodiscard]] Result<> makeStringIterNext(); + [[nodiscard]] Result<> makeStringIterMove(StringIterMoveOp op); + [[nodiscard]] Result<> makeStringSliceWTF(StringSliceWTFOp op); + [[nodiscard]] Result<> makeStringSliceIter(); // Private functions that must be public for technical reasons. [[nodiscard]] Result<> visitExpression(Expression*); @@ -213,6 +213,8 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> visitCallIndirect(CallIndirect*); [[nodiscard]] Result<> visitCallRef(CallRef*); [[nodiscard]] Result<> visitThrow(Throw*); + [[nodiscard]] Result<> visitStringNew(StringNew*); + [[nodiscard]] Result<> visitStringEncode(StringEncode*); private: Module& wasm; diff --git a/src/wasm.h b/src/wasm.h index 7da80d89647..ce334773a2c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1736,6 +1736,7 @@ class ArrayFill : public SpecificExpression { class ArrayInitData : public SpecificExpression { public: + ArrayInitData() = default; ArrayInitData(MixedArena& allocator) {} Name segment; @@ -1749,6 +1750,7 @@ class ArrayInitData : public SpecificExpression { class ArrayInitElem : public SpecificExpression { public: + ArrayInitElem() = default; ArrayInitElem(MixedArena& allocator) {} Name segment; @@ -1774,6 +1776,7 @@ class RefAs : public SpecificExpression { class StringNew : public SpecificExpression { public: + StringNew() = default; StringNew(MixedArena& allocator) {} StringNewOp op; @@ -1798,6 +1801,7 @@ class StringNew : public SpecificExpression { class StringConst : public SpecificExpression { public: + StringConst() = default; StringConst(MixedArena& allocator) {} // TODO: Use a different type to allow null bytes in the middle - @@ -1810,6 +1814,7 @@ class StringConst : public SpecificExpression { class StringMeasure : public SpecificExpression { public: + StringMeasure() = default; StringMeasure(MixedArena& allocator) {} StringMeasureOp op; @@ -1821,6 +1826,7 @@ class StringMeasure : public SpecificExpression { class StringEncode : public SpecificExpression { public: + StringEncode() = default; StringEncode(MixedArena& allocator) {} StringEncodeOp op; @@ -1840,6 +1846,7 @@ class StringEncode : public SpecificExpression { class StringConcat : public SpecificExpression { public: + StringConcat() = default; StringConcat(MixedArena& allocator) {} Expression* left; @@ -1850,6 +1857,7 @@ class StringConcat : public SpecificExpression { class StringEq : public SpecificExpression { public: + StringEq() = default; StringEq(MixedArena& allocator) {} StringEqOp op; @@ -1862,6 +1870,7 @@ class StringEq : public SpecificExpression { class StringAs : public SpecificExpression { public: + StringAs() = default; StringAs(MixedArena& allocator) {} StringAsOp op; @@ -1874,6 +1883,7 @@ class StringAs : public SpecificExpression { class StringWTF8Advance : public SpecificExpression { public: + StringWTF8Advance() = default; StringWTF8Advance(MixedArena& allocator) {} Expression* ref; @@ -1885,6 +1895,7 @@ class StringWTF8Advance class StringWTF16Get : public SpecificExpression { public: + StringWTF16Get() = default; StringWTF16Get(MixedArena& allocator) {} Expression* ref; @@ -1895,6 +1906,7 @@ class StringWTF16Get : public SpecificExpression { class StringIterNext : public SpecificExpression { public: + StringIterNext() = default; StringIterNext(MixedArena& allocator) {} Expression* ref; @@ -1904,6 +1916,7 @@ class StringIterNext : public SpecificExpression { class StringIterMove : public SpecificExpression { public: + StringIterMove() = default; StringIterMove(MixedArena& allocator) {} // Whether the movement is to advance or reverse. @@ -1919,6 +1932,7 @@ class StringIterMove : public SpecificExpression { class StringSliceWTF : public SpecificExpression { public: + StringSliceWTF() = default; StringSliceWTF(MixedArena& allocator) {} StringSliceWTFOp op; @@ -1933,6 +1947,7 @@ class StringSliceWTF : public SpecificExpression { class StringSliceIter : public SpecificExpression { public: + StringSliceIter() = default; StringSliceIter(MixedArena& allocator) {} Expression* ref; diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 5301b75dc9c..d3f48b1c022 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -471,6 +471,65 @@ Result<> IRBuilder::visitThrow(Throw* curr) { return Ok{}; } +Result<> IRBuilder::visitStringNew(StringNew* curr) { + switch (curr->op) { + case StringNewUTF8: + case StringNewWTF8: + case StringNewLossyUTF8: + case StringNewWTF16: { + auto len = pop(); + CHECK_ERR(len); + curr->length = *len; + break; + } + case StringNewUTF8Array: + case StringNewWTF8Array: + case StringNewLossyUTF8Array: + case StringNewWTF16Array: { + auto end = pop(); + CHECK_ERR(end); + curr->end = *end; + auto start = pop(); + CHECK_ERR(start); + curr->start = *start; + break; + } + case StringNewFromCodePoint: + break; + } + auto ptr = pop(); + CHECK_ERR(ptr); + curr->ptr = *ptr; + return Ok{}; +} + +Result<> IRBuilder::visitStringEncode(StringEncode* curr) { + switch (curr->op) { + case StringEncodeUTF8Array: + case StringEncodeLossyUTF8Array: + case StringEncodeWTF8Array: + case StringEncodeWTF16Array: { + auto start = pop(); + CHECK_ERR(start); + curr->start = *start; + } + [[fallthrough]]; + case StringEncodeUTF8: + case StringEncodeLossyUTF8: + case StringEncodeWTF8: + case StringEncodeWTF16: { + auto ptr = pop(); + CHECK_ERR(ptr); + curr->ptr = *ptr; + auto ref = pop(); + CHECK_ERR(ref); + curr->ref = *ref; + return Ok{}; + } + } + WASM_UNREACHABLE("unexpected op"); +} + Result<> IRBuilder::visitFunctionStart(Function* func) { if (!scopeStack.empty()) { return Err{"unexpected start of function"}; @@ -1408,9 +1467,23 @@ Result<> IRBuilder::makeArrayFill(HeapType type) { return Ok{}; } -// Result<> IRBuilder::makeArrayInitData() {} +Result<> IRBuilder::makeArrayInitData(HeapType type, Name data) { + ArrayInitData curr; + CHECK_ERR(visitArrayInitData(&curr)); + CHECK_ERR(validateTypeAnnotation(type, curr.ref)); + push(builder.makeArrayInitData( + data, curr.ref, curr.index, curr.offset, curr.size)); + return Ok{}; +} -// Result<> IRBuilder::makeArrayInitElem() {} +Result<> IRBuilder::makeArrayInitElem(HeapType type, Name elem) { + ArrayInitElem curr; + CHECK_ERR(visitArrayInitElem(&curr)); + CHECK_ERR(validateTypeAnnotation(type, curr.ref)); + push(builder.makeArrayInitElem( + elem, curr.ref, curr.index, curr.offset, curr.size)); + return Ok{}; +} Result<> IRBuilder::makeRefAs(RefAsOp op) { RefAs curr; @@ -1419,30 +1492,113 @@ Result<> IRBuilder::makeRefAs(RefAsOp op) { return Ok{}; } -// Result<> IRBuilder::makeStringNew() {} +Result<> IRBuilder::makeStringNew(StringNewOp op, bool try_, Name mem) { + StringNew curr; + curr.op = op; + CHECK_ERR(visitStringNew(&curr)); + // TODO: Store the memory in the IR. + switch (op) { + case StringNewUTF8: + case StringNewWTF8: + case StringNewLossyUTF8: + case StringNewWTF16: + push(builder.makeStringNew(op, curr.ptr, curr.length, try_)); + return Ok{}; + case StringNewUTF8Array: + case StringNewWTF8Array: + case StringNewLossyUTF8Array: + case StringNewWTF16Array: + push(builder.makeStringNew(op, curr.ptr, curr.start, curr.end, try_)); + return Ok{}; + case StringNewFromCodePoint: + push(builder.makeStringNew(op, curr.ptr, nullptr, try_)); + return Ok{}; + } + WASM_UNREACHABLE("unexpected op"); +} -// Result<> IRBuilder::makeStringConst() {} +Result<> IRBuilder::makeStringConst(Name string) { + push(builder.makeStringConst(string)); + return Ok{}; +} -// Result<> IRBuilder::makeStringMeasure() {} +Result<> IRBuilder::makeStringMeasure(StringMeasureOp op) { + StringMeasure curr; + CHECK_ERR(visitStringMeasure(&curr)); + push(builder.makeStringMeasure(op, curr.ref)); + return Ok{}; +} -// Result<> IRBuilder::makeStringEncode() {} +Result<> IRBuilder::makeStringEncode(StringEncodeOp op, Name mem) { + StringEncode curr; + curr.op = op; + CHECK_ERR(visitStringEncode(&curr)); + // TODO: Store the memory in the IR. + push(builder.makeStringEncode(op, curr.ref, curr.ptr, curr.start)); + return Ok{}; +} -// Result<> IRBuilder::makeStringConcat() {} +Result<> IRBuilder::makeStringConcat() { + StringConcat curr; + CHECK_ERR(visitStringConcat(&curr)); + push(builder.makeStringConcat(curr.left, curr.right)); + return Ok{}; +} -// Result<> IRBuilder::makeStringEq() {} +Result<> IRBuilder::makeStringEq(StringEqOp op) { + StringEq curr; + CHECK_ERR(visitStringEq(&curr)); + push(builder.makeStringEq(op, curr.left, curr.right)); + return Ok{}; +} -// Result<> IRBuilder::makeStringAs() {} +Result<> IRBuilder::makeStringAs(StringAsOp op) { + StringAs curr; + CHECK_ERR(visitStringAs(&curr)); + push(builder.makeStringAs(op, curr.ref)); + return Ok{}; +} -// Result<> IRBuilder::makeStringWTF8Advance() {} +Result<> IRBuilder::makeStringWTF8Advance() { + StringWTF8Advance curr; + CHECK_ERR(visitStringWTF8Advance(&curr)); + push(builder.makeStringWTF8Advance(curr.ref, curr.pos, curr.bytes)); + return Ok{}; +} -// Result<> IRBuilder::makeStringWTF16Get() {} +Result<> IRBuilder::makeStringWTF16Get() { + StringWTF16Get curr; + CHECK_ERR(visitStringWTF16Get(&curr)); + push(builder.makeStringWTF16Get(curr.ref, curr.pos)); + return Ok{}; +} -// Result<> IRBuilder::makeStringIterNext() {} +Result<> IRBuilder::makeStringIterNext() { + StringIterNext curr; + CHECK_ERR(visitStringIterNext(&curr)); + push(builder.makeStringIterNext(curr.ref)); + return Ok{}; +} -// Result<> IRBuilder::makeStringIterMove() {} +Result<> IRBuilder::makeStringIterMove(StringIterMoveOp op) { + StringIterMove curr; + CHECK_ERR(visitStringIterMove(&curr)); + push(builder.makeStringIterMove(op, curr.ref, curr.num)); + return Ok{}; +} -// Result<> IRBuilder::makeStringSliceWTF() {} +Result<> IRBuilder::makeStringSliceWTF(StringSliceWTFOp op) { + StringSliceWTF curr; + CHECK_ERR(visitStringSliceWTF(&curr)); + push(builder.makeStringSliceWTF(op, curr.ref, curr.start, curr.end)); + return Ok{}; +} -// Result<> IRBuilder::makeStringSliceIter() {} +Result<> IRBuilder::makeStringSliceIter() { + StringSliceIter curr; + CHECK_ERR(visitStringSliceIter(&curr)); + push(builder.makeStringSliceIter(curr.ref, curr.num)); + return Ok{}; +} } // namespace wasm diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index c4bd4826056..31910686bab 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -19,10 +19,10 @@ ;; CHECK: (type $5 (func (result i32 i64))) - ;; CHECK: (type $a1 (array i64)) - ;; CHECK: (type $a2 (array (mut f32))) + ;; CHECK: (type $a1 (array i64)) + ;; CHECK: (type $8 (func (param anyref))) ;; CHECK: (rec @@ -34,93 +34,141 @@ (rec) + ;; CHECK: (type $any-array (array (mut anyref))) + + ;; CHECK: (type $packed-i8 (array (mut i8))) + ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) - ;; CHECK: (type $12 (func)) + ;; CHECK: (type $14 (func)) - ;; CHECK: (type $13 (func (param i32))) + ;; CHECK: (type $15 (func (param i32))) - ;; CHECK: (type $14 (func (param i32 i64 v128))) + ;; CHECK: (type $16 (func (param i32 i64 v128))) ;; CHECK: (type $a0 (array i32)) - ;; CHECK: (type $16 (func (param i32 i32 i32))) + ;; CHECK: (type $18 (func (param i32 i32 i32))) - ;; CHECK: (type $17 (func (param v128 i32) (result v128))) - - ;; CHECK: (type $packed-i8 (array (mut i8))) + ;; CHECK: (type $19 (func (param v128 i32) (result v128))) ;; CHECK: (type $packed-i16 (array (mut i16))) - ;; CHECK: (type $20 (func (param i32 i64) (result f32))) + ;; CHECK: (type $21 (func (param stringref))) + + ;; CHECK: (type $22 (func (param stringref stringref) (result i32))) + + ;; CHECK: (type $23 (func (param i32 i64) (result f32))) + + ;; CHECK: (type $24 (func (param i32 i32))) + + ;; CHECK: (type $25 (func (param i32 i32 f64 f64))) + + ;; CHECK: (type $26 (func (param i64))) + + ;; CHECK: (type $27 (func (param v128) (result i32))) + + ;; CHECK: (type $28 (func (param v128 v128) (result v128))) + + ;; CHECK: (type $29 (func (param v128 v128 v128) (result v128))) + + ;; CHECK: (type $30 (func (param i32 i32 i64 i64))) + + ;; CHECK: (type $31 (func (param i32) (result i32))) + + ;; CHECK: (type $32 (func (param i32 i64) (result i32 i64))) - ;; CHECK: (type $21 (func (param i32 i32))) + ;; CHECK: (type $33 (func (param i64) (result i32 i64))) - ;; CHECK: (type $22 (func (param i32 i32 f64 f64))) + ;; CHECK: (type $34 (func (param i32) (result i32 i64))) - ;; CHECK: (type $23 (func (param i64))) + ;; CHECK: (type $35 (func (param anyref) (result i32))) - ;; CHECK: (type $24 (func (param v128) (result i32))) + ;; CHECK: (type $36 (func (param eqref eqref) (result i32))) - ;; CHECK: (type $25 (func (param v128 v128) (result v128))) + ;; CHECK: (type $37 (func (param i32) (result i31ref))) - ;; CHECK: (type $26 (func (param v128 v128 v128) (result v128))) + ;; CHECK: (type $38 (func (param i31ref))) - ;; CHECK: (type $27 (func (param i32 i32 i64 i64))) + ;; CHECK: (type $39 (func (param i32 i64) (result (ref $pair)))) - ;; CHECK: (type $28 (func (param i32) (result i32))) + ;; CHECK: (type $40 (func (result (ref $pair)))) - ;; CHECK: (type $29 (func (param i32 i64) (result i32 i64))) + ;; CHECK: (type $41 (func (param (ref $pair)) (result i32))) - ;; CHECK: (type $30 (func (param i64) (result i32 i64))) + ;; CHECK: (type $42 (func (param (ref $pair)) (result i64))) - ;; CHECK: (type $31 (func (param i32) (result i32 i64))) + ;; CHECK: (type $43 (func (param (ref $pair) i32))) - ;; CHECK: (type $32 (func (param anyref) (result i32))) + ;; CHECK: (type $44 (func (param (ref $pair) i64))) - ;; CHECK: (type $33 (func (param eqref eqref) (result i32))) + ;; CHECK: (type $45 (func (param i64 i32) (result (ref $a1)))) - ;; CHECK: (type $34 (func (param i32) (result i31ref))) + ;; CHECK: (type $46 (func (param i32) (result (ref $a1)))) - ;; CHECK: (type $35 (func (param i31ref))) + ;; CHECK: (type $47 (func (param i32 i32) (result (ref $any-array)))) - ;; CHECK: (type $36 (func (param i32 i64) (result (ref $pair)))) + ;; CHECK: (type $48 (func (param i32 i32) (result (ref $a1)))) - ;; CHECK: (type $37 (func (result (ref $pair)))) + ;; CHECK: (type $49 (func (param (ref $a1) i32) (result i64))) - ;; CHECK: (type $38 (func (param (ref $pair)) (result i32))) + ;; CHECK: (type $50 (func (param (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $39 (func (param (ref $pair)) (result i64))) + ;; CHECK: (type $51 (func (param (ref $packed-i16) i32) (result i32))) - ;; CHECK: (type $40 (func (param (ref $pair) i32))) + ;; CHECK: (type $52 (func (param (ref $a2) i32 f32))) - ;; CHECK: (type $41 (func (param (ref $pair) i64))) + ;; CHECK: (type $53 (func (param arrayref) (result i32))) - ;; CHECK: (type $42 (func (param i64 i32) (result (ref $a1)))) + ;; CHECK: (type $54 (func (param (ref $a2) i32 (ref $a2) i32 i32))) - ;; CHECK: (type $43 (func (param i32) (result (ref $a1)))) + ;; CHECK: (type $55 (func (param (ref $a2) i32 f32 i32))) - ;; CHECK: (type $44 (func (param i32 i32) (result (ref $a1)))) + ;; CHECK: (type $56 (func (param (ref $a2) i32 i32 i32))) - ;; CHECK: (type $45 (func (param (ref $a1) i32) (result i64))) + ;; CHECK: (type $57 (func (param (ref $any-array) i32 i32 i32))) - ;; CHECK: (type $46 (func (param (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $58 (func (param externref))) - ;; CHECK: (type $47 (func (param (ref $packed-i16) i32) (result i32))) + ;; CHECK: (type $59 (func (param i32 i32) (result stringref))) - ;; CHECK: (type $48 (func (param (ref $a2) i32 f32))) + ;; CHECK: (type $60 (func (param (ref $packed-i8) i32 i32) (result stringref))) - ;; CHECK: (type $49 (func (param arrayref) (result i32))) + ;; CHECK: (type $61 (func (param i32) (result stringref))) - ;; CHECK: (type $50 (func (param (ref $a2) i32 (ref $a2) i32 i32))) + ;; CHECK: (type $62 (func (result (ref string)))) - ;; CHECK: (type $51 (func (param (ref $a2) i32 f32 i32))) + ;; CHECK: (type $63 (func (param stringref) (result i32))) - ;; CHECK: (type $52 (func (param externref))) + ;; CHECK: (type $64 (func (param stringview_wtf16) (result i32))) - ;; CHECK: (type $53 (func (param i64 v128) (result v128))) + ;; CHECK: (type $65 (func (param stringref (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $54 (func (param i64 v128))) + ;; CHECK: (type $66 (func (param stringref stringref) (result (ref string)))) + + ;; CHECK: (type $67 (func (param stringref) (result stringview_wtf8))) + + ;; CHECK: (type $68 (func (param stringref) (result (ref stringview_wtf16)))) + + ;; CHECK: (type $69 (func (param stringref) (result stringview_iter))) + + ;; CHECK: (type $70 (func (param (ref stringview_wtf8) i32 i32) (result i32))) + + ;; CHECK: (type $71 (func (param stringview_wtf16 i32) (result i32))) + + ;; CHECK: (type $72 (func (param stringview_iter) (result i32))) + + ;; CHECK: (type $73 (func (param stringview_iter i32) (result i32))) + + ;; CHECK: (type $74 (func (param (ref stringview_iter) i32) (result i32))) + + ;; CHECK: (type $75 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) + + ;; CHECK: (type $76 (func (param stringview_iter i32) (result (ref string)))) + + ;; CHECK: (type $77 (func (param i64 v128) (result v128))) + + ;; CHECK: (type $78 (func (param i64 v128))) ;; CHECK: (type $s2 (struct (field i32))) (type $s2 (struct i32)) @@ -149,6 +197,8 @@ (type $packed-i16 (array (mut i16))) + (type $any-array (array (mut anyref))) + (rec (type $void (sub open (func))) ) @@ -183,7 +233,7 @@ ;; globals (global (mut i32) i32.const 0) - ;; CHECK: (type $65 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) + ;; CHECK: (type $89 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) ;; CHECK: (import "" "mem" (memory $mimport$0 0)) @@ -332,11 +382,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK: (func $f1 (type $13) (param $0 i32) + ;; CHECK: (func $f1 (type $15) (param $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f1 (param i32)) - ;; CHECK: (func $f2 (type $13) (param $x i32) + ;; CHECK: (func $f2 (type $15) (param $x i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f2 (param $x i32)) @@ -352,7 +402,7 @@ ;; CHECK-NEXT: (local $l f32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - (func $f4 (type 17) (local i32 i64) (local $l f32)) + (func $f4 (type 18) (local i32 i64) (local $l f32)) ;; CHECK: (func $nop-skate (type $void) ;; CHECK-NEXT: (nop) @@ -779,7 +829,7 @@ drop ) - ;; CHECK: (func $locals (type $21) (param $0 i32) (param $x i32) + ;; CHECK: (func $locals (type $24) (param $0 i32) (param $x i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (drop @@ -2467,7 +2517,7 @@ ) - ;; CHECK: (func $binary (type $22) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) + ;; CHECK: (func $binary (type $25) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $0) @@ -2492,7 +2542,7 @@ drop ) - ;; CHECK: (func $unary (type $23) (param $0 i64) + ;; CHECK: (func $unary (type $26) (param $0 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $0) @@ -2505,7 +2555,7 @@ drop ) - ;; CHECK: (func $select (type $16) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $select (type $18) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $0) @@ -2787,7 +2837,7 @@ atomic.fence ) - ;; CHECK: (func $simd-extract (type $24) (param $0 v128) (result i32) + ;; CHECK: (func $simd-extract (type $27) (param $0 v128) (result i32) ;; CHECK-NEXT: (i32x4.extract_lane 3 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2797,7 +2847,7 @@ i32x4.extract_lane 3 ) - ;; CHECK: (func $simd-replace (type $17) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-replace (type $19) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i32x4.replace_lane 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2809,7 +2859,7 @@ i32x4.replace_lane 2 ) - ;; CHECK: (func $simd-shuffle (type $25) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK: (func $simd-shuffle (type $28) (param $0 v128) (param $1 v128) (result v128) ;; CHECK-NEXT: (i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2821,7 +2871,7 @@ i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ) - ;; CHECK: (func $simd-ternary (type $26) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK: (func $simd-ternary (type $29) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) ;; CHECK-NEXT: (v128.bitselect ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2835,7 +2885,7 @@ v128.bitselect ) - ;; CHECK: (func $simd-shift (type $17) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-shift (type $19) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i8x16.shl ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2868,7 +2918,7 @@ drop ) - ;; CHECK: (func $simd-load-store-lane (type $14) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $simd-load-store-lane (type $16) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load16_lane $mimport$0 7 ;; CHECK-NEXT: (local.get $0) @@ -2890,7 +2940,7 @@ v128.store64_lane 4 align=4 0 ) - ;; CHECK: (func $memory-init (type $16) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $memory-init (type $18) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (memory.init $mem-i32 $passive ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2931,7 +2981,7 @@ data.drop $passive ) - ;; CHECK: (func $memory-copy (type $27) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) + ;; CHECK: (func $memory-copy (type $30) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) ;; CHECK-NEXT: (memory.copy $mimport$0 $mimport$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3002,7 +3052,7 @@ return ) - ;; CHECK: (func $return-one (type $28) (param $0 i32) (result i32) + ;; CHECK: (func $return-one (type $31) (param $0 i32) (result i32) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3012,7 +3062,7 @@ return ) - ;; CHECK: (func $return-two (type $29) (param $0 i32) (param $1 i64) (result i32 i64) + ;; CHECK: (func $return-two (type $32) (param $0 i32) (param $1 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (local.get $0) @@ -3026,7 +3076,7 @@ return ) - ;; CHECK: (func $return-two-first-unreachable (type $30) (param $0 i64) (result i32 i64) + ;; CHECK: (func $return-two-first-unreachable (type $33) (param $0 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (unreachable) @@ -3040,7 +3090,7 @@ return ) - ;; CHECK: (func $return-two-second-unreachable (type $31) (param $0 i32) (result i32 i64) + ;; CHECK: (func $return-two-second-unreachable (type $34) (param $0 i32) (result i32 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3057,7 +3107,7 @@ return ) - ;; CHECK: (func $ref-is-null (type $32) (param $0 anyref) (result i32) + ;; CHECK: (func $ref-is-null (type $35) (param $0 anyref) (result i32) ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3101,7 +3151,7 @@ throw $tag-pair ) - ;; CHECK: (func $ref-eq (type $33) (param $0 eqref) (param $1 eqref) (result i32) + ;; CHECK: (func $ref-eq (type $36) (param $0 eqref) (param $1 eqref) (result i32) ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3278,7 +3328,7 @@ table.copy 1 $funcs ) - ;; CHECK: (func $i31-new (type $34) (param $0 i32) (result i31ref) + ;; CHECK: (func $i31-new (type $37) (param $0 i32) (result i31ref) ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3288,7 +3338,7 @@ ref.i31 ) - ;; CHECK: (func $i31-get (type $35) (param $0 i31ref) + ;; CHECK: (func $i31-get (type $38) (param $0 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i31.get_s ;; CHECK-NEXT: (local.get $0) @@ -3513,7 +3563,7 @@ drop ) - ;; CHECK: (func $struct-new (type $36) (param $0 i32) (param $1 i64) (result (ref $pair)) + ;; CHECK: (func $struct-new (type $39) (param $0 i32) (param $1 i64) (result (ref $pair)) ;; CHECK-NEXT: (struct.new $pair ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3525,14 +3575,14 @@ struct.new $pair ) - ;; CHECK: (func $struct-new-default (type $37) (result (ref $pair)) + ;; CHECK: (func $struct-new-default (type $40) (result (ref $pair)) ;; CHECK-NEXT: (struct.new_default $pair) ;; CHECK-NEXT: ) (func $struct-new-default (result (ref $pair)) struct.new_default 14 ) - ;; CHECK: (func $struct-get-0 (type $38) (param $0 (ref $pair)) (result i32) + ;; CHECK: (func $struct-get-0 (type $41) (param $0 (ref $pair)) (result i32) ;; CHECK-NEXT: (struct.get $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3542,7 +3592,7 @@ struct.get 14 0 ) - ;; CHECK: (func $struct-get-1 (type $39) (param $0 (ref $pair)) (result i64) + ;; CHECK: (func $struct-get-1 (type $42) (param $0 (ref $pair)) (result i64) ;; CHECK-NEXT: (struct.get $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3552,7 +3602,7 @@ struct.get $pair 1 ) - ;; CHECK: (func $struct-set-0 (type $40) (param $0 (ref $pair)) (param $1 i32) + ;; CHECK: (func $struct-set-0 (type $43) (param $0 (ref $pair)) (param $1 i32) ;; CHECK-NEXT: (struct.set $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3564,7 +3614,7 @@ struct.set $pair 0 ) - ;; CHECK: (func $struct-set-1 (type $41) (param $0 (ref $pair)) (param $1 i64) + ;; CHECK: (func $struct-set-1 (type $44) (param $0 (ref $pair)) (param $1 i64) ;; CHECK-NEXT: (struct.set $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3576,7 +3626,7 @@ struct.set 14 1 ) - ;; CHECK: (func $array-new (type $42) (param $0 i64) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new (type $45) (param $0 i64) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3588,7 +3638,7 @@ array.new $a1 ) - ;; CHECK: (func $array-new-default (type $43) (param $0 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-default (type $46) (param $0 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_default $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3598,7 +3648,19 @@ array.new_default 11 ) - ;; CHECK: (func $array-new-data (type $44) (param $0 i32) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-elem (type $47) (param $0 i32) (param $1 i32) (result (ref $any-array)) + ;; CHECK-NEXT: (array.new_elem $any-array $passive-2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-new-elem (param i32 i32) (result (ref $any-array)) + local.get 0 + local.get 1 + array.new_elem $any-array $passive-2 + ) + + ;; CHECK: (func $array-new-data (type $48) (param $0 i32) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_data $a1 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3632,7 +3694,7 @@ drop ) - ;; CHECK: (func $array-get (type $45) (param $0 (ref $a1)) (param $1 i32) (result i64) + ;; CHECK: (func $array-get (type $49) (param $0 (ref $a1)) (param $1 i32) (result i64) ;; CHECK-NEXT: (array.get $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3644,7 +3706,7 @@ array.get $a1 ) - ;; CHECK: (func $array-get-s (type $46) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-s (type $50) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_s $packed-i8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3656,7 +3718,7 @@ array.get_s 15 ) - ;; CHECK: (func $array-get-u (type $47) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-u (type $51) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_u $packed-i16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3668,7 +3730,7 @@ array.get_u $packed-i16 ) - ;; CHECK: (func $array-set (type $48) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) + ;; CHECK: (func $array-set (type $52) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) ;; CHECK-NEXT: (array.set $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3682,7 +3744,7 @@ array.set $a2 ) - ;; CHECK: (func $array-len (type $49) (param $0 arrayref) (result i32) + ;; CHECK: (func $array-len (type $53) (param $0 arrayref) (result i32) ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3692,7 +3754,7 @@ array.len ) - ;; CHECK: (func $array-copy (type $50) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) + ;; CHECK: (func $array-copy (type $54) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) ;; CHECK-NEXT: (array.copy $a2 $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3710,7 +3772,7 @@ array.copy $a2 $a2 ) - ;; CHECK: (func $array-fill (type $51) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) + ;; CHECK: (func $array-fill (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) ;; CHECK-NEXT: (array.fill $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3726,6 +3788,38 @@ array.fill $a2 ) + ;; CHECK: (func $array-init-data (type $56) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK-NEXT: (array.init_data $a2 $implicit-data + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-init-data (param (ref $a2) i32 i32 i32) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + array.init_data $a2 0 + ) + + ;; CHECK: (func $array-init-elem (type $57) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK-NEXT: (array.init_elem $any-array $passive-2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-init-elem (param (ref $any-array) i32 i32 i32) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + array.init_elem $any-array $passive-2 + ) + ;; CHECK: (func $ref-as-non-null (type $8) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null @@ -3739,7 +3833,7 @@ drop ) - ;; CHECK: (func $any-convert-extern (type $52) (param $0 externref) + ;; CHECK: (func $any-convert-extern (type $58) (param $0 externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.internalize ;; CHECK-NEXT: (local.get $0) @@ -3765,7 +3859,368 @@ drop ) - ;; CHECK: (func $call (type $20) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $string-new (type $59) (param $0 i32) (param $1 i32) (result stringref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.new_utf8_try + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.new_wtf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.new_lossy_utf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (string.new_wtf16 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-new (param i32 i32) (result stringref) + local.get 0 + local.get 1 + string.new_utf8_try + drop + local.get 0 + local.get 1 + string.new_wtf8 0 + drop + local.get 0 + local.get 1 + string.new_lossy_utf8 $mem + drop + local.get 0 + local.get 1 + string.new_wtf16 + ) + + ;; CHECK: (func $string-new-gc (type $60) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) + ;; CHECK-NEXT: (string.new_utf8_array + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-new-gc (param (ref $packed-i8) i32 i32) (result stringref) + local.get 0 + local.get 1 + local.get 2 + string.new_utf8_array + ) + + ;; CHECK: (func $string-new-code-point (type $61) (param $0 i32) (result stringref) + ;; CHECK-NEXT: (string.from_code_point + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-new-code-point (param i32) (result stringref) + local.get 0 + string.from_code_point + ) + + ;; CHECK: (func $string-const (type $62) (result (ref string)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.const "foobar") + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (string.const "\00\00\00") + ;; CHECK-NEXT: ) + (func $string-const (result (ref string)) + string.const "foobar" + drop + string.const "\00\00\00" + ) + + ;; CHECK: (func $string-measure (type $21) (param $0 stringref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.measure_wtf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.measure_utf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.measure_wtf16 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.is_usv_sequence + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-measure (param stringref) + local.get 0 + string.measure_wtf8 + drop + local.get 0 + string.measure_utf8 + drop + local.get 0 + string.measure_wtf16 + drop + local.get 0 + string.is_usv_sequence + drop + ) + + ;; CHECK: (func $string-hash (type $63) (param $0 stringref) (result i32) + ;; CHECK-NEXT: (string.hash + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-hash (param stringref) (result i32) + local.get 0 + string.hash + ) + + ;; CHECK: (func $stringview-length (type $64) (param $0 stringview_wtf16) (result i32) + ;; CHECK-NEXT: (stringview_wtf16.length + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $stringview-length (param stringview_wtf16) (result i32) + local.get 0 + stringview_wtf16.length + ) + + ;; CHECK: (func $string-encode (type $21) (param $0 stringref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.encode_wtf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.encode_lossy_utf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.encode_utf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.encode_wtf16 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-encode (param stringref) + local.get 0 + i32.const 0 + string.encode_wtf8 + drop + local.get 0 + i32.const 1 + string.encode_lossy_utf8 0 + drop + local.get 0 + i32.const 2 + string.encode_utf8 $mem + drop + local.get 0 + i32.const 3 + string.encode_wtf16 + drop + ) + + ;; CHECK: (func $string-encode-gc (type $65) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) + ;; CHECK-NEXT: (string.encode_wtf8_array + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-encode-gc (param stringref (ref $packed-i8) i32) (result i32) + local.get 0 + local.get 1 + local.get 2 + string.encode_wtf8_array + ) + + ;; CHECK: (func $string-concat (type $66) (param $0 stringref) (param $1 stringref) (result (ref string)) + ;; CHECK-NEXT: (string.concat + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-concat (param stringref stringref) (result (ref string)) + local.get 0 + local.get 1 + string.concat + ) + + ;; CHECK: (func $string-eq (type $22) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK-NEXT: (string.eq + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-eq (param stringref stringref) (result i32) + local.get 0 + local.get 1 + string.eq + ) + + ;; CHECK: (func $string-compare (type $22) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK-NEXT: (string.compare + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-compare (param stringref stringref) (result i32) + local.get 0 + local.get 1 + string.compare + ) + + ;; CHECK: (func $string-as-wtf8 (type $67) (param $0 stringref) (result stringview_wtf8) + ;; CHECK-NEXT: (string.as_wtf8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-as-wtf8 (param stringref) (result stringview_wtf8) + local.get 0 + string.as_wtf8 + ) + + ;; CHECK: (func $string-as-wtf16 (type $68) (param $0 stringref) (result (ref stringview_wtf16)) + ;; CHECK-NEXT: (string.as_wtf16 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-as-wtf16 (param stringref) (result (ref stringview_wtf16)) + local.get 0 + string.as_wtf16 + ) + + ;; CHECK: (func $string-as-iter (type $69) (param $0 stringref) (result stringview_iter) + ;; CHECK-NEXT: (string.as_iter + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-as-iter (param stringref) (result stringview_iter) + local.get 0 + string.as_iter + ) + + ;; CHECK: (func $string-advance (type $70) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK-NEXT: (stringview_wtf8.advance + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-advance (param (ref stringview_wtf8) i32 i32) (result i32) + local.get 0 + local.get 1 + local.get 2 + stringview_wtf8.advance + ) + + ;; CHECK: (func $string-get (type $71) (param $0 stringview_wtf16) (param $1 i32) (result i32) + ;; CHECK-NEXT: (stringview_wtf16.get_codeunit + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-get (param stringview_wtf16 i32) (result i32) + local.get 0 + local.get 1 + stringview_wtf16.get_codeunit + ) + + ;; CHECK: (func $string-iter-next (type $72) (param $0 stringview_iter) (result i32) + ;; CHECK-NEXT: (stringview_iter.next + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-iter-next (param stringview_iter) (result i32) + local.get 0 + stringview_iter.next + ) + + ;; CHECK: (func $string-iter-advance (type $73) (param $0 stringview_iter) (param $1 i32) (result i32) + ;; CHECK-NEXT: (stringview_iter.advance + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-iter-advance (param (ref null stringview_iter) i32) (result i32) + local.get 0 + local.get 1 + stringview_iter.advance + ) + + ;; CHECK: (func $string-iter-rewind (type $74) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) + ;; CHECK-NEXT: (stringview_iter.rewind + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-iter-rewind (param (ref stringview_iter) i32) (result i32) + local.get 0 + local.get 1 + stringview_iter.rewind + ) + + ;; CHECK: (func $string-slice (type $75) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (stringview_wtf8.slice + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (stringview_wtf16.slice + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-slice (param stringview_wtf8 stringview_wtf16 i32 i32) + local.get 0 + local.get 2 + local.get 3 + stringview_wtf8.slice + drop + local.get 1 + local.get 2 + local.get 3 + stringview_wtf16.slice + drop + ) + + ;; CHECK: (func $string-iter-slice (type $76) (param $0 stringview_iter) (param $1 i32) (result (ref string)) + ;; CHECK-NEXT: (stringview_iter.slice + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string-iter-slice (param stringview_iter i32) (result (ref string)) + local.get 0 + local.get 1 + stringview_iter.slice + ) + + ;; CHECK: (func $call (type $23) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (call $call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3777,7 +4232,7 @@ call $call ) - ;; CHECK: (func $return_call (type $20) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $return_call (type $23) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (return_call $return_call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3789,7 +4244,7 @@ return_call $return_call ) - ;; CHECK: (func $call-indirect (type $14) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect (type $16) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3818,7 +4273,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $53) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $77) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -3851,7 +4306,7 @@ drop ) - ;; CHECK: (func $return-call-indirect (type $14) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $return-call-indirect (type $16) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3879,7 +4334,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $54) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $78) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -3910,7 +4365,7 @@ return_call_indirect (param i64 v128) ) - ;; CHECK: (func $use-types (type $65) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) + ;; CHECK: (func $use-types (type $89) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-types From 0024c8bdd28f701d57e49e65d38b28aad0594299 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 13 Dec 2023 10:53:50 -0800 Subject: [PATCH 002/553] [test] Port tests in test/ to test/lit/basic/ (#6160) This ports all tests from `test/` to `test/lit/basic/`. The set of commands and `CHECK` lines used are the same as the ones in #6159. Now we use `lit` to test these, this also deletes all `.wast`, `.wast.from-wast`, `.wast.fromBinary`, and `.wast.fromBinary.noDebugInfo` files from `test/` and all related test routines from the python scripts. All `CHECK` lines are generated by `update_lit_checks.py --all-items`. This also deletes these three multi-memory tests in `test/lit/`, because they seem to contain the same code with the ones in `test/`, which have been ported to `test/lit/basic/` along with other tests. - `test/lit/multi-memories-atomics64.wast` - `test/lit/multi-memories-basics.wast` - `test/lit/multi-memories-simd.wast` This also adds newlines between `(func`s in case there are none to make `CHECK` lines easy to view, and removes some extra existing newlines here and there. --- check.py | 2 +- scripts/test/wasm2js.py | 10 +- scripts/test/wasm_opt.py | 61 +- test/atomics-unshared.wast | 10 - test/atomics-unshared.wast.from-wast | 13 - test/atomics-unshared.wast.fromBinary | 14 - ...omics-unshared.wast.fromBinary.noDebugInfo | 14 - test/atomics.wast | 184 - test/atomics.wast.from-wast | 184 - test/atomics.wast.fromBinary | 185 - test/atomics.wast.fromBinary.noDebugInfo | 185 - test/atomics64.wast | 188 - test/atomics64.wast.from-wast | 188 - test/atomics64.wast.fromBinary | 189 - test/atomics64.wast.fromBinary.noDebugInfo | 189 - test/complexTextNames.wast | 4 - test/complexTextNames.wast.from-wast | 10 - test/complexTextNames.wast.fromBinary | 11 - ...mplexTextNames.wast.fromBinary.noDebugInfo | 11 - test/duplicate_types.wast | 15 - test/duplicate_types.wast.from-wast | 10 - test/duplicate_types.wast.fromBinary | 11 - ...uplicate_types.wast.fromBinary.noDebugInfo | 11 - test/empty_imported_table.wast | 4 - test/empty_imported_table.wast.from-wast | 4 - test/empty_imported_table.wast.fromBinary | 5 - ...imported_table.wast.fromBinary.noDebugInfo | 5 - test/empty_table.wast | 4 - test/empty_table.wast.from-wast | 4 - test/empty_table.wast.fromBinary | 5 - test/empty_table.wast.fromBinary.noDebugInfo | 5 - test/exception-handling.wast | 386 -- test/exception-handling.wast.from-wast | 423 -- test/exception-handling.wast.fromBinary | 446 -- ...ption-handling.wast.fromBinary.noDebugInfo | 446 -- test/export-import.wast | 8 - test/export-import.wast.from-wast | 7 - test/export-import.wast.fromBinary | 8 - .../export-import.wast.fromBinary.noDebugInfo | 8 - test/extended-names.wast | 6 - test/extended-names.wast.from-wast | 6 - test/extended-names.wast.fromBinary | 7 - ...extended-names.wast.fromBinary.noDebugInfo | 7 - test/externref.wast.from-wast | 19 - test/externref.wast.fromBinary | 20 - test/externref.wast.fromBinary.noDebugInfo | 20 - test/fn_prolog_epilog.debugInfo.wast | 16 - .../fn_prolog_epilog.debugInfo.wast.from-wast | 17 - ...fn_prolog_epilog.debugInfo.wast.fromBinary | 13 - ...ilog.debugInfo.wast.fromBinary.noDebugInfo | 13 - test/gc.wast.from-wast | 154 - test/gc.wast.fromBinary | 155 - test/gc.wast.fromBinary.noDebugInfo | 155 - test/grow_memory.wast | 17 - test/grow_memory.wast.from-wast | 16 - test/grow_memory.wast.fromBinary | 17 - test/grow_memory.wast.fromBinary.noDebugInfo | 17 - test/hello_world.wast.from-wast | 11 - test/hello_world.wast.fromBinary | 12 - test/hello_world.wast.fromBinary.noDebugInfo | 12 - test/imported_memory.wast | 4 - test/imported_memory.wast.from-wast | 4 - test/imported_memory.wast.fromBinary | 5 - ...mported_memory.wast.fromBinary.noDebugInfo | 5 - test/imported_memory_growth.wast | 4 - test/imported_memory_growth.wast.from-wast | 4 - test/imported_memory_growth.wast.fromBinary | 5 - ..._memory_growth.wast.fromBinary.noDebugInfo | 5 - test/kitchen_sink.wast | 707 -- test/kitchen_sink.wast.from-wast | 707 -- test/kitchen_sink.wast.fromBinary | 706 -- test/kitchen_sink.wast.fromBinary.noDebugInfo | 706 -- test/lit/basic/atomics-unshared.wast | 58 + test/lit/basic/atomics.wast | 750 ++ test/lit/basic/atomics64.wast | 766 +++ test/lit/basic/complexTextNames.wast | 49 + test/lit/basic/duplicate_types.wast | 55 + test/lit/basic/empty_imported_table.wast | 21 + test/lit/basic/empty_table.wast | 23 + test/lit/basic/exception-handling.wast | 1737 +++++ test/lit/basic/export-import.wast | 34 + test/lit/basic/extended-names.wast | 38 + .../lit/basic/fn_prolog_epilog.debugInfo.wast | 66 + test/lit/basic/grow_memory.wast | 71 + test/lit/basic/hello_world.wat | 50 + test/lit/basic/imported_memory.wast | 21 + test/lit/basic/imported_memory_growth.wast | 21 + test/lit/basic/kitchen_sink.wast | 2833 ++++++++ test/lit/basic/memory-import.wast | 42 + test/lit/basic/memory-import64.wast | 42 + test/lit/basic/memory-shared.wast | 17 + test/lit/basic/min.wast | 234 + test/lit/basic/multi-memories-atomics64.wast | 1421 ++++ test/lit/basic/multi-memories-basics.wast | 490 ++ test/lit/basic/multi-memories-simd.wast | 1399 ++++ test/lit/basic/multi-table.wast | 163 + test/lit/basic/mutable-global.wast | 54 + test/lit/basic/newsyntax.wast | 80 + test/lit/basic/nonspec-bulk-memory.wast | 137 + test/lit/basic/polymorphic_stack.wast | 449 ++ test/lit/basic/reference-types.wast | 2470 +++++++ test/lit/basic/reg_switch.wast | 62 + test/lit/basic/segment-overlap.wast | 30 + test/lit/basic/signext.wast | 114 + test/lit/basic/simd.wast | 6087 +++++++++++++++++ test/lit/basic/simd64.wast | 343 + test/lit/basic/subtypes.wast | 219 + test/lit/basic/table-import.wast | 45 + test/lit/basic/tags.wast | 91 + test/lit/basic/unit.wat | 2293 +++++++ test/lit/basic/unreachable-code.wast | 355 + test/lit/basic/unreachable-instr-type.wast | 81 + test/lit/basic/untaken-br_if.wast | 67 + test/lit/multi-memories-atomics64.wast | 704 -- test/lit/multi-memories-basics.wast | 176 - test/lit/multi-memories-simd.wast | 635 -- test/memory-import.wast | 9 - test/memory-import.wast.from-wast | 9 - test/memory-import.wast.fromBinary | 10 - .../memory-import.wast.fromBinary.noDebugInfo | 10 - test/memory-import64.wast | 9 - test/memory-import64.wast.from-wast | 9 - test/memory-import64.wast.fromBinary | 10 - ...emory-import64.wast.fromBinary.noDebugInfo | 10 - test/memory-shared.wast | 3 - test/memory-shared.wast.from-wast | 3 - test/memory-shared.wast.fromBinary | 4 - .../memory-shared.wast.fromBinary.noDebugInfo | 4 - test/min.wast | 57 - test/min.wast.from-wast | 57 - test/min.wast.fromBinary | 55 - test/min.wast.fromBinary.noDebugInfo | 55 - test/multi-memories-atomics64.wast | 352 - test/multi-memories-atomics64.wast.from-wast | 351 - test/multi-memories-atomics64.wast.fromBinary | 352 - ...ries-atomics64.wast.fromBinary.noDebugInfo | 352 - test/multi-memories-basics.wast | 117 - test/multi-memories-basics.wast.from-wast | 116 - test/multi-memories-basics.wast.fromBinary | 117 - ...emories-basics.wast.fromBinary.noDebugInfo | 117 - test/multi-memories-simd.wast | 320 - test/multi-memories-simd.wast.from-wast | 319 - test/multi-memories-simd.wast.fromBinary | 320 - ...-memories-simd.wast.fromBinary.noDebugInfo | 320 - test/multi-table.wast | 38 - test/multi-table.wast.from-wast | 31 - test/multi-table.wast.fromBinary | 32 - test/multi-table.wast.fromBinary.noDebugInfo | 32 - test/mutable-global.wast | 12 - test/mutable-global.wast.from-wast | 12 - test/mutable-global.wast.fromBinary | 13 - ...mutable-global.wast.fromBinary.noDebugInfo | 13 - test/newsyntax.wast | 10 - test/newsyntax.wast.from-wast | 18 - test/newsyntax.wast.fromBinary | 19 - test/newsyntax.wast.fromBinary.noDebugInfo | 19 - test/nonspec-bulk-memory.wast | 29 - test/nonspec-bulk-memory.wast.from-wast | 29 - test/nonspec-bulk-memory.wast.fromBinary | 30 - ...ec-bulk-memory.wast.fromBinary.noDebugInfo | 30 - test/polymorphic_stack.wast | 133 - test/polymorphic_stack.wast.from-wast | 135 - test/polymorphic_stack.wast.fromBinary | 76 - ...ymorphic_stack.wast.fromBinary.noDebugInfo | 76 - test/reference-types.wast | 464 -- test/reference-types.wast.from-wast | 650 -- test/reference-types.wast.fromBinary | 624 -- ...eference-types.wast.fromBinary.noDebugInfo | 624 -- test/reg_switch.wast | 14 - test/reg_switch.wast.from-wast | 14 - test/reg_switch.wast.fromBinary | 15 - test/reg_switch.wast.fromBinary.noDebugInfo | 15 - test/segment-overlap.wast | 6 - test/segment-overlap.wast.from-wast | 5 - test/segment-overlap.wast.fromBinary | 6 - ...egment-overlap.wast.fromBinary.noDebugInfo | 6 - test/signext.wast | 12 - test/signext.wast.from-wast | 32 - test/signext.wast.fromBinary | 33 - test/signext.wast.fromBinary.noDebugInfo | 33 - test/simd.wast | 1372 ---- test/simd.wast.from-wast | 1389 ---- test/simd.wast.fromBinary | 1390 ---- test/simd.wast.fromBinary.noDebugInfo | 1390 ---- test/simd64.wast | 74 - test/simd64.wast.from-wast | 76 - test/simd64.wast.fromBinary | 77 - test/simd64.wast.fromBinary.noDebugInfo | 77 - test/subtypes.wast | 59 - test/subtypes.wast.from-wast | 40 - test/subtypes.wast.fromBinary | 41 - test/subtypes.wast.fromBinary.noDebugInfo | 41 - test/table-import.wast | 9 - test/table-import.wast.from-wast | 9 - test/table-import.wast.fromBinary | 10 - test/table-import.wast.fromBinary.noDebugInfo | 10 - test/tags.wast | 16 - test/tags.wast.from-wast | 15 - test/tags.wast.fromBinary | 16 - test/tags.wast.fromBinary.noDebugInfo | 16 - test/tail-call.wast.from-wast | 13 - test/tail-call.wast.fromBinary | 14 - test/tail-call.wast.fromBinary.noDebugInfo | 14 - test/unit.wast.from-wast | 619 -- test/unit.wast.fromBinary | 537 -- test/unit.wast.fromBinary.noDebugInfo | 537 -- test/unit.wat | 554 -- test/unreachable-code.wast | 85 - test/unreachable-code.wast.from-wast | 89 - test/unreachable-code.wast.fromBinary | 79 - ...reachable-code.wast.fromBinary.noDebugInfo | 79 - test/unreachable-instr-type.wast | 28 - test/unreachable-instr-type.wast.from-wast | 27 - test/unreachable-instr-type.wast.fromBinary | 8 - ...ble-instr-type.wast.fromBinary.noDebugInfo | 8 - test/untaken-br_if.wast | 14 - test/untaken-br_if.wast.from-wast | 15 - test/untaken-br_if.wast.fromBinary | 16 - .../untaken-br_if.wast.fromBinary.noDebugInfo | 16 - 219 files changed, 23387 insertions(+), 24231 deletions(-) delete mode 100644 test/atomics-unshared.wast delete mode 100644 test/atomics-unshared.wast.from-wast delete mode 100644 test/atomics-unshared.wast.fromBinary delete mode 100644 test/atomics-unshared.wast.fromBinary.noDebugInfo delete mode 100644 test/atomics.wast delete mode 100644 test/atomics.wast.from-wast delete mode 100644 test/atomics.wast.fromBinary delete mode 100644 test/atomics.wast.fromBinary.noDebugInfo delete mode 100644 test/atomics64.wast delete mode 100644 test/atomics64.wast.from-wast delete mode 100644 test/atomics64.wast.fromBinary delete mode 100644 test/atomics64.wast.fromBinary.noDebugInfo delete mode 100644 test/complexTextNames.wast delete mode 100644 test/complexTextNames.wast.from-wast delete mode 100644 test/complexTextNames.wast.fromBinary delete mode 100644 test/complexTextNames.wast.fromBinary.noDebugInfo delete mode 100644 test/duplicate_types.wast delete mode 100644 test/duplicate_types.wast.from-wast delete mode 100644 test/duplicate_types.wast.fromBinary delete mode 100644 test/duplicate_types.wast.fromBinary.noDebugInfo delete mode 100644 test/empty_imported_table.wast delete mode 100644 test/empty_imported_table.wast.from-wast delete mode 100644 test/empty_imported_table.wast.fromBinary delete mode 100644 test/empty_imported_table.wast.fromBinary.noDebugInfo delete mode 100644 test/empty_table.wast delete mode 100644 test/empty_table.wast.from-wast delete mode 100644 test/empty_table.wast.fromBinary delete mode 100644 test/empty_table.wast.fromBinary.noDebugInfo delete mode 100644 test/exception-handling.wast delete mode 100644 test/exception-handling.wast.from-wast delete mode 100644 test/exception-handling.wast.fromBinary delete mode 100644 test/exception-handling.wast.fromBinary.noDebugInfo delete mode 100644 test/export-import.wast delete mode 100644 test/export-import.wast.from-wast delete mode 100644 test/export-import.wast.fromBinary delete mode 100644 test/export-import.wast.fromBinary.noDebugInfo delete mode 100644 test/extended-names.wast delete mode 100644 test/extended-names.wast.from-wast delete mode 100644 test/extended-names.wast.fromBinary delete mode 100644 test/extended-names.wast.fromBinary.noDebugInfo delete mode 100644 test/externref.wast.from-wast delete mode 100644 test/externref.wast.fromBinary delete mode 100644 test/externref.wast.fromBinary.noDebugInfo delete mode 100644 test/fn_prolog_epilog.debugInfo.wast delete mode 100644 test/fn_prolog_epilog.debugInfo.wast.from-wast delete mode 100644 test/fn_prolog_epilog.debugInfo.wast.fromBinary delete mode 100644 test/fn_prolog_epilog.debugInfo.wast.fromBinary.noDebugInfo delete mode 100644 test/gc.wast.from-wast delete mode 100644 test/gc.wast.fromBinary delete mode 100644 test/gc.wast.fromBinary.noDebugInfo delete mode 100644 test/grow_memory.wast delete mode 100644 test/grow_memory.wast.from-wast delete mode 100644 test/grow_memory.wast.fromBinary delete mode 100644 test/grow_memory.wast.fromBinary.noDebugInfo delete mode 100644 test/hello_world.wast.from-wast delete mode 100644 test/hello_world.wast.fromBinary delete mode 100644 test/hello_world.wast.fromBinary.noDebugInfo delete mode 100644 test/imported_memory.wast delete mode 100644 test/imported_memory.wast.from-wast delete mode 100644 test/imported_memory.wast.fromBinary delete mode 100644 test/imported_memory.wast.fromBinary.noDebugInfo delete mode 100644 test/imported_memory_growth.wast delete mode 100644 test/imported_memory_growth.wast.from-wast delete mode 100644 test/imported_memory_growth.wast.fromBinary delete mode 100644 test/imported_memory_growth.wast.fromBinary.noDebugInfo delete mode 100644 test/kitchen_sink.wast delete mode 100644 test/kitchen_sink.wast.from-wast delete mode 100644 test/kitchen_sink.wast.fromBinary delete mode 100644 test/kitchen_sink.wast.fromBinary.noDebugInfo create mode 100644 test/lit/basic/atomics-unshared.wast create mode 100644 test/lit/basic/atomics.wast create mode 100644 test/lit/basic/atomics64.wast create mode 100644 test/lit/basic/complexTextNames.wast create mode 100644 test/lit/basic/duplicate_types.wast create mode 100644 test/lit/basic/empty_imported_table.wast create mode 100644 test/lit/basic/empty_table.wast create mode 100644 test/lit/basic/exception-handling.wast create mode 100644 test/lit/basic/export-import.wast create mode 100644 test/lit/basic/extended-names.wast create mode 100644 test/lit/basic/fn_prolog_epilog.debugInfo.wast create mode 100644 test/lit/basic/grow_memory.wast create mode 100644 test/lit/basic/hello_world.wat create mode 100644 test/lit/basic/imported_memory.wast create mode 100644 test/lit/basic/imported_memory_growth.wast create mode 100644 test/lit/basic/kitchen_sink.wast create mode 100644 test/lit/basic/memory-import.wast create mode 100644 test/lit/basic/memory-import64.wast create mode 100644 test/lit/basic/memory-shared.wast create mode 100644 test/lit/basic/min.wast create mode 100644 test/lit/basic/multi-memories-atomics64.wast create mode 100644 test/lit/basic/multi-memories-basics.wast create mode 100644 test/lit/basic/multi-memories-simd.wast create mode 100644 test/lit/basic/multi-table.wast create mode 100644 test/lit/basic/mutable-global.wast create mode 100644 test/lit/basic/newsyntax.wast create mode 100644 test/lit/basic/nonspec-bulk-memory.wast create mode 100644 test/lit/basic/polymorphic_stack.wast create mode 100644 test/lit/basic/reference-types.wast create mode 100644 test/lit/basic/reg_switch.wast create mode 100644 test/lit/basic/segment-overlap.wast create mode 100644 test/lit/basic/signext.wast create mode 100644 test/lit/basic/simd.wast create mode 100644 test/lit/basic/simd64.wast create mode 100644 test/lit/basic/subtypes.wast create mode 100644 test/lit/basic/table-import.wast create mode 100644 test/lit/basic/tags.wast create mode 100644 test/lit/basic/unit.wat create mode 100644 test/lit/basic/unreachable-code.wast create mode 100644 test/lit/basic/unreachable-instr-type.wast create mode 100644 test/lit/basic/untaken-br_if.wast delete mode 100644 test/lit/multi-memories-atomics64.wast delete mode 100644 test/lit/multi-memories-basics.wast delete mode 100644 test/lit/multi-memories-simd.wast delete mode 100644 test/memory-import.wast delete mode 100644 test/memory-import.wast.from-wast delete mode 100644 test/memory-import.wast.fromBinary delete mode 100644 test/memory-import.wast.fromBinary.noDebugInfo delete mode 100644 test/memory-import64.wast delete mode 100644 test/memory-import64.wast.from-wast delete mode 100644 test/memory-import64.wast.fromBinary delete mode 100644 test/memory-import64.wast.fromBinary.noDebugInfo delete mode 100644 test/memory-shared.wast delete mode 100644 test/memory-shared.wast.from-wast delete mode 100644 test/memory-shared.wast.fromBinary delete mode 100644 test/memory-shared.wast.fromBinary.noDebugInfo delete mode 100644 test/min.wast delete mode 100644 test/min.wast.from-wast delete mode 100644 test/min.wast.fromBinary delete mode 100644 test/min.wast.fromBinary.noDebugInfo delete mode 100644 test/multi-memories-atomics64.wast delete mode 100644 test/multi-memories-atomics64.wast.from-wast delete mode 100644 test/multi-memories-atomics64.wast.fromBinary delete mode 100644 test/multi-memories-atomics64.wast.fromBinary.noDebugInfo delete mode 100644 test/multi-memories-basics.wast delete mode 100644 test/multi-memories-basics.wast.from-wast delete mode 100644 test/multi-memories-basics.wast.fromBinary delete mode 100644 test/multi-memories-basics.wast.fromBinary.noDebugInfo delete mode 100644 test/multi-memories-simd.wast delete mode 100644 test/multi-memories-simd.wast.from-wast delete mode 100644 test/multi-memories-simd.wast.fromBinary delete mode 100644 test/multi-memories-simd.wast.fromBinary.noDebugInfo delete mode 100644 test/multi-table.wast delete mode 100644 test/multi-table.wast.from-wast delete mode 100644 test/multi-table.wast.fromBinary delete mode 100644 test/multi-table.wast.fromBinary.noDebugInfo delete mode 100644 test/mutable-global.wast delete mode 100644 test/mutable-global.wast.from-wast delete mode 100644 test/mutable-global.wast.fromBinary delete mode 100644 test/mutable-global.wast.fromBinary.noDebugInfo delete mode 100644 test/newsyntax.wast delete mode 100644 test/newsyntax.wast.from-wast delete mode 100644 test/newsyntax.wast.fromBinary delete mode 100644 test/newsyntax.wast.fromBinary.noDebugInfo delete mode 100644 test/nonspec-bulk-memory.wast delete mode 100644 test/nonspec-bulk-memory.wast.from-wast delete mode 100644 test/nonspec-bulk-memory.wast.fromBinary delete mode 100644 test/nonspec-bulk-memory.wast.fromBinary.noDebugInfo delete mode 100644 test/polymorphic_stack.wast delete mode 100644 test/polymorphic_stack.wast.from-wast delete mode 100644 test/polymorphic_stack.wast.fromBinary delete mode 100644 test/polymorphic_stack.wast.fromBinary.noDebugInfo delete mode 100644 test/reference-types.wast delete mode 100644 test/reference-types.wast.from-wast delete mode 100644 test/reference-types.wast.fromBinary delete mode 100644 test/reference-types.wast.fromBinary.noDebugInfo delete mode 100644 test/reg_switch.wast delete mode 100644 test/reg_switch.wast.from-wast delete mode 100644 test/reg_switch.wast.fromBinary delete mode 100644 test/reg_switch.wast.fromBinary.noDebugInfo delete mode 100644 test/segment-overlap.wast delete mode 100644 test/segment-overlap.wast.from-wast delete mode 100644 test/segment-overlap.wast.fromBinary delete mode 100644 test/segment-overlap.wast.fromBinary.noDebugInfo delete mode 100644 test/signext.wast delete mode 100644 test/signext.wast.from-wast delete mode 100644 test/signext.wast.fromBinary delete mode 100644 test/signext.wast.fromBinary.noDebugInfo delete mode 100644 test/simd.wast delete mode 100644 test/simd.wast.from-wast delete mode 100644 test/simd.wast.fromBinary delete mode 100644 test/simd.wast.fromBinary.noDebugInfo delete mode 100644 test/simd64.wast delete mode 100644 test/simd64.wast.from-wast delete mode 100644 test/simd64.wast.fromBinary delete mode 100644 test/simd64.wast.fromBinary.noDebugInfo delete mode 100644 test/subtypes.wast delete mode 100644 test/subtypes.wast.from-wast delete mode 100644 test/subtypes.wast.fromBinary delete mode 100644 test/subtypes.wast.fromBinary.noDebugInfo delete mode 100644 test/table-import.wast delete mode 100644 test/table-import.wast.from-wast delete mode 100644 test/table-import.wast.fromBinary delete mode 100644 test/table-import.wast.fromBinary.noDebugInfo delete mode 100644 test/tags.wast delete mode 100644 test/tags.wast.from-wast delete mode 100644 test/tags.wast.fromBinary delete mode 100644 test/tags.wast.fromBinary.noDebugInfo delete mode 100644 test/tail-call.wast.from-wast delete mode 100644 test/tail-call.wast.fromBinary delete mode 100644 test/tail-call.wast.fromBinary.noDebugInfo delete mode 100644 test/unit.wast.from-wast delete mode 100644 test/unit.wast.fromBinary delete mode 100644 test/unit.wast.fromBinary.noDebugInfo delete mode 100644 test/unit.wat delete mode 100644 test/unreachable-code.wast delete mode 100644 test/unreachable-code.wast.from-wast delete mode 100644 test/unreachable-code.wast.fromBinary delete mode 100644 test/unreachable-code.wast.fromBinary.noDebugInfo delete mode 100644 test/unreachable-instr-type.wast delete mode 100644 test/unreachable-instr-type.wast.from-wast delete mode 100644 test/unreachable-instr-type.wast.fromBinary delete mode 100644 test/unreachable-instr-type.wast.fromBinary.noDebugInfo delete mode 100644 test/untaken-br_if.wast delete mode 100644 test/untaken-br_if.wast.from-wast delete mode 100644 test/untaken-br_if.wast.fromBinary delete mode 100644 test/untaken-br_if.wast.fromBinary.noDebugInfo diff --git a/check.py b/check.py index a7b2286fe12..5c0e19ff3d9 100755 --- a/check.py +++ b/check.py @@ -166,7 +166,7 @@ def run_wasm_reduce_tests(): if 'fsanitize=thread' not in str(os.environ): print('\n[ checking wasm-reduce fuzz testcase ]\n') # TODO: re-enable multivalue once it is better optimized - support.run_command(shared.WASM_OPT + [os.path.join(shared.options.binaryen_test, 'signext.wast'), '-ttf', '-Os', '-o', 'a.wasm', '--detect-features', '--disable-multivalue']) + support.run_command(shared.WASM_OPT + [os.path.join(shared.options.binaryen_test, 'lit/basic/signext.wast'), '-ttf', '-Os', '-o', 'a.wasm', '--detect-features', '--disable-multivalue']) before = os.stat('a.wasm').st_size support.run_command(shared.WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec --detect-features' % shared.WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm']) after = os.stat('c.wasm').st_size diff --git a/scripts/test/wasm2js.py b/scripts/test/wasm2js.py index cbae2216a9c..ec2c98124b2 100644 --- a/scripts/test/wasm2js.py +++ b/scripts/test/wasm2js.py @@ -18,9 +18,9 @@ from . import shared from . import support -tests = shared.get_tests(shared.options.binaryen_test) +basic_tests = shared.get_tests(os.path.join(shared.options.binaryen_test, 'lit', 'basic')) # memory64 is not supported in wasm2js yet (but may be with BigInt eventually). -tests = [t for t in tests if '64.wast' not in t] +basic_tests = [t for t in basic_tests if '64.wast' not in t] spec_tests = shared.options.spec_tests spec_tests = [t for t in spec_tests if '.fail' not in t] spec_tests = [t for t in spec_tests if '64.wast' not in t] @@ -36,7 +36,7 @@ def check_for_stale_files(): # TODO(sbc): Generalize and apply other test suites all_tests = [] - for t in tests + spec_tests + wasm2js_tests: + for t in basic_tests + spec_tests + wasm2js_tests: all_tests.append(os.path.basename(os.path.splitext(t)[0])) all_files = os.listdir(shared.get_test_dir('wasm2js')) @@ -50,7 +50,7 @@ def check_for_stale_files(): def test_wasm2js_output(): for opt in (0, 1): - for t in tests + spec_tests + wasm2js_tests: + for t in basic_tests + spec_tests + wasm2js_tests: basename = os.path.basename(t) if basename in wasm2js_blacklist: continue @@ -154,7 +154,7 @@ def update_wasm2js_tests(): print('\n[ checking wasm2js ]\n') for opt in (0, 1): - for wasm in tests + spec_tests + wasm2js_tests: + for wasm in basic_tests + spec_tests + wasm2js_tests: if not wasm.endswith('.wast'): continue diff --git a/scripts/test/wasm_opt.py b/scripts/test/wasm_opt.py index 9695eadca53..ee95029d6cb 100644 --- a/scripts/test/wasm_opt.py +++ b/scripts/test/wasm_opt.py @@ -104,35 +104,15 @@ def check(): actual, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate() shared.fail_if_not_identical(actual.strip(), open(os.path.join(shared.get_test_dir('print'), wasm + '.minified.txt')).read().strip()) - print('\n[ checking wasm-opt testcases... ]\n') - - for t in shared.get_tests(shared.options.binaryen_test, ['.wast']): - print('..', os.path.basename(t)) - f = t + '.from-wast' - cmd = shared.WASM_OPT + [t, '--print', '-all'] - actual = support.run_command(cmd) - actual = actual.replace('printing before:\n', '') - - shared.fail_if_not_identical_to_file(actual, f) - - # FIXME Remove this condition after nullref is implemented in V8 - if 'reference-types.wast' not in t: - shared.binary_format_check(t, wasm_as_args=['-g']) # test with debuginfo - shared.binary_format_check(t, wasm_as_args=[], binary_suffix='.fromBinary.noDebugInfo') # test without debuginfo - - shared.minify_check(t) - - print('\n[ checking wasm-opt debugInfo read-write... ]\n') - def update_wasm_opt_tests(): - print('\n[ checking wasm-opt -o notation... ]\n') + print('\n[ updating wasm-opt -o notation... ]\n') wast = os.path.join(shared.options.binaryen_test, 'hello_world.wat') cmd = shared.WASM_OPT + [wast, '-o', 'a.wast', '-S'] support.run_command(cmd) open(wast, 'w').write(open('a.wast').read()) - print('\n[ checking wasm-opt parsing & printing... ]\n') + print('\n[ updating wasm-opt parsing & printing... ]\n') for t in shared.get_tests(shared.get_test_dir('print'), ['.wast']): print('..', os.path.basename(t)) wasm = t.replace('.wast', '') @@ -148,7 +128,7 @@ def update_wasm_opt_tests(): with open(wasm + '.minified.txt', 'wb') as o: o.write(actual) - print('\n[ checking wasm-opt passes... ]\n') + print('\n[ updating wasm-opt passes... ]\n') for t in shared.get_tests(shared.get_test_dir('passes'), ['.wast', '.wasm']): print('..', os.path.basename(t)) # windows has some failures that need to be investigated: @@ -183,38 +163,3 @@ def update_wasm_opt_tests(): with open('a.wat') as i: with open(t + '.wat', 'w') as o: o.write(i.read()) - - print('\n[ checking wasm-opt testcases... ]\n') - for t in shared.get_tests(shared.options.binaryen_test, ['.wast']): - print('..', os.path.basename(t)) - f = t + '.from-wast' - cmd = shared.WASM_OPT + [t, '--print', '-all'] - actual = support.run_command(cmd) - actual = actual.replace('printing before:\n', '') - open(f, 'w').write(actual) - - print('\n[ checking binary format testcases... ]\n') - for wast in shared.get_tests(shared.options.binaryen_test, ['.wast']): - for debug_info in [0, 1]: - cmd = shared.WASM_AS + [wast, '-o', 'a.wasm', '-all'] - if debug_info: - cmd += ['-g'] - print(' '.join(cmd)) - if os.path.exists('a.wasm'): - os.unlink('a.wasm') - subprocess.check_call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - assert os.path.exists('a.wasm') - - cmd = shared.WASM_DIS + ['a.wasm', '-o', 'a.wast', '-all'] - print(' '.join(cmd)) - if os.path.exists('a.wast'): - os.unlink('a.wast') - subprocess.check_call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - assert os.path.exists('a.wast') - actual = open('a.wast').read() - binary_file = wast + '.fromBinary' - if not debug_info: - binary_file += '.noDebugInfo' - with open(binary_file, 'w') as o: - print('writey', binary_file) - o.write(actual) diff --git a/test/atomics-unshared.wast b/test/atomics-unshared.wast deleted file mode 100644 index 7b6d7bc3b7d..00000000000 --- a/test/atomics-unshared.wast +++ /dev/null @@ -1,10 +0,0 @@ -(module - (memory $0 1 1) - (func $foo - (drop (i32.atomic.rmw.cmpxchg - (i32.const 0) - (i32.const 0) - (i32.const 0) - )) - ) -) diff --git a/test/atomics-unshared.wast.from-wast b/test/atomics-unshared.wast.from-wast deleted file mode 100644 index 2e0ed82b9b0..00000000000 --- a/test/atomics-unshared.wast.from-wast +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1 1) - (func $foo (type $0) - (drop - (i32.atomic.rmw.cmpxchg - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - ) - ) -) diff --git a/test/atomics-unshared.wast.fromBinary b/test/atomics-unshared.wast.fromBinary deleted file mode 100644 index 321c8141ee8..00000000000 --- a/test/atomics-unshared.wast.fromBinary +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1 1) - (func $foo (type $0) - (drop - (i32.atomic.rmw.cmpxchg - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - ) - ) -) - diff --git a/test/atomics-unshared.wast.fromBinary.noDebugInfo b/test/atomics-unshared.wast.fromBinary.noDebugInfo deleted file mode 100644 index 0c47138fc04..00000000000 --- a/test/atomics-unshared.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1 1) - (func $0 (type $0) - (drop - (i32.atomic.rmw.cmpxchg - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - ) - ) -) - diff --git a/test/atomics.wast b/test/atomics.wast deleted file mode 100644 index 792772a510f..00000000000 --- a/test/atomics.wast +++ /dev/null @@ -1,184 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 align=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store8 offset=4 align=1 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $0) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw16.and_u align=2 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u align=1 - (local.get $0) - (local.get $0) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u align=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i32) - (local $1 i64) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 align=4 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.notify offset=24 align=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 align=8 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/atomics.wast.from-wast b/test/atomics.wast.from-wast deleted file mode 100644 index 7c9d18076a4..00000000000 --- a/test/atomics.wast.from-wast +++ /dev/null @@ -1,184 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $0) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $0) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i32) - (local $1 i64) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/atomics.wast.fromBinary b/test/atomics.wast.fromBinary deleted file mode 100644 index 751684f72fe..00000000000 --- a/test/atomics.wast.fromBinary +++ /dev/null @@ -1,185 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $0) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $0) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i32) - (local $1 i64) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) - diff --git a/test/atomics.wast.fromBinary.noDebugInfo b/test/atomics.wast.fromBinary.noDebugInfo deleted file mode 100644 index 375782db25d..00000000000 --- a/test/atomics.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,185 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 23 256)) - (func $0 (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $0) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $0) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $1 (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $0) - ) - ) - ) - (func $2 (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $0) - (local.get $0) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $3 (type $0) - (local $0 i32) - (local $1 i64) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $0) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $0) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $4 (type $0) - (atomic.fence) - ) -) - diff --git a/test/atomics64.wast b/test/atomics64.wast deleted file mode 100644 index 6ccab9cfa45..00000000000 --- a/test/atomics64.wast +++ /dev/null @@ -1,188 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared i64 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 align=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 offset=4 align=1 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u align=2 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u align=1 - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u align=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 align=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify offset=24 align=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 align=8 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/atomics64.wast.from-wast b/test/atomics64.wast.from-wast deleted file mode 100644 index d2e03030960..00000000000 --- a/test/atomics64.wast.from-wast +++ /dev/null @@ -1,188 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared i64 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/atomics64.wast.fromBinary b/test/atomics64.wast.fromBinary deleted file mode 100644 index f1be9008d85..00000000000 --- a/test/atomics64.wast.fromBinary +++ /dev/null @@ -1,189 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared i64 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) - diff --git a/test/atomics64.wast.fromBinary.noDebugInfo b/test/atomics64.wast.fromBinary.noDebugInfo deleted file mode 100644 index 2dce1d5f57a..00000000000 --- a/test/atomics64.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,189 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared i64 23 256)) - (func $0 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (i32.atomic.store offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $1 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u - (local.get $0) - (local.get $2) - ) - ) - ) - (func $2 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $3 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $4 (type $0) - (atomic.fence) - ) -) - diff --git a/test/complexTextNames.wast b/test/complexTextNames.wast deleted file mode 100644 index f27ca56b34e..00000000000 --- a/test/complexTextNames.wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (func $foo\20\28.bar\29) - (func "$zoo (.bar)" (call $foo\20\28.bar\29)) -) diff --git a/test/complexTextNames.wast.from-wast b/test/complexTextNames.wast.from-wast deleted file mode 100644 index f055f085056..00000000000 --- a/test/complexTextNames.wast.from-wast +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func)) - (export "$zoo (.bar)" (func $1)) - (func $foo\20\28.bar\29 (type $0) - (nop) - ) - (func $1 (type $0) - (call $foo\20\28.bar\29) - ) -) diff --git a/test/complexTextNames.wast.fromBinary b/test/complexTextNames.wast.fromBinary deleted file mode 100644 index ed3994dd0e0..00000000000 --- a/test/complexTextNames.wast.fromBinary +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $0 (func)) - (export "$zoo (.bar)" (func $1)) - (func $foo\20\28.bar\29 (type $0) - (nop) - ) - (func $1 (type $0) - (call $foo\20\28.bar\29) - ) -) - diff --git a/test/complexTextNames.wast.fromBinary.noDebugInfo b/test/complexTextNames.wast.fromBinary.noDebugInfo deleted file mode 100644 index 2cc81f7084b..00000000000 --- a/test/complexTextNames.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $0 (func)) - (export "$zoo (.bar)" (func $1)) - (func $0 (type $0) - (nop) - ) - (func $1 (type $0) - (call $0) - ) -) - diff --git a/test/duplicate_types.wast b/test/duplicate_types.wast deleted file mode 100644 index 2fd5e2f4b38..00000000000 --- a/test/duplicate_types.wast +++ /dev/null @@ -1,15 +0,0 @@ -(module ;; tests duplicate types are named properly - (type (func)) - (type (func)) - (type (func)) - (type (func (param i32))) - (type $0 (func (param i32))) - (type (func (param i32))) - (type $b (func (param i32) (result f32))) - (type (func (param i32) (result f32))) - - (func $f0 (param i32)) - (func $f1 (param i32) (result i32) - (i32.const 0) - ) -) diff --git a/test/duplicate_types.wast.from-wast b/test/duplicate_types.wast.from-wast deleted file mode 100644 index 20d2faba5ef..00000000000 --- a/test/duplicate_types.wast.from-wast +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func (param i32))) - (type $1 (func (param i32) (result i32))) - (func $f0 (type $0) (param $0 i32) - (nop) - ) - (func $f1 (type $1) (param $0 i32) (result i32) - (i32.const 0) - ) -) diff --git a/test/duplicate_types.wast.fromBinary b/test/duplicate_types.wast.fromBinary deleted file mode 100644 index ead3abc9f70..00000000000 --- a/test/duplicate_types.wast.fromBinary +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $0 (func (param i32))) - (type $1 (func (param i32) (result i32))) - (func $f0 (type $0) (param $0 i32) - (nop) - ) - (func $f1 (type $1) (param $0 i32) (result i32) - (i32.const 0) - ) -) - diff --git a/test/duplicate_types.wast.fromBinary.noDebugInfo b/test/duplicate_types.wast.fromBinary.noDebugInfo deleted file mode 100644 index f0a97e48819..00000000000 --- a/test/duplicate_types.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $0 (func (param i32))) - (type $1 (func (param i32) (result i32))) - (func $0 (type $0) (param $0 i32) - (nop) - ) - (func $1 (type $1) (param $0 i32) (result i32) - (i32.const 0) - ) -) - diff --git a/test/empty_imported_table.wast b/test/empty_imported_table.wast deleted file mode 100644 index e4314d59f84..00000000000 --- a/test/empty_imported_table.wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "table" (table 0 0 funcref)) - (memory $0 0) -) diff --git a/test/empty_imported_table.wast.from-wast b/test/empty_imported_table.wast.from-wast deleted file mode 100644 index 29a9780b11e..00000000000 --- a/test/empty_imported_table.wast.from-wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "table" (table $timport$0 0 0 funcref)) - (memory $0 0) -) diff --git a/test/empty_imported_table.wast.fromBinary b/test/empty_imported_table.wast.fromBinary deleted file mode 100644 index c2936323621..00000000000 --- a/test/empty_imported_table.wast.fromBinary +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "table" (table $timport$0 0 0 funcref)) - (memory $0 0) -) - diff --git a/test/empty_imported_table.wast.fromBinary.noDebugInfo b/test/empty_imported_table.wast.fromBinary.noDebugInfo deleted file mode 100644 index c2936323621..00000000000 --- a/test/empty_imported_table.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "table" (table $timport$0 0 0 funcref)) - (memory $0 0) -) - diff --git a/test/empty_table.wast b/test/empty_table.wast deleted file mode 100644 index 04f4026aff7..00000000000 --- a/test/empty_table.wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (table 0 0 funcref) - (memory $0 0) -) diff --git a/test/empty_table.wast.from-wast b/test/empty_table.wast.from-wast deleted file mode 100644 index 78d1b5937b7..00000000000 --- a/test/empty_table.wast.from-wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (memory $0 0) - (table $0 0 0 funcref) -) diff --git a/test/empty_table.wast.fromBinary b/test/empty_table.wast.fromBinary deleted file mode 100644 index f43b3c0010a..00000000000 --- a/test/empty_table.wast.fromBinary +++ /dev/null @@ -1,5 +0,0 @@ -(module - (memory $0 0) - (table $0 0 0 funcref) -) - diff --git a/test/empty_table.wast.fromBinary.noDebugInfo b/test/empty_table.wast.fromBinary.noDebugInfo deleted file mode 100644 index f43b3c0010a..00000000000 --- a/test/empty_table.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,5 +0,0 @@ -(module - (memory $0 0) - (table $0 0 0 funcref) -) - diff --git a/test/exception-handling.wast b/test/exception-handling.wast deleted file mode 100644 index 6a4b3b897d5..00000000000 --- a/test/exception-handling.wast +++ /dev/null @@ -1,386 +0,0 @@ -(module - (tag $e-i32 (param i32)) - (tag $e-i64 (param i64)) - (tag $e-i32-i64 (param i32 i64)) - (tag $e-eqref (param (ref null eq))) - (tag $e-empty) - - (func $foo) - (func $bar) - - ;; --------------------------------------------------------------------------- - ;; Old Phase 3 exception handling - - (func $eh-test (local $x (i32 i64)) - ;; Simple try-catch - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - ) - - ;; try-catch with multivalue tag - (try - (do - (throw $e-i32-i64 (i32.const 0) (i64.const 0)) - ) - (catch $e-i32-i64 - (local.set $x (pop i32 i64)) - (drop - (tuple.extract 2 0 - (local.get $x) - ) - ) - ) - ) - - ;; Try with a block label - (try $l1 - (do - (br $l1) - ) - (catch $e-i32 - (drop (pop i32)) - (br $l1) - ) - ) - - ;; Empty try body - (try - (do) - (catch $e-i32 - (drop (pop i32)) - ) - ) - - ;; Multiple instructions within try and catch bodies - (try - (do - (call $foo) - (call $bar) - ) - (catch $e-i32 - (drop (pop i32)) - (call $foo) - (call $bar) - ) - ) - - ;; Multiple catch clauses - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - ) - - ;; Single catch-all clause - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch_all) - ) - - ;; catch and catch-all clauses together - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - (catch_all - (call $foo) - (call $bar) - ) - ) - - ;; nested try-catch - (try - (do - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all) - ) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all) - ) - ) - ) - - ;; try without catch or delegate - (try - (do - (throw $e-i32 (i32.const 0)) - ) - ) - ) - - (func $delegate-test - ;; Inner delegates target an outer catch - (try $l0 - (do - (try - (do - (call $foo) - ) - (delegate $l0) ;; by label - ) - (try - (do - (call $foo) - ) - (delegate 0) ;; by depth - ) - ) - (catch_all) - ) - - ;; When there are both a branch and a delegate that target the same try - ;; label. Because binaryen only allows blocks and loops to be targetted by - ;; branches, we wrap the try with a block and make branches that block - ;; instead, resulting in the br and delegate target different labels in the - ;; output. - (try $l0 - (do - (try - (do - (br_if $l0 (i32.const 1)) - ) - (delegate $l0) ;; by label - ) - (try - (do - (br_if $l0 (i32.const 1)) - ) - (delegate 0) ;; by depth - ) - ) - (catch_all) - ) - - ;; The inner delegate targets the outer delegate, which in turn targets the - ;; caller. - (try $l0 - (do - (try - (do - (call $foo) - ) - (delegate $l0) - ) - ) - (delegate 0) - ) - - ;; 'catch' body can be empty when the tag's type is none. - (try - (do) - (catch $e-empty) - ) - ) - - (func $rethrow-test - ;; Simple try-catch-rethrow - (try $l0 - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) ;; by label - ) - (catch_all - (rethrow 0) ;; by depth - ) - ) - - ;; When there are both a branch and a rethrow that target the same try - ;; label. Because binaryen only allows blocks and loops to be targetted by - ;; branches, we wrap the try with a block and make branches that block - ;; instead, resulting in the br and rethrow target different labels in the - ;; output. - (try $l0 - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) - ) - (catch_all - (br $l0) - ) - ) - - ;; One more level deep - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) ;; by label - ) - (catch_all - (rethrow 1) ;; by depth - ) - ) - ) - ) - - ;; Interleaving block - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (block $b0 - (rethrow $l0) ;; by label - ) - ) - (catch_all - (block $b1 - (rethrow 2) ;; by depth - ) - ) - ) - ) - ) - - ;; Within nested try, but rather in 'try' part and not 'catch' - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (rethrow $l0) ;; by label - ) - (catch_all) - ) - ) - ) - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (rethrow 1) ;; by depth - ) - (catch_all) - ) - ) - ) - ) - - (func $pop-test - (try - (do) - (catch $e-i32 - (throw $e-i32 - (if (result i32) - ;; pop is within an if condition, so this is OK. - (pop i32) - (i32.const 0) - (i32.const 3) - ) - ) - ) - ) - - (try - (do) - (catch $e-eqref - (drop - (pop anyref) ;; pop can be supertype - ) - ) - ) - ) - - (func $catchless-try-with-inner-delegate - (try $label$0 - (do - (try - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (delegate $label$0) - ) - ) - ) - ) - - ;; When 'delegate' is next to a nested block, make sure its delegate argument - ;; is parsed correctly. - (func $nested-block-and-try - (block $l0 - (block $l1) - (try - (do) - (delegate 1) ;; to caller - ) - ) - (nop) - ) - - ;; --------------------------------------------------------------------------- - ;; New exception handling - - (func $exnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref) - (if (result exnref) - (i32.const 1) - (if (result nullexnref) - (i32.const 1) - (local.get $null-exn) - (ref.null noexn) - ) - (local.get $exn) - ) - ) -) diff --git a/test/exception-handling.wast.from-wast b/test/exception-handling.wast.from-wast deleted file mode 100644 index 8bd46bd8754..00000000000 --- a/test/exception-handling.wast.from-wast +++ /dev/null @@ -1,423 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32))) - (type $2 (func (param i64))) - (type $3 (func (param i32 i64))) - (type $4 (func (param eqref))) - (type $5 (func (result exnref))) - (tag $e-i32 (param i32)) - (tag $e-i64 (param i64)) - (tag $e-i32-i64 (param i32 i64)) - (tag $e-eqref (param eqref)) - (tag $e-empty) - (func $foo (type $0) - (nop) - ) - (func $bar (type $0) - (nop) - ) - (func $eh-test (type $0) - (local $x (i32 i64)) - (try $try - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - ) - (try $try0 - (do - (throw $e-i32-i64 - (i32.const 0) - (i64.const 0) - ) - ) - (catch $e-i32-i64 - (local.set $x - (pop i32 i64) - ) - (drop - (tuple.extract 2 0 - (local.get $x) - ) - ) - ) - ) - (block $l11 - (try $l1 - (do - (br $l11) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (br $l11) - ) - ) - ) - (try $try2 - (do - (nop) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - ) - (try $try3 - (do - (call $foo) - (call $bar) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (call $foo) - (call $bar) - ) - ) - (try $try4 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch $e-i64 - (drop - (pop i64) - ) - ) - ) - (try $try5 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch_all - (nop) - ) - ) - (try $try6 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch $e-i64 - (drop - (pop i64) - ) - ) - (catch_all - (call $foo) - (call $bar) - ) - ) - (try $try7 - (do - (try $try8 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (try $try9 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $try10 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - ) - ) - (func $delegate-test (type $0) - (try $l0 - (do - (try $try - (do - (call $foo) - ) - (delegate $l0) - ) - (try $try11 - (do - (call $foo) - ) - (delegate $l0) - ) - ) - (catch_all - (nop) - ) - ) - (block $l015 - (try $l012 - (do - (try $try13 - (do - (br_if $l015 - (i32.const 1) - ) - ) - (delegate $l012) - ) - (try $try14 - (do - (br_if $l015 - (i32.const 1) - ) - ) - (delegate $l012) - ) - ) - (catch_all - (nop) - ) - ) - ) - (try $l016 - (do - (try $try17 - (do - (call $foo) - ) - (delegate $l016) - ) - ) - (delegate 0) - ) - (try $try18 - (do - (nop) - ) - (catch $e-empty - (nop) - ) - ) - ) - (func $rethrow-test (type $0) - (try $l0 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $l0) - ) - (catch_all - (rethrow $l0) - ) - ) - (block $l020 - (try $l019 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $l019) - ) - (catch_all - (br $l020) - ) - ) - ) - (try $l021 - (do - (call $foo) - ) - (catch_all - (try $try - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $l021) - ) - (catch_all - (rethrow $l021) - ) - ) - ) - ) - (try $l022 - (do - (call $foo) - ) - (catch_all - (try $try23 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (block $b0 - (rethrow $l022) - ) - ) - (catch_all - (block $b1 - (rethrow $l022) - ) - ) - ) - ) - ) - (try $l024 - (do - (call $foo) - ) - (catch_all - (try $try25 - (do - (rethrow $l024) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $l026 - (do - (call $foo) - ) - (catch_all - (try $try27 - (do - (rethrow $l026) - ) - (catch_all - (nop) - ) - ) - ) - ) - ) - (func $pop-test (type $0) - (try $try - (do - (nop) - ) - (catch $e-i32 - (throw $e-i32 - (if (result i32) - (pop i32) - (i32.const 0) - (i32.const 3) - ) - ) - ) - ) - (try $try28 - (do - (nop) - ) - (catch $e-eqref - (drop - (pop anyref) - ) - ) - ) - ) - (func $catchless-try-with-inner-delegate (type $0) - (try $label$0 - (do - (try $try - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (delegate $label$0) - ) - ) - ) - ) - (func $nested-block-and-try (type $0) - (block $l0 - (block $l1 - ) - (try $try - (do - (nop) - ) - (delegate 1) - ) - ) - (nop) - ) - (func $exnref-test (type $5) (result exnref) - (local $exn exnref) - (local $null-exn nullexnref) - (if (result exnref) - (i32.const 1) - (if (result nullexnref) - (i32.const 1) - (local.get $null-exn) - (ref.null noexn) - ) - (local.get $exn) - ) - ) -) diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary deleted file mode 100644 index aa6e92788ac..00000000000 --- a/test/exception-handling.wast.fromBinary +++ /dev/null @@ -1,446 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32))) - (type $2 (func (param i64))) - (type $3 (func (param i32 i64))) - (type $4 (func (param eqref))) - (type $5 (func (result exnref))) - (tag $e-i32 (param i32)) - (tag $e-i64 (param i64)) - (tag $e-i32-i64 (param i32 i64)) - (tag $e-eqref (param eqref)) - (tag $e-empty) - (func $foo (type $0) - (nop) - ) - (func $bar (type $0) - (nop) - ) - (func $eh-test (type $0) - (local $x i32) - (local $1 i64) - (local $2 (i32 i64)) - (local $3 i32) - (try $label$3 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - ) - (try $label$6 - (do - (throw $e-i32-i64 - (i32.const 0) - (i64.const 0) - ) - ) - (catch $e-i32-i64 - (local.set $2 - (pop i32 i64) - ) - (local.set $x - (block (result i32) - (local.set $3 - (tuple.extract 2 0 - (local.get $2) - ) - ) - (local.set $1 - (tuple.extract 2 1 - (local.get $2) - ) - ) - (local.get $3) - ) - ) - (drop - (local.get $x) - ) - ) - ) - (block $label$7 - (try $label$10 - (do - (br $label$7) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (br $label$7) - ) - ) - ) - (try $label$13 - (do - (nop) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - ) - (try $label$16 - (do - (call $foo) - (call $bar) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (call $foo) - (call $bar) - ) - ) - (try $label$19 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch $e-i64 - (drop - (pop i64) - ) - ) - ) - (try $label$22 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch_all - (nop) - ) - ) - (try $label$25 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch $e-i64 - (drop - (pop i64) - ) - ) - (catch_all - (call $foo) - (call $bar) - ) - ) - (try $label$34 - (do - (try $label$29 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (try $label$33 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (catch $e-i32 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $label$37 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - ) - ) - (func $delegate-test (type $0) - (try $label$9 - (do - (block $label$1 - (try $label$4 - (do - (call $foo) - ) - (delegate $label$9) - ) - (try $label$7 - (do - (call $foo) - ) - (delegate $label$9) - ) - ) - ) - (catch_all - (nop) - ) - ) - (block $label$10 - (try $label$19 - (do - (block $label$11 - (try $label$14 - (do - (br_if $label$10 - (i32.const 1) - ) - ) - (delegate $label$19) - ) - (try $label$17 - (do - (br_if $label$10 - (i32.const 1) - ) - ) - (delegate $label$19) - ) - ) - ) - (catch_all - (nop) - ) - ) - ) - (try $label$25 - (do - (block $label$20 - (try $label$23 - (do - (call $foo) - ) - (delegate $label$25) - ) - ) - ) - (delegate 0) - ) - (try $label$28 - (do - (nop) - ) - (catch $e-empty - (nop) - ) - ) - ) - (func $rethrow-test (type $0) - (try $label$3 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $label$3) - ) - (catch_all - (rethrow $label$3) - ) - ) - (block $label$4 - (try $label$7 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $label$7) - ) - (catch_all - (br $label$4) - ) - ) - ) - (try $label$13 - (do - (call $foo) - ) - (catch_all - (try $label$12 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (rethrow $label$13) - ) - (catch_all - (rethrow $label$13) - ) - ) - ) - ) - (try $label$20 - (do - (call $foo) - ) - (catch_all - (try $label$19 - (do - (call $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (block $label$18 - (rethrow $label$20) - ) - ) - (catch_all - (rethrow $label$20) - ) - ) - ) - ) - (try $label$26 - (do - (call $foo) - ) - (catch_all - (try $label$25 - (do - (rethrow $label$26) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $label$32 - (do - (call $foo) - ) - (catch_all - (try $label$31 - (do - (rethrow $label$32) - ) - (catch_all - (nop) - ) - ) - ) - ) - ) - (func $pop-test (type $0) - (try $label$5 - (do - (nop) - ) - (catch $e-i32 - (throw $e-i32 - (if (result i32) - (pop i32) - (i32.const 0) - (i32.const 3) - ) - ) - ) - ) - (try $label$8 - (do - (nop) - ) - (catch $e-eqref - (drop - (pop eqref) - ) - ) - ) - ) - (func $catchless-try-with-inner-delegate (type $0) - (try $label$6 - (do - (block $label$1 - (try $label$4 - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (delegate $label$6) - ) - ) - ) - ) - ) - (func $nested-block-and-try (type $0) - (block $label$1 - (block $label$2 - ) - (try $label$5 - (do - (nop) - ) - (delegate 1) - ) - ) - (nop) - ) - (func $exnref-test (type $5) (result exnref) - (local $exn exnref) - (local $null-exn nullexnref) - (if (result exnref) - (i32.const 1) - (if (result nullexnref) - (i32.const 1) - (local.get $null-exn) - (ref.null noexn) - ) - (local.get $exn) - ) - ) -) - diff --git a/test/exception-handling.wast.fromBinary.noDebugInfo b/test/exception-handling.wast.fromBinary.noDebugInfo deleted file mode 100644 index b0da0391b12..00000000000 --- a/test/exception-handling.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,446 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32))) - (type $2 (func (param i64))) - (type $3 (func (param i32 i64))) - (type $4 (func (param eqref))) - (type $5 (func (result exnref))) - (tag $tag$0 (param i32)) - (tag $tag$1 (param i64)) - (tag $tag$2 (param i32 i64)) - (tag $tag$3 (param eqref)) - (tag $tag$4) - (func $0 (type $0) - (nop) - ) - (func $1 (type $0) - (nop) - ) - (func $2 (type $0) - (local $0 i32) - (local $1 i64) - (local $2 (i32 i64)) - (local $3 i32) - (try $label$3 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - ) - (try $label$6 - (do - (throw $tag$2 - (i32.const 0) - (i64.const 0) - ) - ) - (catch $tag$2 - (local.set $2 - (pop i32 i64) - ) - (local.set $0 - (block (result i32) - (local.set $3 - (tuple.extract 2 0 - (local.get $2) - ) - ) - (local.set $1 - (tuple.extract 2 1 - (local.get $2) - ) - ) - (local.get $3) - ) - ) - (drop - (local.get $0) - ) - ) - ) - (block $label$7 - (try $label$10 - (do - (br $label$7) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (br $label$7) - ) - ) - ) - (try $label$13 - (do - (nop) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - ) - (try $label$16 - (do - (call $0) - (call $1) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (call $0) - (call $1) - ) - ) - (try $label$19 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - (catch $tag$1 - (drop - (pop i64) - ) - ) - ) - (try $label$22 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch_all - (nop) - ) - ) - (try $label$25 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - (catch $tag$1 - (drop - (pop i64) - ) - ) - (catch_all - (call $0) - (call $1) - ) - ) - (try $label$34 - (do - (try $label$29 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - (catch_all - (try $label$33 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (catch $tag$0 - (drop - (pop i32) - ) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $label$37 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - ) - ) - (func $3 (type $0) - (try $label$9 - (do - (block $label$1 - (try $label$4 - (do - (call $0) - ) - (delegate $label$9) - ) - (try $label$7 - (do - (call $0) - ) - (delegate $label$9) - ) - ) - ) - (catch_all - (nop) - ) - ) - (block $label$10 - (try $label$19 - (do - (block $label$11 - (try $label$14 - (do - (br_if $label$10 - (i32.const 1) - ) - ) - (delegate $label$19) - ) - (try $label$17 - (do - (br_if $label$10 - (i32.const 1) - ) - ) - (delegate $label$19) - ) - ) - ) - (catch_all - (nop) - ) - ) - ) - (try $label$25 - (do - (block $label$20 - (try $label$23 - (do - (call $0) - ) - (delegate $label$25) - ) - ) - ) - (delegate 0) - ) - (try $label$28 - (do - (nop) - ) - (catch $tag$4 - (nop) - ) - ) - ) - (func $4 (type $0) - (try $label$3 - (do - (call $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (rethrow $label$3) - ) - (catch_all - (rethrow $label$3) - ) - ) - (block $label$4 - (try $label$7 - (do - (call $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (rethrow $label$7) - ) - (catch_all - (br $label$4) - ) - ) - ) - (try $label$13 - (do - (call $0) - ) - (catch_all - (try $label$12 - (do - (call $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (rethrow $label$13) - ) - (catch_all - (rethrow $label$13) - ) - ) - ) - ) - (try $label$20 - (do - (call $0) - ) - (catch_all - (try $label$19 - (do - (call $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (block $label$18 - (rethrow $label$20) - ) - ) - (catch_all - (rethrow $label$20) - ) - ) - ) - ) - (try $label$26 - (do - (call $0) - ) - (catch_all - (try $label$25 - (do - (rethrow $label$26) - ) - (catch_all - (nop) - ) - ) - ) - ) - (try $label$32 - (do - (call $0) - ) - (catch_all - (try $label$31 - (do - (rethrow $label$32) - ) - (catch_all - (nop) - ) - ) - ) - ) - ) - (func $5 (type $0) - (try $label$5 - (do - (nop) - ) - (catch $tag$0 - (throw $tag$0 - (if (result i32) - (pop i32) - (i32.const 0) - (i32.const 3) - ) - ) - ) - ) - (try $label$8 - (do - (nop) - ) - (catch $tag$3 - (drop - (pop eqref) - ) - ) - ) - ) - (func $6 (type $0) - (try $label$6 - (do - (block $label$1 - (try $label$4 - (do - (throw $tag$0 - (i32.const 0) - ) - ) - (delegate $label$6) - ) - ) - ) - ) - ) - (func $7 (type $0) - (block $label$1 - (block $label$2 - ) - (try $label$5 - (do - (nop) - ) - (delegate 1) - ) - ) - (nop) - ) - (func $8 (type $5) (result exnref) - (local $0 exnref) - (local $1 nullexnref) - (if (result exnref) - (i32.const 1) - (if (result nullexnref) - (i32.const 1) - (local.get $1) - (ref.null noexn) - ) - (local.get $0) - ) - ) -) - diff --git a/test/export-import.wast b/test/export-import.wast deleted file mode 100644 index 5dc2185c694..00000000000 --- a/test/export-import.wast +++ /dev/null @@ -1,8 +0,0 @@ -(module - (type $v (func)) - (import "env" "test1" (func $test1)) - (import "env" "test2" (global $test2 i32)) - (export "test1" (func $test1)) - (export "test2" (global $test2)) -) - diff --git a/test/export-import.wast.from-wast b/test/export-import.wast.from-wast deleted file mode 100644 index b56bd3f93f8..00000000000 --- a/test/export-import.wast.from-wast +++ /dev/null @@ -1,7 +0,0 @@ -(module - (type $v (func)) - (import "env" "test2" (global $test2 i32)) - (import "env" "test1" (func $test1 (type $v))) - (export "test1" (func $test1)) - (export "test2" (global $test2)) -) diff --git a/test/export-import.wast.fromBinary b/test/export-import.wast.fromBinary deleted file mode 100644 index 37a701e0765..00000000000 --- a/test/export-import.wast.fromBinary +++ /dev/null @@ -1,8 +0,0 @@ -(module - (type $v (func)) - (import "env" "test2" (global $test2 i32)) - (import "env" "test1" (func $test1 (type $v))) - (export "test1" (func $test1)) - (export "test2" (global $test2)) -) - diff --git a/test/export-import.wast.fromBinary.noDebugInfo b/test/export-import.wast.fromBinary.noDebugInfo deleted file mode 100644 index 0ac0ec0c9f5..00000000000 --- a/test/export-import.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,8 +0,0 @@ -(module - (type $0 (func)) - (import "env" "test2" (global $gimport$0 i32)) - (import "env" "test1" (func $fimport$0 (type $0))) - (export "test1" (func $fimport$0)) - (export "test2" (global $gimport$0)) -) - diff --git a/test/extended-names.wast b/test/extended-names.wast deleted file mode 100644 index 009ef5689b4..00000000000 --- a/test/extended-names.wast +++ /dev/null @@ -1,6 +0,0 @@ -(module $foo - (table $t1 1 funcref) - (memory $m1 1 1) - (data $mydata (i32.const 0) "a") - (data $passive_data "b") -) diff --git a/test/extended-names.wast.from-wast b/test/extended-names.wast.from-wast deleted file mode 100644 index 5719e9e445d..00000000000 --- a/test/extended-names.wast.from-wast +++ /dev/null @@ -1,6 +0,0 @@ -(module $foo - (memory $m1 1 1) - (data $mydata (i32.const 0) "a") - (data $passive_data "b") - (table $t1 1 funcref) -) diff --git a/test/extended-names.wast.fromBinary b/test/extended-names.wast.fromBinary deleted file mode 100644 index 18a08262d2d..00000000000 --- a/test/extended-names.wast.fromBinary +++ /dev/null @@ -1,7 +0,0 @@ -(module $foo - (memory $m1 1 1) - (data $mydata (i32.const 0) "a") - (data $passive_data "b") - (table $t1 1 funcref) -) - diff --git a/test/extended-names.wast.fromBinary.noDebugInfo b/test/extended-names.wast.fromBinary.noDebugInfo deleted file mode 100644 index 48a5ec9e5a5..00000000000 --- a/test/extended-names.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,7 +0,0 @@ -(module - (memory $0 1 1) - (data $0 (i32.const 0) "a") - (data $1 "b") - (table $0 1 funcref) -) - diff --git a/test/externref.wast.from-wast b/test/externref.wast.from-wast deleted file mode 100644 index 514123aabb1..00000000000 --- a/test/externref.wast.from-wast +++ /dev/null @@ -1,19 +0,0 @@ -(module - (type $externref_=>_externref (func (param externref) (result externref))) - (import "env" "test2" (global $test2 externref)) - (import "env" "test1" (func $test1 (param externref) (result externref))) - (memory $0 1 1) - (export "test1" (func $test1)) - (export "test2" (global $test2)) - (func $externref_test (; 1 ;) (param $0 externref) (result externref) - (local $1 externref) - (local.set $1 - (call $test1 - (local.get $0) - ) - ) - (return - (local.get $1) - ) - ) -) diff --git a/test/externref.wast.fromBinary b/test/externref.wast.fromBinary deleted file mode 100644 index ab2d2f96398..00000000000 --- a/test/externref.wast.fromBinary +++ /dev/null @@ -1,20 +0,0 @@ -(module - (type $externref_=>_externref (func (param externref) (result externref))) - (import "env" "test2" (global $gimport$1 externref)) - (import "env" "test1" (func $test1 (param externref) (result externref))) - (memory $0 1 1) - (export "test1" (func $test1)) - (export "test2" (global $gimport$1)) - (func $externref_test (; 1 ;) (param $0 externref) (result externref) - (local $1 externref) - (local.set $1 - (call $test1 - (local.get $0) - ) - ) - (return - (local.get $1) - ) - ) -) - diff --git a/test/externref.wast.fromBinary.noDebugInfo b/test/externref.wast.fromBinary.noDebugInfo deleted file mode 100644 index 44d9029bef7..00000000000 --- a/test/externref.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,20 +0,0 @@ -(module - (type $externref_=>_externref (func (param externref) (result externref))) - (import "env" "test2" (global $gimport$1 externref)) - (import "env" "test1" (func $fimport$0 (param externref) (result externref))) - (memory $0 1 1) - (export "test1" (func $fimport$0)) - (export "test2" (global $gimport$1)) - (func $0 (; 1 ;) (param $0 externref) (result externref) - (local $1 externref) - (local.set $1 - (call $fimport$0 - (local.get $0) - ) - ) - (return - (local.get $1) - ) - ) -) - diff --git a/test/fn_prolog_epilog.debugInfo.wast b/test/fn_prolog_epilog.debugInfo.wast deleted file mode 100644 index 39c893fbb24..00000000000 --- a/test/fn_prolog_epilog.debugInfo.wast +++ /dev/null @@ -1,16 +0,0 @@ -(module - ;;@ src.cpp:1:1 - (func - (nop) - ;;@ src.cpp:2:1 - (block $l0 - ;;@ src.cpp:2:2 - (block $l1 - (br $l1) - ) - ) - ;;@ src.cpp:3:1 - (return) - ;;@ src.cpp:3:2 - ) -) diff --git a/test/fn_prolog_epilog.debugInfo.wast.from-wast b/test/fn_prolog_epilog.debugInfo.wast.from-wast deleted file mode 100644 index 990d4e1407a..00000000000 --- a/test/fn_prolog_epilog.debugInfo.wast.from-wast +++ /dev/null @@ -1,17 +0,0 @@ -(module - (type $0 (func)) - ;;@ src.cpp:1:1 - (func $0 (type $0) - (nop) - ;;@ src.cpp:2:1 - (block $l0 - ;;@ src.cpp:2:2 - (block $l1 - (br $l1) - ) - ) - ;;@ src.cpp:3:1 - (return) - ;;@ src.cpp:3:2 - ) -) diff --git a/test/fn_prolog_epilog.debugInfo.wast.fromBinary b/test/fn_prolog_epilog.debugInfo.wast.fromBinary deleted file mode 100644 index e3b343451c3..00000000000 --- a/test/fn_prolog_epilog.debugInfo.wast.fromBinary +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $0 (func)) - (func $0 (type $0) - (nop) - (block $label$1 - (block $label$2 - (br $label$2) - ) - ) - (return) - ) -) - diff --git a/test/fn_prolog_epilog.debugInfo.wast.fromBinary.noDebugInfo b/test/fn_prolog_epilog.debugInfo.wast.fromBinary.noDebugInfo deleted file mode 100644 index e3b343451c3..00000000000 --- a/test/fn_prolog_epilog.debugInfo.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $0 (func)) - (func $0 (type $0) - (nop) - (block $label$1 - (block $label$2 - (br $label$2) - ) - ) - (return) - ) -) - diff --git a/test/gc.wast.from-wast b/test/gc.wast.from-wast deleted file mode 100644 index 38f7eb9f676..00000000000 --- a/test/gc.wast.from-wast +++ /dev/null @@ -1,154 +0,0 @@ -(module - (type $i31ref_structref_=>_none (func (param i31ref structref))) - (type $i31ref_ref|i31|_structref_ref|struct|_=>_none (func (param i31ref (ref i31) structref (ref struct)))) - (global $global_anyref (mut anyref) (ref.null none)) - (global $global_eqref (mut eqref) (ref.null none)) - (global $global_i31ref (mut i31ref) (ref.i31 - (i32.const 0) - )) - (global $global_anyref2 (mut anyref) (ref.null none)) - (global $global_anyref3 (mut anyref) (ref.i31 - (i32.const 0) - )) - (global $global_eqref2 (mut eqref) (ref.i31 - (i32.const 0) - )) - (func $test (type $i31ref_structref_=>_none) (param $local_i31ref i31ref) (param $local_structref structref) - (local $local_i32 i32) - (local $local_anyref anyref) - (local $local_eqref eqref) - (local.set $local_anyref - (local.get $local_anyref) - ) - (local.set $local_anyref - (global.get $global_anyref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_eqref - (local.get $local_eqref) - ) - (local.set $local_eqref - (global.get $global_eqref) - ) - (local.set $local_eqref - (ref.null none) - ) - (local.set $local_i31ref - (local.get $local_i31ref) - ) - (local.set $local_i31ref - (global.get $global_i31ref) - ) - (local.set $local_i31ref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_anyref - (local.get $local_eqref) - ) - (local.set $local_anyref - (global.get $global_eqref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_anyref - (local.get $local_i31ref) - ) - (local.set $local_anyref - (global.get $global_i31ref) - ) - (local.set $local_anyref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_eqref - (local.get $local_i31ref) - ) - (local.set $local_eqref - (global.get $global_i31ref) - ) - (local.set $local_eqref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_anyref - (local.get $local_anyref) - ) - (global.set $global_anyref - (global.get $global_anyref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_eqref - (local.get $local_eqref) - ) - (global.set $global_eqref - (global.get $global_eqref) - ) - (global.set $global_eqref - (ref.null none) - ) - (global.set $global_i31ref - (local.get $local_i31ref) - ) - (global.set $global_i31ref - (global.get $global_i31ref) - ) - (global.set $global_i31ref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_anyref - (local.get $local_eqref) - ) - (global.set $global_anyref - (global.get $global_eqref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_anyref - (local.get $local_i31ref) - ) - (global.set $global_anyref - (global.get $global_i31ref) - ) - (global.set $global_anyref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_eqref - (local.get $local_i31ref) - ) - (global.set $global_eqref - (global.get $global_i31ref) - ) - (global.set $global_eqref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_i32 - (i31.get_s - (local.get $local_i31ref) - ) - ) - (local.set $local_i32 - (i31.get_u - (local.get $local_i31ref) - ) - ) - ) - (func $test-variants (type $i31ref_ref|i31|_structref_ref|struct|_=>_none) (param $local_i31refnull i31ref) (param $local_i31refnonnull (ref i31)) (param $local_structrefnull structref) (param $local_structrefnonnull (ref struct)) - (nop) - ) -) diff --git a/test/gc.wast.fromBinary b/test/gc.wast.fromBinary deleted file mode 100644 index 8e5f11a0cc6..00000000000 --- a/test/gc.wast.fromBinary +++ /dev/null @@ -1,155 +0,0 @@ -(module - (type $i31ref_structref_=>_none (func (param i31ref structref))) - (type $i31ref_ref|i31|_structref_ref|struct|_=>_none (func (param i31ref (ref i31) structref (ref struct)))) - (global $global_anyref (mut anyref) (ref.null none)) - (global $global_eqref (mut eqref) (ref.null none)) - (global $global_i31ref (mut i31ref) (ref.i31 - (i32.const 0) - )) - (global $global_anyref2 (mut anyref) (ref.null none)) - (global $global_anyref3 (mut anyref) (ref.i31 - (i32.const 0) - )) - (global $global_eqref2 (mut eqref) (ref.i31 - (i32.const 0) - )) - (func $test (type $i31ref_structref_=>_none) (param $local_i31ref i31ref) (param $local_structref structref) - (local $local_i32 i32) - (local $local_anyref anyref) - (local $local_eqref eqref) - (local.set $local_anyref - (local.get $local_anyref) - ) - (local.set $local_anyref - (global.get $global_anyref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_eqref - (local.get $local_eqref) - ) - (local.set $local_eqref - (global.get $global_eqref) - ) - (local.set $local_eqref - (ref.null none) - ) - (local.set $local_i31ref - (local.get $local_i31ref) - ) - (local.set $local_i31ref - (global.get $global_i31ref) - ) - (local.set $local_i31ref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_anyref - (local.get $local_eqref) - ) - (local.set $local_anyref - (global.get $global_eqref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_anyref - (local.get $local_i31ref) - ) - (local.set $local_anyref - (global.get $global_i31ref) - ) - (local.set $local_anyref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_eqref - (local.get $local_i31ref) - ) - (local.set $local_eqref - (global.get $global_i31ref) - ) - (local.set $local_eqref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_anyref - (local.get $local_anyref) - ) - (global.set $global_anyref - (global.get $global_anyref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_eqref - (local.get $local_eqref) - ) - (global.set $global_eqref - (global.get $global_eqref) - ) - (global.set $global_eqref - (ref.null none) - ) - (global.set $global_i31ref - (local.get $local_i31ref) - ) - (global.set $global_i31ref - (global.get $global_i31ref) - ) - (global.set $global_i31ref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_anyref - (local.get $local_eqref) - ) - (global.set $global_anyref - (global.get $global_eqref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_anyref - (local.get $local_i31ref) - ) - (global.set $global_anyref - (global.get $global_i31ref) - ) - (global.set $global_anyref - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global_eqref - (local.get $local_i31ref) - ) - (global.set $global_eqref - (global.get $global_i31ref) - ) - (global.set $global_eqref - (ref.i31 - (i32.const 0) - ) - ) - (local.set $local_i32 - (i31.get_s - (local.get $local_i31ref) - ) - ) - (local.set $local_i32 - (i31.get_u - (local.get $local_i31ref) - ) - ) - ) - (func $test-variants (type $i31ref_ref|i31|_structref_ref|struct|_=>_none) (param $local_i31refnull i31ref) (param $local_i31refnonnull (ref i31)) (param $local_structrefnull structref) (param $local_structrefnonnull (ref struct)) - (nop) - ) -) - diff --git a/test/gc.wast.fromBinary.noDebugInfo b/test/gc.wast.fromBinary.noDebugInfo deleted file mode 100644 index 64f11cfafef..00000000000 --- a/test/gc.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,155 +0,0 @@ -(module - (type $i31ref_structref_=>_none (func (param i31ref structref))) - (type $i31ref_ref|i31|_structref_ref|struct|_=>_none (func (param i31ref (ref i31) structref (ref struct)))) - (global $global$0 (mut anyref) (ref.null none)) - (global $global$1 (mut eqref) (ref.null none)) - (global $global$2 (mut i31ref) (ref.i31 - (i32.const 0) - )) - (global $global$3 (mut anyref) (ref.null none)) - (global $global$4 (mut anyref) (ref.i31 - (i32.const 0) - )) - (global $global$5 (mut eqref) (ref.i31 - (i32.const 0) - )) - (func $0 (type $i31ref_structref_=>_none) (param $0 i31ref) (param $1 structref) - (local $2 i32) - (local $3 anyref) - (local $4 eqref) - (local.set $3 - (local.get $3) - ) - (local.set $3 - (global.get $global$0) - ) - (local.set $3 - (ref.null none) - ) - (local.set $4 - (local.get $4) - ) - (local.set $4 - (global.get $global$1) - ) - (local.set $4 - (ref.null none) - ) - (local.set $0 - (local.get $0) - ) - (local.set $0 - (global.get $global$2) - ) - (local.set $0 - (ref.i31 - (i32.const 0) - ) - ) - (local.set $3 - (local.get $4) - ) - (local.set $3 - (global.get $global$1) - ) - (local.set $3 - (ref.null none) - ) - (local.set $3 - (local.get $0) - ) - (local.set $3 - (global.get $global$2) - ) - (local.set $3 - (ref.i31 - (i32.const 0) - ) - ) - (local.set $4 - (local.get $0) - ) - (local.set $4 - (global.get $global$2) - ) - (local.set $4 - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global$0 - (local.get $3) - ) - (global.set $global$0 - (global.get $global$0) - ) - (global.set $global$0 - (ref.null none) - ) - (global.set $global$1 - (local.get $4) - ) - (global.set $global$1 - (global.get $global$1) - ) - (global.set $global$1 - (ref.null none) - ) - (global.set $global$2 - (local.get $0) - ) - (global.set $global$2 - (global.get $global$2) - ) - (global.set $global$2 - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global$0 - (local.get $4) - ) - (global.set $global$0 - (global.get $global$1) - ) - (global.set $global$0 - (ref.null none) - ) - (global.set $global$0 - (local.get $0) - ) - (global.set $global$0 - (global.get $global$2) - ) - (global.set $global$0 - (ref.i31 - (i32.const 0) - ) - ) - (global.set $global$1 - (local.get $0) - ) - (global.set $global$1 - (global.get $global$2) - ) - (global.set $global$1 - (ref.i31 - (i32.const 0) - ) - ) - (local.set $2 - (i31.get_s - (local.get $0) - ) - ) - (local.set $2 - (i31.get_u - (local.get $0) - ) - ) - ) - (func $1 (type $i31ref_ref|i31|_structref_ref|struct|_=>_none) (param $0 i31ref) (param $1 (ref i31)) (param $2 structref) (param $3 (ref struct)) - (nop) - ) -) - diff --git a/test/grow_memory.wast b/test/grow_memory.wast deleted file mode 100644 index 0022477133d..00000000000 --- a/test/grow_memory.wast +++ /dev/null @@ -1,17 +0,0 @@ -(module - (type $0 (func (param i32) (result i32))) - (type $1 (func (result i32))) - (memory $0 1) - (export "memory" (memory $0)) - (export "grow" (func $0)) - (export "current" (func $1)) - (func $0 (; 0 ;) (type $0) (param $var$0 i32) (result i32) - (memory.grow - (local.get $var$0) - ) - ) - (func $1 (; 1 ;) (type $1) (result i32) - (memory.size) - ) -) - diff --git a/test/grow_memory.wast.from-wast b/test/grow_memory.wast.from-wast deleted file mode 100644 index 9994eb61d11..00000000000 --- a/test/grow_memory.wast.from-wast +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $0 (func (param i32) (result i32))) - (type $1 (func (result i32))) - (memory $0 1) - (export "memory" (memory $0)) - (export "grow" (func $0)) - (export "current" (func $1)) - (func $0 (type $0) (param $var$0 i32) (result i32) - (memory.grow - (local.get $var$0) - ) - ) - (func $1 (type $1) (result i32) - (memory.size) - ) -) diff --git a/test/grow_memory.wast.fromBinary b/test/grow_memory.wast.fromBinary deleted file mode 100644 index ea4be881657..00000000000 --- a/test/grow_memory.wast.fromBinary +++ /dev/null @@ -1,17 +0,0 @@ -(module - (type $0 (func (param i32) (result i32))) - (type $1 (func (result i32))) - (memory $0 1) - (export "memory" (memory $0)) - (export "grow" (func $0)) - (export "current" (func $1)) - (func $0 (type $0) (param $var$0 i32) (result i32) - (memory.grow - (local.get $var$0) - ) - ) - (func $1 (type $1) (result i32) - (memory.size) - ) -) - diff --git a/test/grow_memory.wast.fromBinary.noDebugInfo b/test/grow_memory.wast.fromBinary.noDebugInfo deleted file mode 100644 index 2b7ab97d154..00000000000 --- a/test/grow_memory.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,17 +0,0 @@ -(module - (type $0 (func (param i32) (result i32))) - (type $1 (func (result i32))) - (memory $0 1) - (export "memory" (memory $0)) - (export "grow" (func $0)) - (export "current" (func $1)) - (func $0 (type $0) (param $0 i32) (result i32) - (memory.grow - (local.get $0) - ) - ) - (func $1 (type $1) (result i32) - (memory.size) - ) -) - diff --git a/test/hello_world.wast.from-wast b/test/hello_world.wast.from-wast deleted file mode 100644 index cbe9cb5ae14..00000000000 --- a/test/hello_world.wast.from-wast +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (memory $0 256 256) - (export "add" (func $add)) - (func $add (; 0 ;) (param $x i32) (param $y i32) (result i32) - (i32.add - (local.get $x) - (local.get $y) - ) - ) -) diff --git a/test/hello_world.wast.fromBinary b/test/hello_world.wast.fromBinary deleted file mode 100644 index 9b96024e208..00000000000 --- a/test/hello_world.wast.fromBinary +++ /dev/null @@ -1,12 +0,0 @@ -(module - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (memory $0 256 256) - (export "add" (func $add)) - (func $add (; 0 ;) (param $0 i32) (param $1 i32) (result i32) - (i32.add - (local.get $0) - (local.get $1) - ) - ) -) - diff --git a/test/hello_world.wast.fromBinary.noDebugInfo b/test/hello_world.wast.fromBinary.noDebugInfo deleted file mode 100644 index f44465c5ef0..00000000000 --- a/test/hello_world.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,12 +0,0 @@ -(module - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (memory $0 256 256) - (export "add" (func $0)) - (func $0 (; 0 ;) (param $0 i32) (param $1 i32) (result i32) - (i32.add - (local.get $0) - (local.get $1) - ) - ) -) - diff --git a/test/imported_memory.wast b/test/imported_memory.wast deleted file mode 100644 index 51bd9ce461d..00000000000 --- a/test/imported_memory.wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "memory" (memory $0 256 256)) - (import "env" "table" (table 256 256 funcref)) -) diff --git a/test/imported_memory.wast.from-wast b/test/imported_memory.wast.from-wast deleted file mode 100644 index f36ba739685..00000000000 --- a/test/imported_memory.wast.from-wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "memory" (memory $0 256 256)) - (import "env" "table" (table $timport$0 256 256 funcref)) -) diff --git a/test/imported_memory.wast.fromBinary b/test/imported_memory.wast.fromBinary deleted file mode 100644 index ae1205de00a..00000000000 --- a/test/imported_memory.wast.fromBinary +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "memory" (memory $0 256 256)) - (import "env" "table" (table $timport$0 256 256 funcref)) -) - diff --git a/test/imported_memory.wast.fromBinary.noDebugInfo b/test/imported_memory.wast.fromBinary.noDebugInfo deleted file mode 100644 index 46ecefe0f8e..00000000000 --- a/test/imported_memory.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "memory" (memory $mimport$0 256 256)) - (import "env" "table" (table $timport$0 256 256 funcref)) -) - diff --git a/test/imported_memory_growth.wast b/test/imported_memory_growth.wast deleted file mode 100644 index 8f47fb8a1cd..00000000000 --- a/test/imported_memory_growth.wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "memory" (memory $0 256)) - (import "env" "table" (table 256 funcref)) -) diff --git a/test/imported_memory_growth.wast.from-wast b/test/imported_memory_growth.wast.from-wast deleted file mode 100644 index a2533591b7b..00000000000 --- a/test/imported_memory_growth.wast.from-wast +++ /dev/null @@ -1,4 +0,0 @@ -(module - (import "env" "memory" (memory $0 256)) - (import "env" "table" (table $timport$0 256 funcref)) -) diff --git a/test/imported_memory_growth.wast.fromBinary b/test/imported_memory_growth.wast.fromBinary deleted file mode 100644 index 75fe9ff1482..00000000000 --- a/test/imported_memory_growth.wast.fromBinary +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "memory" (memory $0 256)) - (import "env" "table" (table $timport$0 256 funcref)) -) - diff --git a/test/imported_memory_growth.wast.fromBinary.noDebugInfo b/test/imported_memory_growth.wast.fromBinary.noDebugInfo deleted file mode 100644 index e0dc8ab7a06..00000000000 --- a/test/imported_memory_growth.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,5 +0,0 @@ -(module - (import "env" "memory" (memory $mimport$0 256)) - (import "env" "table" (table $timport$0 256 funcref)) -) - diff --git a/test/kitchen_sink.wast b/test/kitchen_sink.wast deleted file mode 100644 index e8c6cd5896f..00000000000 --- a/test/kitchen_sink.wast +++ /dev/null @@ -1,707 +0,0 @@ -(module - (type $0 (func (result i32))) - (memory $0 4096 4096) - (data (i32.const 1026) "\14\00") - (func $kitchensink (type $0) (result i32) - (block $block0 (result i32) - (drop - (i32.add - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.sub - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.mul - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.and - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.or - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.xor - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shl - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.eq - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ne - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.clz - (i32.const 10) - ) - ) - (drop - (i32.ctz - (i32.const 10) - ) - ) - (drop - (i32.popcnt - (i32.const 10) - ) - ) - (drop - (i64.add - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.sub - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.mul - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.and - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.or - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.xor - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shl - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ne - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.clz - (i64.const 100) - ) - ) - (drop - (i64.ctz - (i64.const 100) - ) - ) - (drop - (i64.popcnt - (i64.const 100) - ) - ) - (drop - (f32.add - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.sub - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.mul - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.div - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.min - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.max - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.abs - (f32.const 10) - ) - ) - (drop - (f32.neg - (f32.const 10) - ) - ) - (drop - (f32.copysign - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ceil - (f32.const 10) - ) - ) - (drop - (f32.floor - (f32.const 10) - ) - ) - (drop - (f32.trunc - (f32.const 10) - ) - ) - (drop - (f32.nearest - (f32.const 10) - ) - ) - (drop - (f32.sqrt - (f32.const 10) - ) - ) - (drop - (f32.eq - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ne - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.lt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.le - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.gt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ge - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f64.add - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.sub - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.mul - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.div - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.min - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.max - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.abs - (f64.const 10) - ) - ) - (drop - (f64.neg - (f64.const 10) - ) - ) - (drop - (f64.copysign - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ceil - (f64.const 10) - ) - ) - (drop - (f64.floor - (f64.const 10) - ) - ) - (drop - (f64.trunc - (f64.const 10) - ) - ) - (drop - (f64.nearest - (f64.const 10) - ) - ) - (drop - (f64.sqrt - (f64.const 10) - ) - ) - (drop - (f64.eq - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ne - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.lt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.le - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.gt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ge - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i32.wrap_i64 - (i64.const 100) - ) - ) - (drop - (i64.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i64.extend_i32_s - (i32.const 10) - ) - ) - (drop - (i64.extend_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f32.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f32.demote_f64 - (f64.const 10) - ) - ) - (drop - (f32.reinterpret_i32 - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f64.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f64.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f64.promote_f32 - (f32.const 10) - ) - ) - (drop - (f64.reinterpret_i64 - (i64.const 100) - ) - ) - (drop - (i32.reinterpret_f32 - (f32.const 10) - ) - ) - (drop - (i64.reinterpret_f64 - (f64.const 10) - ) - ) - (i32.const 0) - ) - ) -) diff --git a/test/kitchen_sink.wast.from-wast b/test/kitchen_sink.wast.from-wast deleted file mode 100644 index 522f9d3b57b..00000000000 --- a/test/kitchen_sink.wast.from-wast +++ /dev/null @@ -1,707 +0,0 @@ -(module - (type $0 (func (result i32))) - (memory $0 4096 4096) - (data $0 (i32.const 1026) "\14\00") - (func $kitchensink (type $0) (result i32) - (block $block0 (result i32) - (drop - (i32.add - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.sub - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.mul - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.and - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.or - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.xor - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shl - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.eq - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ne - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.clz - (i32.const 10) - ) - ) - (drop - (i32.ctz - (i32.const 10) - ) - ) - (drop - (i32.popcnt - (i32.const 10) - ) - ) - (drop - (i64.add - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.sub - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.mul - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.and - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.or - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.xor - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shl - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ne - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.clz - (i64.const 100) - ) - ) - (drop - (i64.ctz - (i64.const 100) - ) - ) - (drop - (i64.popcnt - (i64.const 100) - ) - ) - (drop - (f32.add - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.sub - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.mul - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.div - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.min - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.max - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.abs - (f32.const 10) - ) - ) - (drop - (f32.neg - (f32.const 10) - ) - ) - (drop - (f32.copysign - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ceil - (f32.const 10) - ) - ) - (drop - (f32.floor - (f32.const 10) - ) - ) - (drop - (f32.trunc - (f32.const 10) - ) - ) - (drop - (f32.nearest - (f32.const 10) - ) - ) - (drop - (f32.sqrt - (f32.const 10) - ) - ) - (drop - (f32.eq - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ne - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.lt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.le - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.gt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ge - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f64.add - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.sub - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.mul - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.div - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.min - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.max - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.abs - (f64.const 10) - ) - ) - (drop - (f64.neg - (f64.const 10) - ) - ) - (drop - (f64.copysign - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ceil - (f64.const 10) - ) - ) - (drop - (f64.floor - (f64.const 10) - ) - ) - (drop - (f64.trunc - (f64.const 10) - ) - ) - (drop - (f64.nearest - (f64.const 10) - ) - ) - (drop - (f64.sqrt - (f64.const 10) - ) - ) - (drop - (f64.eq - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ne - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.lt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.le - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.gt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ge - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i32.wrap_i64 - (i64.const 100) - ) - ) - (drop - (i64.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i64.extend_i32_s - (i32.const 10) - ) - ) - (drop - (i64.extend_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f32.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f32.demote_f64 - (f64.const 10) - ) - ) - (drop - (f32.reinterpret_i32 - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f64.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f64.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f64.promote_f32 - (f32.const 10) - ) - ) - (drop - (f64.reinterpret_i64 - (i64.const 100) - ) - ) - (drop - (i32.reinterpret_f32 - (f32.const 10) - ) - ) - (drop - (i64.reinterpret_f64 - (f64.const 10) - ) - ) - (i32.const 0) - ) - ) -) diff --git a/test/kitchen_sink.wast.fromBinary b/test/kitchen_sink.wast.fromBinary deleted file mode 100644 index 12b3aaf5c7f..00000000000 --- a/test/kitchen_sink.wast.fromBinary +++ /dev/null @@ -1,706 +0,0 @@ -(module - (type $0 (func (result i32))) - (memory $0 4096 4096) - (data $0 (i32.const 1026) "\14\00") - (func $kitchensink (type $0) (result i32) - (drop - (i32.add - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.sub - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.mul - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.and - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.or - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.xor - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shl - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.eq - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ne - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.clz - (i32.const 10) - ) - ) - (drop - (i32.ctz - (i32.const 10) - ) - ) - (drop - (i32.popcnt - (i32.const 10) - ) - ) - (drop - (i64.add - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.sub - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.mul - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.and - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.or - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.xor - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shl - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ne - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.clz - (i64.const 100) - ) - ) - (drop - (i64.ctz - (i64.const 100) - ) - ) - (drop - (i64.popcnt - (i64.const 100) - ) - ) - (drop - (f32.add - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.sub - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.mul - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.div - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.min - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.max - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.abs - (f32.const 10) - ) - ) - (drop - (f32.neg - (f32.const 10) - ) - ) - (drop - (f32.copysign - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ceil - (f32.const 10) - ) - ) - (drop - (f32.floor - (f32.const 10) - ) - ) - (drop - (f32.trunc - (f32.const 10) - ) - ) - (drop - (f32.nearest - (f32.const 10) - ) - ) - (drop - (f32.sqrt - (f32.const 10) - ) - ) - (drop - (f32.eq - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ne - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.lt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.le - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.gt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ge - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f64.add - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.sub - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.mul - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.div - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.min - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.max - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.abs - (f64.const 10) - ) - ) - (drop - (f64.neg - (f64.const 10) - ) - ) - (drop - (f64.copysign - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ceil - (f64.const 10) - ) - ) - (drop - (f64.floor - (f64.const 10) - ) - ) - (drop - (f64.trunc - (f64.const 10) - ) - ) - (drop - (f64.nearest - (f64.const 10) - ) - ) - (drop - (f64.sqrt - (f64.const 10) - ) - ) - (drop - (f64.eq - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ne - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.lt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.le - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.gt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ge - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i32.wrap_i64 - (i64.const 100) - ) - ) - (drop - (i64.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i64.extend_i32_s - (i32.const 10) - ) - ) - (drop - (i64.extend_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f32.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f32.demote_f64 - (f64.const 10) - ) - ) - (drop - (f32.reinterpret_i32 - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f64.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f64.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f64.promote_f32 - (f32.const 10) - ) - ) - (drop - (f64.reinterpret_i64 - (i64.const 100) - ) - ) - (drop - (i32.reinterpret_f32 - (f32.const 10) - ) - ) - (drop - (i64.reinterpret_f64 - (f64.const 10) - ) - ) - (i32.const 0) - ) -) - diff --git a/test/kitchen_sink.wast.fromBinary.noDebugInfo b/test/kitchen_sink.wast.fromBinary.noDebugInfo deleted file mode 100644 index 30b11066289..00000000000 --- a/test/kitchen_sink.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,706 +0,0 @@ -(module - (type $0 (func (result i32))) - (memory $0 4096 4096) - (data $0 (i32.const 1026) "\14\00") - (func $0 (type $0) (result i32) - (drop - (i32.add - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.sub - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.mul - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.div_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.rem_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.and - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.or - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.xor - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shl - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.shr_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.eq - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ne - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.lt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.le_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_s - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.gt_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.ge_u - (i32.const 10) - (i32.const 10) - ) - ) - (drop - (i32.clz - (i32.const 10) - ) - ) - (drop - (i32.ctz - (i32.const 10) - ) - ) - (drop - (i32.popcnt - (i32.const 10) - ) - ) - (drop - (i64.add - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.sub - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.mul - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.div_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.rem_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.and - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.or - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.xor - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shl - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.shr_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ne - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.lt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.le_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_s - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.gt_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.ge_u - (i64.const 100) - (i64.const 100) - ) - ) - (drop - (i64.clz - (i64.const 100) - ) - ) - (drop - (i64.ctz - (i64.const 100) - ) - ) - (drop - (i64.popcnt - (i64.const 100) - ) - ) - (drop - (f32.add - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.sub - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.mul - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.div - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.min - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.max - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.abs - (f32.const 10) - ) - ) - (drop - (f32.neg - (f32.const 10) - ) - ) - (drop - (f32.copysign - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ceil - (f32.const 10) - ) - ) - (drop - (f32.floor - (f32.const 10) - ) - ) - (drop - (f32.trunc - (f32.const 10) - ) - ) - (drop - (f32.nearest - (f32.const 10) - ) - ) - (drop - (f32.sqrt - (f32.const 10) - ) - ) - (drop - (f32.eq - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ne - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.lt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.le - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.gt - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f32.ge - (f32.const 10) - (f32.const 10) - ) - ) - (drop - (f64.add - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.sub - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.mul - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.div - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.min - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.max - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.abs - (f64.const 10) - ) - ) - (drop - (f64.neg - (f64.const 10) - ) - ) - (drop - (f64.copysign - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ceil - (f64.const 10) - ) - ) - (drop - (f64.floor - (f64.const 10) - ) - ) - (drop - (f64.trunc - (f64.const 10) - ) - ) - (drop - (f64.nearest - (f64.const 10) - ) - ) - (drop - (f64.sqrt - (f64.const 10) - ) - ) - (drop - (f64.eq - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ne - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.lt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.le - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.gt - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (f64.ge - (f64.const 10) - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i32.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i32.wrap_i64 - (i64.const 100) - ) - ) - (drop - (i64.trunc_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_f64_u - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_s - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f32_u - (f32.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_s - (f64.const 10) - ) - ) - (drop - (i64.trunc_sat_f64_u - (f64.const 10) - ) - ) - (drop - (i64.extend_i32_s - (i32.const 10) - ) - ) - (drop - (i64.extend_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f32.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f32.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f32.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f32.demote_f64 - (f64.const 10) - ) - ) - (drop - (f32.reinterpret_i32 - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_s - (i32.const 10) - ) - ) - (drop - (f64.convert_i32_u - (i32.const 10) - ) - ) - (drop - (f64.convert_i64_s - (i64.const 100) - ) - ) - (drop - (f64.convert_i64_u - (i64.const 100) - ) - ) - (drop - (f64.promote_f32 - (f32.const 10) - ) - ) - (drop - (f64.reinterpret_i64 - (i64.const 100) - ) - ) - (drop - (i32.reinterpret_f32 - (f32.const 10) - ) - ) - (drop - (i64.reinterpret_f64 - (f64.const 10) - ) - ) - (i32.const 0) - ) -) - diff --git a/test/lit/basic/atomics-unshared.wast b/test/lit/basic/atomics-unshared.wast new file mode 100644 index 00000000000..3a2196bb34b --- /dev/null +++ b/test/lit/basic/atomics-unshared.wast @@ -0,0 +1,58 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (memory $0 1 1) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (memory $0 1 1) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + + ;; CHECK-BIN-NODEBUG: (memory $0 1 1) + (memory $0 1 1) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.cmpxchg + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $foo + (drop (i32.atomic.rmw.cmpxchg + (i32.const 0) + (i32.const 0) + (i32.const 0) + )) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.cmpxchg +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/atomics.wast b/test/lit/basic/atomics.wast new file mode 100644 index 00000000000..ef98afe4e9a --- /dev/null +++ b/test/lit/basic/atomics.wast @@ -0,0 +1,750 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (memory $0 (shared 23 256)) + ;; CHECK-BIN: (memory $0 (shared 23 256)) + ;; CHECK-BIN-NODEBUG: (memory $0 (shared 23 256)) + (memory $0 (shared 23 256)) + + ;; CHECK-TEXT: (func $atomic-loadstore (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i32) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load8_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load16_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load32_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store8 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store16 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store8 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store16 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store32 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-loadstore (type $0) + ;; CHECK-BIN-NEXT: (local $0 i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load8_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load16_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load32_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store8 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store16 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store8 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store16 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store32 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-loadstore (type $0) + (local $0 i32) + (local $1 i64) + (drop + (i32.atomic.load8_u offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load16_u offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load offset=4 + (local.get $0) + ) + ) + (drop + (i64.atomic.load8_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load16_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load32_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load + (local.get $0) + ) + ) + (i32.atomic.store offset=4 align=4 + (local.get $0) + (local.get $0) + ) + (i32.atomic.store8 offset=4 align=1 + (local.get $0) + (local.get $0) + ) + (i32.atomic.store16 offset=4 + (local.get $0) + (local.get $0) + ) + (i64.atomic.store offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store8 offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store16 offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store32 offset=4 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $atomic-rmw (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i32) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.add offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.add_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw16.and_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.or_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.xchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-rmw (type $0) + ;; CHECK-BIN-NEXT: (local $0 i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.add offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.add_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw16.and_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.or_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.xchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-rmw (type $0) + (local $0 i32) + (local $1 i64) + (drop + (i32.atomic.rmw.add offset=4 + (local.get $0) + (local.get $0) + ) + ) + (drop + (i32.atomic.rmw8.add_u offset=4 + (local.get $0) + (local.get $0) + ) + ) + (drop + (i32.atomic.rmw16.and_u align=2 + (local.get $0) + (local.get $0) + ) + ) + (drop + (i64.atomic.rmw32.or_u + (local.get $0) + (local.get $1) + ) + ) + (drop + (i32.atomic.rmw8.xchg_u align=1 + (local.get $0) + (local.get $0) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-cmpxchg (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i32) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw.cmpxchg offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.cmpxchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-cmpxchg (type $0) + ;; CHECK-BIN-NEXT: (local $0 i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.cmpxchg offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw.cmpxchg offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.cmpxchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-cmpxchg (type $0) + (local $0 i32) + (local $1 i64) + (drop + (i32.atomic.rmw.cmpxchg offset=4 + (local.get $0) + (local.get $0) + (local.get $0) + ) + ) + (drop + (i32.atomic.rmw8.cmpxchg_u + (local.get $0) + (local.get $0) + (local.get $0) + ) + ) + (drop + (i64.atomic.rmw.cmpxchg offset=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw32.cmpxchg_u align=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-wait-notify (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i32) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify offset=24 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 offset=16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-wait-notify (type $0) + ;; CHECK-BIN-NEXT: (local $0 i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify offset=24 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 offset=16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-wait-notify (type $0) + (local $0 i32) + (local $1 i64) + (drop + (memory.atomic.wait32 + (local.get $0) + (local.get $0) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait32 offset=4 align=4 + (local.get $0) + (local.get $0) + (local.get $1) + ) + ) + (drop + (memory.atomic.notify + (local.get $0) + (local.get $0) + ) + ) + (drop + (memory.atomic.notify offset=24 align=4 + (local.get $0) + (local.get $0) + ) + ) + (drop + (memory.atomic.wait64 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait64 align=8 offset=16 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-fence (type $0) + ;; CHECK-TEXT-NEXT: (atomic.fence) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-fence (type $0) + ;; CHECK-BIN-NEXT: (atomic.fence) + ;; CHECK-BIN-NEXT: ) + (func $atomic-fence (type $0) + (atomic.fence) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load8_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load16_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load32_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store8 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store16 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store8 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store16 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store32 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.add offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.add_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw16.and_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.or_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.xchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.cmpxchg offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.cmpxchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw.cmpxchg offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.cmpxchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify offset=24 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 offset=16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (atomic.fence) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/atomics64.wast b/test/lit/basic/atomics64.wast new file mode 100644 index 00000000000..b30b1ce6e36 --- /dev/null +++ b/test/lit/basic/atomics64.wast @@ -0,0 +1,766 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (memory $0 (shared i64 23 256)) + ;; CHECK-BIN: (memory $0 (shared i64 23 256)) + ;; CHECK-BIN-NODEBUG: (memory $0 (shared i64 23 256)) + (memory $0 (shared i64 23 256)) + + ;; CHECK-TEXT: (func $atomic-loadstore (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load8_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load16_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load32_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store8 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store16 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store8 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store16 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store32 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-loadstore (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load8_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load16_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load32_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store8 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store16 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store8 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store16 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store32 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-loadstore (type $0) + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.load8_u offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load16_u offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load offset=4 + (local.get $0) + ) + ) + (drop + (i64.atomic.load8_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load16_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load32_u + (local.get $0) + ) + ) + (drop + (i64.atomic.load + (local.get $0) + ) + ) + (i32.atomic.store offset=4 align=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store8 offset=4 align=1 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store16 offset=4 + (local.get $0) + (local.get $2) + ) + (i64.atomic.store offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store8 offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store16 offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store32 offset=4 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $atomic-rmw (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.add offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.add_u offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw16.and_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.or_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.xchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-rmw (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.add offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.add_u offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw16.and_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.or_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.xchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-rmw (type $0) + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.rmw.add offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.add_u offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw16.and_u align=2 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i64.atomic.rmw32.or_u + (local.get $0) + (local.get $1) + ) + ) + (drop + (i32.atomic.rmw8.xchg_u align=1 + (local.get $0) + (local.get $2) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-cmpxchg (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw.cmpxchg offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.cmpxchg_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-cmpxchg (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.cmpxchg offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw.cmpxchg offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.cmpxchg_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-cmpxchg (type $0) + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.rmw.cmpxchg offset=4 + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.cmpxchg_u + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i64.atomic.rmw.cmpxchg offset=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw32.cmpxchg_u align=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-wait-notify (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify offset=24 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 offset=16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-wait-notify (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify offset=24 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 offset=16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-wait-notify (type $0) + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (memory.atomic.wait32 + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait32 offset=4 align=4 + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.notify + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.notify offset=24 align=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.wait64 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait64 align=8 offset=16 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-fence (type $0) + ;; CHECK-TEXT-NEXT: (atomic.fence) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-fence (type $0) + ;; CHECK-BIN-NEXT: (atomic.fence) + ;; CHECK-BIN-NEXT: ) + (func $atomic-fence (type $0) + (atomic.fence) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load8_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load16_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load32_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store8 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store16 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store8 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store16 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store32 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.add offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.add_u offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw16.and_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.or_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.xchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.cmpxchg offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.cmpxchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw.cmpxchg offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.cmpxchg_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify offset=24 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 offset=16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (atomic.fence) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/complexTextNames.wast b/test/lit/basic/complexTextNames.wast new file mode 100644 index 00000000000..4605f0165f1 --- /dev/null +++ b/test/lit/basic/complexTextNames.wast @@ -0,0 +1,49 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (export "$zoo (.bar)" (func $1)) + + ;; CHECK-TEXT: (func $foo\20\28.bar\29 (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (export "$zoo (.bar)" (func $1)) + + ;; CHECK-BIN: (func $foo\20\28.bar\29 (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo\20\28.bar\29) + + (func "$zoo (.bar)" (call $foo\20\28.bar\29)) +) +;; CHECK-TEXT: (func $1 (type $0) +;; CHECK-TEXT-NEXT: (call $foo\20\28.bar\29) +;; CHECK-TEXT-NEXT: ) + +;; CHECK-BIN: (func $1 (type $0) +;; CHECK-BIN-NEXT: (call $foo\20\28.bar\29) +;; CHECK-BIN-NEXT: ) + +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (export "$zoo (.bar)" (func $1)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/duplicate_types.wast b/test/lit/basic/duplicate_types.wast new file mode 100644 index 00000000000..244d97bc9fe --- /dev/null +++ b/test/lit/basic/duplicate_types.wast @@ -0,0 +1,55 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module ;; tests duplicate types are named properly + (type (func)) + (type (func)) + (type (func)) + (type (func (param i32))) + ;; CHECK-TEXT: (type $0 (func (param i32))) + ;; CHECK-BIN: (type $0 (func (param i32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32))) + (type $0 (func (param i32))) + (type (func (param i32))) + (type $b (func (param i32) (result f32))) + (type (func (param i32) (result f32))) + + ;; CHECK-TEXT: (type $1 (func (param i32) (result i32))) + + ;; CHECK-TEXT: (func $f0 (type $0) (param $0 i32) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $1 (func (param i32) (result i32))) + + ;; CHECK-BIN: (func $f0 (type $0) (param $0 i32) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $f0 (param i32)) + + ;; CHECK-TEXT: (func $f1 (type $1) (param $0 i32) (result i32) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f1 (type $1) (param $0 i32) (result i32) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + (func $f1 (param i32) (result i32) + (i32.const 0) + ) +) +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result i32))) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/empty_imported_table.wast b/test/lit/basic/empty_imported_table.wast new file mode 100644 index 00000000000..1a874dc0835 --- /dev/null +++ b/test/lit/basic/empty_imported_table.wast @@ -0,0 +1,21 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 0 0 funcref)) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 0 0 funcref)) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 0 0 funcref)) + (import "env" "table" (table 0 0 funcref)) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (memory $0 0) + (memory $0 0) +) diff --git a/test/lit/basic/empty_table.wast b/test/lit/basic/empty_table.wast new file mode 100644 index 00000000000..06e06edacf5 --- /dev/null +++ b/test/lit/basic/empty_table.wast @@ -0,0 +1,23 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (table 0 0 funcref) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (memory $0 0) + (memory $0 0) +) +;; CHECK-TEXT: (table $0 0 0 funcref) + +;; CHECK-BIN: (table $0 0 0 funcref) + +;; CHECK-BIN-NODEBUG: (table $0 0 0 funcref) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast new file mode 100644 index 00000000000..ed85338e820 --- /dev/null +++ b/test/lit/basic/exception-handling.wast @@ -0,0 +1,1737 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (type $1 (func (param i32))) + + ;; CHECK-TEXT: (type $2 (func (param i64))) + + ;; CHECK-TEXT: (type $3 (func (param i32 i64))) + + ;; CHECK-TEXT: (type $4 (func (param eqref))) + + ;; CHECK-TEXT: (type $5 (func (result exnref))) + + ;; CHECK-TEXT: (tag $e-i32 (param i32)) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (type $1 (func (param i32))) + + ;; CHECK-BIN: (type $2 (func (param i64))) + + ;; CHECK-BIN: (type $3 (func (param i32 i64))) + + ;; CHECK-BIN: (type $4 (func (param eqref))) + + ;; CHECK-BIN: (type $5 (func (result exnref))) + + ;; CHECK-BIN: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + ;; CHECK-TEXT: (tag $e-i64 (param i64)) + ;; CHECK-BIN: (tag $e-i64 (param i64)) + (tag $e-i64 (param i64)) + ;; CHECK-TEXT: (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-BIN: (tag $e-i32-i64 (param i32 i64)) + (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-TEXT: (tag $e-eqref (param eqref)) + ;; CHECK-BIN: (tag $e-eqref (param eqref)) + (tag $e-eqref (param (ref null eq))) + ;; CHECK-TEXT: (tag $e-empty) + ;; CHECK-BIN: (tag $e-empty) + (tag $e-empty) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo) + + ;; CHECK-TEXT: (func $bar (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $bar (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $bar) + + ;; --------------------------------------------------------------------------- + ;; Old Phase 3 exception handling + + ;; CHECK-TEXT: (func $eh-test (type $0) + ;; CHECK-TEXT-NEXT: (local $x (i32 i64)) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32-i64 + ;; CHECK-TEXT-NEXT: (local.set $x + ;; CHECK-TEXT-NEXT: (pop i32 i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (tuple.extract 2 0 + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $l11 + ;; CHECK-TEXT-NEXT: (try $l1 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br $l11) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $l11) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try2 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try3 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try4 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i64 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try5 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try6 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i64 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try7 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try8 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try9 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try10 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $eh-test (type $0) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 (i32 i64)) + ;; CHECK-BIN-NEXT: (local $3 i32) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32-i64 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32-i64 + ;; CHECK-BIN-NEXT: (local.set $2 + ;; CHECK-BIN-NEXT: (pop i32 i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $3 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$7 + ;; CHECK-BIN-NEXT: (try $label$10 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$13 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$16 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$19 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$22 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$25 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$34 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (try $label$29 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$33 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$37 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $eh-test (local $x (i32 i64)) + ;; Simple try-catch + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + ) + + ;; try-catch with multivalue tag + (try + (do + (throw $e-i32-i64 (i32.const 0) (i64.const 0)) + ) + (catch $e-i32-i64 + (local.set $x (pop i32 i64)) + (drop + (tuple.extract 2 0 + (local.get $x) + ) + ) + ) + ) + + ;; Try with a block label + (try $l1 + (do + (br $l1) + ) + (catch $e-i32 + (drop (pop i32)) + (br $l1) + ) + ) + + ;; Empty try body + (try + (do) + (catch $e-i32 + (drop (pop i32)) + ) + ) + + ;; Multiple instructions within try and catch bodies + (try + (do + (call $foo) + (call $bar) + ) + (catch $e-i32 + (drop (pop i32)) + (call $foo) + (call $bar) + ) + ) + + ;; Multiple catch clauses + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + ) + + ;; Single catch-all clause + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch_all) + ) + + ;; catch and catch-all clauses together + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + (catch_all + (call $foo) + (call $bar) + ) + ) + + ;; nested try-catch + (try + (do + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all) + ) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all) + ) + ) + ) + + ;; try without catch or delegate + (try + (do + (throw $e-i32 (i32.const 0)) + ) + ) + ) + + ;; CHECK-TEXT: (func $delegate-test (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try11 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $l015 + ;; CHECK-TEXT-NEXT: (try $l012 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try13 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l015 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l012) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try14 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l015 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l012) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l016 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try17 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l016) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try18 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-empty + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $delegate-test (type $0) + ;; CHECK-BIN-NEXT: (try $label$9 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$9) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$7 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$9) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$10 + ;; CHECK-BIN-NEXT: (try $label$19 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$11 + ;; CHECK-BIN-NEXT: (try $label$14 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br_if $label$10 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$19) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$17 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br_if $label$10 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$19) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$25 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$20 + ;; CHECK-BIN-NEXT: (try $label$23 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$25) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$28 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-empty + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $delegate-test + ;; Inner delegates target an outer catch + (try $l0 + (do + (try + (do + (call $foo) + ) + (delegate $l0) ;; by label + ) + (try + (do + (call $foo) + ) + (delegate 0) ;; by depth + ) + ) + (catch_all) + ) + + ;; When there are both a branch and a delegate that target the same try + ;; label. Because binaryen only allows blocks and loops to be targetted by + ;; branches, we wrap the try with a block and make branches that block + ;; instead, resulting in the br and delegate target different labels in the + ;; output. + (try $l0 + (do + (try + (do + (br_if $l0 (i32.const 1)) + ) + (delegate $l0) ;; by label + ) + (try + (do + (br_if $l0 (i32.const 1)) + ) + (delegate 0) ;; by depth + ) + ) + (catch_all) + ) + + ;; The inner delegate targets the outer delegate, which in turn targets the + ;; caller. + (try $l0 + (do + (try + (do + (call $foo) + ) + (delegate $l0) + ) + ) + (delegate 0) + ) + + ;; 'catch' body can be empty when the tag's type is none. + (try + (do) + (catch $e-empty) + ) + ) + + ;; CHECK-TEXT: (func $rethrow-test (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $l020 + ;; CHECK-TEXT-NEXT: (try $l019 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l019) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (br $l020) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l021 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l021) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (rethrow $l021) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l022 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try23 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $b0 + ;; CHECK-TEXT-NEXT: (rethrow $l022) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (block $b1 + ;; CHECK-TEXT-NEXT: (rethrow $l022) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l024 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try25 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l024) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l026 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try27 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l026) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $rethrow-test (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$4 + ;; CHECK-BIN-NEXT: (try $label$7 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (br $label$4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$13 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$12 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$13) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$13) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$20 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$19 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$18 + ;; CHECK-BIN-NEXT: (rethrow $label$20) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$20) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$26 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$25 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$26) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$32 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$31 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $rethrow-test + ;; Simple try-catch-rethrow + (try $l0 + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) ;; by label + ) + (catch_all + (rethrow 0) ;; by depth + ) + ) + + ;; When there are both a branch and a rethrow that target the same try + ;; label. Because binaryen only allows blocks and loops to be targetted by + ;; branches, we wrap the try with a block and make branches that block + ;; instead, resulting in the br and rethrow target different labels in the + ;; output. + (try $l0 + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) + ) + (catch_all + (br $l0) + ) + ) + + ;; One more level deep + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) ;; by label + ) + (catch_all + (rethrow 1) ;; by depth + ) + ) + ) + ) + + ;; Interleaving block + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (block $b0 + (rethrow $l0) ;; by label + ) + ) + (catch_all + (block $b1 + (rethrow 2) ;; by depth + ) + ) + ) + ) + ) + + ;; Within nested try, but rather in 'try' part and not 'catch' + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (rethrow $l0) ;; by label + ) + (catch_all) + ) + ) + ) + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (rethrow 1) ;; by depth + ) + (catch_all) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $pop-test (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (if (result i32) + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try28 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-eqref + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $pop-test (type $0) + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (if (result i32) + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$8 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-eqref + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $pop-test + (try + (do) + (catch $e-i32 + (throw $e-i32 + (if (result i32) + ;; pop is within an if condition, so this is OK. + (pop i32) + (i32.const 0) + (i32.const 3) + ) + ) + ) + ) + + (try + (do) + (catch $e-eqref + (drop + (pop anyref) ;; pop can be supertype + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $catchless-try-with-inner-delegate (type $0) + ;; CHECK-TEXT-NEXT: (try $label$0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $label$0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catchless-try-with-inner-delegate (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catchless-try-with-inner-delegate + (try $label$0 + (do + (try + (do + (throw $e-i32 + (i32.const 0) + ) + ) + (delegate $label$0) + ) + ) + ) + ) + + ;; When 'delegate' is next to a nested block, make sure its delegate argument + ;; is parsed correctly. + + ;; CHECK-TEXT: (func $nested-block-and-try (type $0) + ;; CHECK-TEXT-NEXT: (block $l0 + ;; CHECK-TEXT-NEXT: (block $l1 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-block-and-try (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $nested-block-and-try + (block $l0 + (block $l1) + (try + (do) + (delegate 1) ;; to caller + ) + ) + (nop) + ) + + ;; --------------------------------------------------------------------------- + ;; New exception handling + + ;; CHECK-TEXT: (func $exnref-test (type $5) (result exnref) + ;; CHECK-TEXT-NEXT: (local $exn exnref) + ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) + ;; CHECK-TEXT-NEXT: (if (result exnref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (if (result nullexnref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (local.get $null-exn) + ;; CHECK-TEXT-NEXT: (ref.null noexn) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $exn) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $exnref-test (type $5) (result exnref) + ;; CHECK-BIN-NEXT: (local $exn exnref) + ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) + ;; CHECK-BIN-NEXT: (if (result exnref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (if (result nullexnref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (local.get $null-exn) + ;; CHECK-BIN-NEXT: (ref.null noexn) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $exn) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $exnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref) + (if (result exnref) + (i32.const 1) + (if (result nullexnref) + (i32.const 1) + (local.get $null-exn) + (ref.null noexn) + ) + (local.get $exn) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) + +;; CHECK-BIN-NODEBUG: (type $2 (func (param i64))) + +;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 i64))) + +;; CHECK-BIN-NODEBUG: (type $4 (func (param eqref))) + +;; CHECK-BIN-NODEBUG: (type $5 (func (result exnref))) + +;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + +;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i64)) + +;; CHECK-BIN-NODEBUG: (tag $tag$2 (param i32 i64)) + +;; CHECK-BIN-NODEBUG: (tag $tag$3 (param eqref)) + +;; CHECK-BIN-NODEBUG: (tag $tag$4) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64)) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 i32) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$2 +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (pop i32 i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br $label$7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$13 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$16 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$22 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$34 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (try $label$29 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$33 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$37 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$11 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$14 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$19) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$17 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$19) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$20 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$23 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$25) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$28 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$4 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (br $label$4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$13 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$12 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$13) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$13) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$20 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$18 +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$20) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$20) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$26 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$26) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$32 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$31 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (if (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$3 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop eqref) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $5) (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 exnref) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) +;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (if (result nullexnref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null noexn) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/export-import.wast b/test/lit/basic/export-import.wast new file mode 100644 index 00000000000..853e1d93a7b --- /dev/null +++ b/test/lit/basic/export-import.wast @@ -0,0 +1,34 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $v (func)) + ;; CHECK-BIN: (type $v (func)) + (type $v (func)) + ;; CHECK-TEXT: (import "env" "test2" (global $test2 i32)) + ;; CHECK-BIN: (import "env" "test2" (global $test2 i32)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + + ;; CHECK-BIN-NODEBUG: (import "env" "test2" (global $gimport$0 i32)) + (import "env" "test1" (func $test1)) + ;; CHECK-TEXT: (import "env" "test1" (func $test1 (type $v))) + ;; CHECK-BIN: (import "env" "test1" (func $test1 (type $v))) + ;; CHECK-BIN-NODEBUG: (import "env" "test1" (func $fimport$0 (type $0))) + (import "env" "test2" (global $test2 i32)) + ;; CHECK-TEXT: (export "test1" (func $test1)) + ;; CHECK-BIN: (export "test1" (func $test1)) + ;; CHECK-BIN-NODEBUG: (export "test1" (func $fimport$0)) + (export "test1" (func $test1)) + ;; CHECK-TEXT: (export "test2" (global $test2)) + ;; CHECK-BIN: (export "test2" (global $test2)) + ;; CHECK-BIN-NODEBUG: (export "test2" (global $gimport$0)) + (export "test2" (global $test2)) +) diff --git a/test/lit/basic/extended-names.wast b/test/lit/basic/extended-names.wast new file mode 100644 index 00000000000..b6c4d52ae2b --- /dev/null +++ b/test/lit/basic/extended-names.wast @@ -0,0 +1,38 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module $foo + ;; CHECK-TEXT: (memory $m1 1 1) + + ;; CHECK-TEXT: (data $mydata (i32.const 0) "a") + + ;; CHECK-TEXT: (data $passive_data "b") + + ;; CHECK-TEXT: (table $t1 1 funcref) + ;; CHECK-BIN: (memory $m1 1 1) + + ;; CHECK-BIN: (data $mydata (i32.const 0) "a") + + ;; CHECK-BIN: (data $passive_data "b") + + ;; CHECK-BIN: (table $t1 1 funcref) + (table $t1 1 funcref) + (memory $m1 1 1) + (data $mydata (i32.const 0) "a") + (data $passive_data "b") +) +;; CHECK-BIN-NODEBUG: (memory $0 1 1) + +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 0) "a") + +;; CHECK-BIN-NODEBUG: (data $1 "b") + +;; CHECK-BIN-NODEBUG: (table $0 1 funcref) diff --git a/test/lit/basic/fn_prolog_epilog.debugInfo.wast b/test/lit/basic/fn_prolog_epilog.debugInfo.wast new file mode 100644 index 00000000000..636c3346e9b --- /dev/null +++ b/test/lit/basic/fn_prolog_epilog.debugInfo.wast @@ -0,0 +1,66 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;;@ src.cpp:1:1 + (func + (nop) + ;;@ src.cpp:2:1 + (block $l0 + ;;@ src.cpp:2:2 + (block $l1 + (br $l1) + ) + ) + ;;@ src.cpp:3:1 + (return) + ;;@ src.cpp:3:2 + ) +) +;; CHECK-TEXT: (type $0 (func)) + +;; CHECK-TEXT: (func $0 (type $0) +;; CHECK-TEXT-NEXT: (nop) +;; CHECK-TEXT-NEXT: ;;@ src.cpp:2:1 +;; CHECK-TEXT-NEXT: (block $l0 +;; CHECK-TEXT-NEXT: ;;@ src.cpp:2:2 +;; CHECK-TEXT-NEXT: (block $l1 +;; CHECK-TEXT-NEXT: (br $l1) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: ;;@ src.cpp:3:1 +;; CHECK-TEXT-NEXT: (return) +;; CHECK-TEXT-NEXT: ;;@ src.cpp:3:2 +;; CHECK-TEXT-NEXT: ) + +;; CHECK-BIN: (type $0 (func)) + +;; CHECK-BIN: (func $0 (type $0) +;; CHECK-BIN-NEXT: (nop) +;; CHECK-BIN-NEXT: (block $label$1 +;; CHECK-BIN-NEXT: (block $label$2 +;; CHECK-BIN-NEXT: (br $label$2) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: (return) +;; CHECK-BIN-NEXT: ) + +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (br $label$2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/grow_memory.wast b/test/lit/basic/grow_memory.wast new file mode 100644 index 00000000000..2a8c45ece93 --- /dev/null +++ b/test/lit/basic/grow_memory.wast @@ -0,0 +1,71 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (param i32) (result i32))) + ;; CHECK-BIN: (type $0 (func (param i32) (result i32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32) (result i32))) + (type $0 (func (param i32) (result i32))) + ;; CHECK-TEXT: (type $1 (func (result i32))) + ;; CHECK-BIN: (type $1 (func (result i32))) + ;; CHECK-BIN-NODEBUG: (type $1 (func (result i32))) + (type $1 (func (result i32))) + ;; CHECK-TEXT: (memory $0 1) + ;; CHECK-BIN: (memory $0 1) + ;; CHECK-BIN-NODEBUG: (memory $0 1) + (memory $0 1) + ;; CHECK-TEXT: (export "memory" (memory $0)) + ;; CHECK-BIN: (export "memory" (memory $0)) + ;; CHECK-BIN-NODEBUG: (export "memory" (memory $0)) + (export "memory" (memory $0)) + ;; CHECK-TEXT: (export "grow" (func $0)) + ;; CHECK-BIN: (export "grow" (func $0)) + ;; CHECK-BIN-NODEBUG: (export "grow" (func $0)) + (export "grow" (func $0)) + ;; CHECK-TEXT: (export "current" (func $1)) + ;; CHECK-BIN: (export "current" (func $1)) + ;; CHECK-BIN-NODEBUG: (export "current" (func $1)) + (export "current" (func $1)) + + ;; CHECK-TEXT: (func $0 (type $0) (param $var$0 i32) (result i32) + ;; CHECK-TEXT-NEXT: (memory.grow + ;; CHECK-TEXT-NEXT: (local.get $var$0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $0 (type $0) (param $var$0 i32) (result i32) + ;; CHECK-BIN-NEXT: (memory.grow + ;; CHECK-BIN-NEXT: (local.get $var$0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (result i32) + ;; CHECK-BIN-NODEBUG-NEXT: (memory.grow + ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) + ;; CHECK-BIN-NODEBUG-NEXT: ) + ;; CHECK-BIN-NODEBUG-NEXT: ) + (func $0 (; 0 ;) (type $0) (param $var$0 i32) (result i32) + (memory.grow + (local.get $var$0) + ) + ) + + ;; CHECK-TEXT: (func $1 (type $1) (result i32) + ;; CHECK-TEXT-NEXT: (memory.size) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $1 (type $1) (result i32) + ;; CHECK-BIN-NEXT: (memory.size) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NODEBUG: (func $1 (type $1) (result i32) + ;; CHECK-BIN-NODEBUG-NEXT: (memory.size) + ;; CHECK-BIN-NODEBUG-NEXT: ) + (func $1 (; 1 ;) (type $1) (result i32) + (memory.size) + ) +) diff --git a/test/lit/basic/hello_world.wat b/test/lit/basic/hello_world.wat new file mode 100644 index 00000000000..5ddb3012845 --- /dev/null +++ b/test/lit/basic/hello_world.wat @@ -0,0 +1,50 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wat -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wat +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wat +;; RUN: cat %t.text.wat | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wat | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wat | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + ;; CHECK-BIN: (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + ;; CHECK-TEXT: (memory $0 256 256) + ;; CHECK-BIN: (memory $0 256 256) + ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32 i32) (result i32))) + + ;; CHECK-BIN-NODEBUG: (memory $0 256 256) + (memory $0 256 256) + ;; CHECK-TEXT: (export "add" (func $add)) + ;; CHECK-BIN: (export "add" (func $add)) + ;; CHECK-BIN-NODEBUG: (export "add" (func $0)) + (export "add" (func $add)) + ;; CHECK-TEXT: (func $add (type $i32_i32_=>_i32) (param $x i32) (param $y i32) (result i32) + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (local.get $y) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $add (type $i32_i32_=>_i32) (param $x i32) (param $y i32) (result i32) + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (local.get $y) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $add (param $x i32) (param $y i32) (result i32) + (i32.add + (local.get $x) + (local.get $y) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (param $1 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/imported_memory.wast b/test/lit/basic/imported_memory.wast new file mode 100644 index 00000000000..52eccce7f07 --- /dev/null +++ b/test/lit/basic/imported_memory.wast @@ -0,0 +1,21 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (import "env" "memory" (memory $0 256 256)) + ;; CHECK-BIN: (import "env" "memory" (memory $0 256 256)) + ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256 256)) + (import "env" "memory" (memory $0 256 256)) + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 256 funcref)) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 256 256 funcref)) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 256 funcref)) + (import "env" "table" (table 256 256 funcref)) +) diff --git a/test/lit/basic/imported_memory_growth.wast b/test/lit/basic/imported_memory_growth.wast new file mode 100644 index 00000000000..d1d62c2d985 --- /dev/null +++ b/test/lit/basic/imported_memory_growth.wast @@ -0,0 +1,21 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (import "env" "memory" (memory $0 256)) + ;; CHECK-BIN: (import "env" "memory" (memory $0 256)) + ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256)) + (import "env" "memory" (memory $0 256)) + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 funcref)) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 256 funcref)) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 funcref)) + (import "env" "table" (table 256 funcref)) +) diff --git a/test/lit/basic/kitchen_sink.wast b/test/lit/basic/kitchen_sink.wast new file mode 100644 index 00000000000..ca20996e71b --- /dev/null +++ b/test/lit/basic/kitchen_sink.wast @@ -0,0 +1,2833 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result i32))) + ;; CHECK-BIN: (type $0 (func (result i32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + (type $0 (func (result i32))) + ;; CHECK-TEXT: (memory $0 4096 4096) + ;; CHECK-BIN: (memory $0 4096 4096) + ;; CHECK-BIN-NODEBUG: (memory $0 4096 4096) + (memory $0 4096 4096) + (data (i32.const 1026) "\14\00") + + ;; CHECK-TEXT: (data $0 (i32.const 1026) "\14\00") + + ;; CHECK-TEXT: (func $kitchensink (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (block $block0 (result i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.mul + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.div_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.div_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.rem_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.rem_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.and + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.or + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.xor + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.shl + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.shr_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.shr_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.eq + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.ne + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.lt_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.le_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.lt_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.le_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.gt_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.ge_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.gt_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.ge_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.clz + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.ctz + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.popcnt + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.add + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.sub + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.mul + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.div_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.div_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.rem_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.rem_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.and + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.or + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.xor + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.shl + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.shr_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.shr_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eq + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.ne + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.lt_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.le_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.lt_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.le_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.gt_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.ge_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.gt_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.ge_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.clz + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.ctz + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.popcnt + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.add + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.sub + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.mul + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.div + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.min + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.max + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.abs + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.neg + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.copysign + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.ceil + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.floor + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.trunc + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.nearest + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.sqrt + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.eq + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.ne + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.lt + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.le + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.gt + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.ge + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.add + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.sub + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.mul + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.div + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.min + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.max + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.neg + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.copysign + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.ceil + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.floor + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.trunc + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.nearest + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.sqrt + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.eq + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.ne + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.lt + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.le + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.gt + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.ge + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_f32_s + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_f64_s + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_f32_u + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_f64_u + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_sat_f32_s + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_sat_f32_u + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_sat_f64_s + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.trunc_sat_f64_u + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.wrap_i64 + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_f32_s + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_f64_s + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_f32_u + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_f64_u + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_sat_f32_s + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_sat_f32_u + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_sat_f64_s + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.trunc_sat_f64_u + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.extend_i32_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.extend_i32_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.convert_i32_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.convert_i32_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.convert_i64_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.convert_i64_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.demote_f64 + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.reinterpret_i32 + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.convert_i32_s + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.convert_i32_u + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.convert_i64_s + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.convert_i64_u + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.promote_f32 + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.reinterpret_i64 + ;; CHECK-TEXT-NEXT: (i64.const 100) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.reinterpret_f32 + ;; CHECK-TEXT-NEXT: (f32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.reinterpret_f64 + ;; CHECK-TEXT-NEXT: (f64.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (data $0 (i32.const 1026) "\14\00") + + ;; CHECK-BIN: (func $kitchensink (type $0) (result i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.mul + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.div_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.div_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.rem_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.rem_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.and + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.or + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.xor + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.shl + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.shr_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.shr_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.eq + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.ne + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.lt_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.le_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.lt_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.le_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.gt_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.ge_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.gt_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.ge_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.clz + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.ctz + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.popcnt + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.add + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.sub + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.mul + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.div_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.div_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.rem_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.rem_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.and + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.or + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.xor + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.shl + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.shr_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.shr_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.eq + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.ne + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.lt_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.le_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.lt_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.le_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.gt_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.ge_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.gt_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.ge_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.clz + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.ctz + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.popcnt + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.add + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.sub + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.mul + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.div + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.min + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.max + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.abs + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.neg + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.copysign + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.ceil + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.floor + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.trunc + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.nearest + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.sqrt + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.eq + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.ne + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.lt + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.le + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.gt + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.ge + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.add + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.sub + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.mul + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.div + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.min + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.max + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.abs + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.neg + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.copysign + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.ceil + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.floor + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.trunc + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.nearest + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.sqrt + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.eq + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.ne + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.lt + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.le + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.gt + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.ge + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_f32_s + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_f64_s + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_f32_u + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_f64_u + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_sat_f32_s + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_sat_f32_u + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_sat_f64_s + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.trunc_sat_f64_u + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.wrap_i64 + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_f32_s + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_f64_s + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_f32_u + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_f64_u + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_sat_f32_s + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_sat_f32_u + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_sat_f64_s + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.trunc_sat_f64_u + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.extend_i32_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.extend_i32_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.convert_i32_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.convert_i32_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.convert_i64_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.convert_i64_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.demote_f64 + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.reinterpret_i32 + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.convert_i32_s + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.convert_i32_u + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.convert_i64_s + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.convert_i64_u + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.promote_f32 + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.reinterpret_i64 + ;; CHECK-BIN-NEXT: (i64.const 100) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.reinterpret_f32 + ;; CHECK-BIN-NEXT: (f32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.reinterpret_f64 + ;; CHECK-BIN-NEXT: (f64.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + (func $kitchensink (type $0) (result i32) + (block $block0 (result i32) + (drop + (i32.add + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.sub + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.mul + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.div_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.div_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.rem_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.rem_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.and + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.or + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.xor + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.shl + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.shr_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.shr_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.eq + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.ne + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.lt_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.le_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.lt_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.le_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.gt_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.ge_s + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.gt_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.ge_u + (i32.const 10) + (i32.const 10) + ) + ) + (drop + (i32.clz + (i32.const 10) + ) + ) + (drop + (i32.ctz + (i32.const 10) + ) + ) + (drop + (i32.popcnt + (i32.const 10) + ) + ) + (drop + (i64.add + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.sub + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.mul + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.div_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.div_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.rem_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.rem_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.and + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.or + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.xor + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.shl + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.shr_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.shr_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.eq + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.ne + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.lt_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.le_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.lt_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.le_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.gt_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.ge_s + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.gt_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.ge_u + (i64.const 100) + (i64.const 100) + ) + ) + (drop + (i64.clz + (i64.const 100) + ) + ) + (drop + (i64.ctz + (i64.const 100) + ) + ) + (drop + (i64.popcnt + (i64.const 100) + ) + ) + (drop + (f32.add + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.sub + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.mul + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.div + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.min + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.max + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.abs + (f32.const 10) + ) + ) + (drop + (f32.neg + (f32.const 10) + ) + ) + (drop + (f32.copysign + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.ceil + (f32.const 10) + ) + ) + (drop + (f32.floor + (f32.const 10) + ) + ) + (drop + (f32.trunc + (f32.const 10) + ) + ) + (drop + (f32.nearest + (f32.const 10) + ) + ) + (drop + (f32.sqrt + (f32.const 10) + ) + ) + (drop + (f32.eq + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.ne + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.lt + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.le + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.gt + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f32.ge + (f32.const 10) + (f32.const 10) + ) + ) + (drop + (f64.add + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.sub + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.mul + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.div + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.min + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.max + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.abs + (f64.const 10) + ) + ) + (drop + (f64.neg + (f64.const 10) + ) + ) + (drop + (f64.copysign + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.ceil + (f64.const 10) + ) + ) + (drop + (f64.floor + (f64.const 10) + ) + ) + (drop + (f64.trunc + (f64.const 10) + ) + ) + (drop + (f64.nearest + (f64.const 10) + ) + ) + (drop + (f64.sqrt + (f64.const 10) + ) + ) + (drop + (f64.eq + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.ne + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.lt + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.le + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.gt + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (f64.ge + (f64.const 10) + (f64.const 10) + ) + ) + (drop + (i32.trunc_f32_s + (f32.const 10) + ) + ) + (drop + (i32.trunc_f64_s + (f64.const 10) + ) + ) + (drop + (i32.trunc_f32_u + (f32.const 10) + ) + ) + (drop + (i32.trunc_f64_u + (f64.const 10) + ) + ) + (drop + (i32.trunc_sat_f32_s + (f32.const 10) + ) + ) + (drop + (i32.trunc_sat_f32_u + (f32.const 10) + ) + ) + (drop + (i32.trunc_sat_f64_s + (f64.const 10) + ) + ) + (drop + (i32.trunc_sat_f64_u + (f64.const 10) + ) + ) + (drop + (i32.wrap_i64 + (i64.const 100) + ) + ) + (drop + (i64.trunc_f32_s + (f32.const 10) + ) + ) + (drop + (i64.trunc_f64_s + (f64.const 10) + ) + ) + (drop + (i64.trunc_f32_u + (f32.const 10) + ) + ) + (drop + (i64.trunc_f64_u + (f64.const 10) + ) + ) + (drop + (i64.trunc_sat_f32_s + (f32.const 10) + ) + ) + (drop + (i64.trunc_sat_f32_u + (f32.const 10) + ) + ) + (drop + (i64.trunc_sat_f64_s + (f64.const 10) + ) + ) + (drop + (i64.trunc_sat_f64_u + (f64.const 10) + ) + ) + (drop + (i64.extend_i32_s + (i32.const 10) + ) + ) + (drop + (i64.extend_i32_u + (i32.const 10) + ) + ) + (drop + (f32.convert_i32_s + (i32.const 10) + ) + ) + (drop + (f32.convert_i32_u + (i32.const 10) + ) + ) + (drop + (f32.convert_i64_s + (i64.const 100) + ) + ) + (drop + (f32.convert_i64_u + (i64.const 100) + ) + ) + (drop + (f32.demote_f64 + (f64.const 10) + ) + ) + (drop + (f32.reinterpret_i32 + (i32.const 10) + ) + ) + (drop + (f64.convert_i32_s + (i32.const 10) + ) + ) + (drop + (f64.convert_i32_u + (i32.const 10) + ) + ) + (drop + (f64.convert_i64_s + (i64.const 100) + ) + ) + (drop + (f64.convert_i64_u + (i64.const 100) + ) + ) + (drop + (f64.promote_f32 + (f32.const 10) + ) + ) + (drop + (f64.reinterpret_i64 + (i64.const 100) + ) + ) + (drop + (i32.reinterpret_f32 + (f32.const 10) + ) + ) + (drop + (i64.reinterpret_f64 + (f64.const 10) + ) + ) + (i32.const 0) + ) + ) +) +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 1026) "\14\00") + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.mul +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.div_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.div_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.rem_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.rem_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.and +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.or +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.xor +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.shl +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.eq +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.ne +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.le_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.lt_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.le_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.ge_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.clz +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.ctz +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.popcnt +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.add +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.sub +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.mul +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.div_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.div_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.rem_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.rem_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.and +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.or +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.xor +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.shl +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.eq +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.ne +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.le_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.lt_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.le_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.ge_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.clz +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.ctz +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.popcnt +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.add +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.sub +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.mul +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.div +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.min +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.max +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.abs +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.neg +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.copysign +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.ceil +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.floor +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.trunc +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.nearest +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.sqrt +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.eq +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.ne +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.lt +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.le +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.gt +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.ge +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.add +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.sub +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.mul +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.div +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.min +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.max +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.abs +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.neg +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.copysign +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.ceil +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.floor +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.trunc +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.nearest +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.sqrt +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.eq +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.ne +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.lt +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.le +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.gt +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.ge +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_f32_s +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_f64_s +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_f32_u +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_f64_u +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_sat_f32_s +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_sat_f32_u +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_sat_f64_s +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.trunc_sat_f64_u +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.wrap_i64 +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_f32_s +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_f64_s +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_f32_u +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_f64_u +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_sat_f32_s +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_sat_f32_u +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_sat_f64_s +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.trunc_sat_f64_u +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.extend_i32_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.extend_i32_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.convert_i32_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.convert_i32_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.convert_i64_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.convert_i64_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.demote_f64 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.reinterpret_i32 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i32_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i32_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i64_s +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i64_u +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.promote_f32 +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.reinterpret_i64 +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 100) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.reinterpret_f32 +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.reinterpret_f64 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/memory-import.wast b/test/lit/basic/memory-import.wast new file mode 100644 index 00000000000..fb6a3d62317 --- /dev/null +++ b/test/lit/basic/memory-import.wast @@ -0,0 +1,42 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result i32))) + ;; CHECK-BIN: (type $0 (func (result i32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + (type $0 (func (result i32))) + ;; CHECK-TEXT: (import "env" "memory" (memory $0 1 1)) + ;; CHECK-BIN: (import "env" "memory" (memory $0 1 1)) + ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) + (import "env" "memory" (memory $0 1 1)) + + ;; CHECK-TEXT: (func $foo (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (i32.load offset=13 + ;; CHECK-TEXT-NEXT: (i32.const 37) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) (result i32) + ;; CHECK-BIN-NEXT: (i32.load offset=13 + ;; CHECK-BIN-NEXT: (i32.const 37) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $foo (type $0) (result i32) + (i32.load offset=13 + (i32.const 37) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.load offset=13 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 37) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/memory-import64.wast b/test/lit/basic/memory-import64.wast new file mode 100644 index 00000000000..7794d6b5fd5 --- /dev/null +++ b/test/lit/basic/memory-import64.wast @@ -0,0 +1,42 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result i32))) + ;; CHECK-BIN: (type $0 (func (result i32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + (type $0 (func (result i32))) + ;; CHECK-TEXT: (import "env" "memory" (memory $0 i64 1 1)) + ;; CHECK-BIN: (import "env" "memory" (memory $0 i64 1 1)) + ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 i64 1 1)) + (import "env" "memory" (memory $0 i64 1 1)) + + ;; CHECK-TEXT: (func $foo (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (i32.load offset=13 + ;; CHECK-TEXT-NEXT: (i64.const 37) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) (result i32) + ;; CHECK-BIN-NEXT: (i32.load offset=13 + ;; CHECK-BIN-NEXT: (i64.const 37) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $foo (type $0) (result i32) + (i32.load offset=13 + (i64.const 37) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.load offset=13 +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 37) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/memory-shared.wast b/test/lit/basic/memory-shared.wast new file mode 100644 index 00000000000..bc2f8baccf7 --- /dev/null +++ b/test/lit/basic/memory-shared.wast @@ -0,0 +1,17 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (memory $0 (shared 23 256)) + ;; CHECK-BIN: (memory $0 (shared 23 256)) + ;; CHECK-BIN-NODEBUG: (memory $0 (shared 23 256)) + (memory $0 (shared 23 256)) +) diff --git a/test/lit/basic/min.wast b/test/lit/basic/min.wast new file mode 100644 index 00000000000..74898f59fe5 --- /dev/null +++ b/test/lit/basic/min.wast @@ -0,0 +1,234 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (param f32) (result f32))) + ;; CHECK-BIN: (type $0 (func (param f32) (result f32))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (param f32) (result f32))) + (type $0 (func (param f32) (result f32))) + ;; CHECK-TEXT: (type $1 (func (param i32 i32) (result f32))) + ;; CHECK-BIN: (type $1 (func (param i32 i32) (result f32))) + ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 i32) (result f32))) + (type $1 (func (param i32 i32) (result f32))) + ;; CHECK-TEXT: (type $2 (func (param i32) (result i32))) + ;; CHECK-BIN: (type $2 (func (param i32) (result i32))) + ;; CHECK-BIN-NODEBUG: (type $2 (func (param i32) (result i32))) + (type $2 (func (param i32) (result i32))) + ;; CHECK-TEXT: (type $3 (func (param i32 i32 i32) (result i32))) + ;; CHECK-BIN: (type $3 (func (param i32 i32 i32) (result i32))) + ;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 i32 i32) (result i32))) + (type $3 (func (param i32 i32 i32) (result i32))) + ;; CHECK-TEXT: (memory $0 256 256) + ;; CHECK-BIN: (memory $0 256 256) + ;; CHECK-BIN-NODEBUG: (memory $0 256 256) + (memory $0 256 256) + ;; CHECK-TEXT: (export "floats" (func $floats)) + ;; CHECK-BIN: (export "floats" (func $floats)) + ;; CHECK-BIN-NODEBUG: (export "floats" (func $0)) + (export "floats" (func $floats)) + + ;; CHECK-TEXT: (func $floats (type $0) (param $f f32) (result f32) + ;; CHECK-TEXT-NEXT: (local $t f32) + ;; CHECK-TEXT-NEXT: (f32.add + ;; CHECK-TEXT-NEXT: (local.get $t) + ;; CHECK-TEXT-NEXT: (local.get $f) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $floats (type $0) (param $f f32) (result f32) + ;; CHECK-BIN-NEXT: (local $t f32) + ;; CHECK-BIN-NEXT: (f32.add + ;; CHECK-BIN-NEXT: (local.get $t) + ;; CHECK-BIN-NEXT: (local.get $f) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $floats (type $0) (param $f f32) (result f32) + (local $t f32) + (f32.add + (local.get $t) + (local.get $f) + ) + ) + + ;; CHECK-TEXT: (func $neg (type $1) (param $k i32) (param $p i32) (result f32) + ;; CHECK-TEXT-NEXT: (local $n f32) + ;; CHECK-TEXT-NEXT: (local.tee $n + ;; CHECK-TEXT-NEXT: (f32.neg + ;; CHECK-TEXT-NEXT: (block $block0 (result f32) + ;; CHECK-TEXT-NEXT: (i32.store + ;; CHECK-TEXT-NEXT: (local.get $k) + ;; CHECK-TEXT-NEXT: (local.get $p) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f32.load + ;; CHECK-TEXT-NEXT: (local.get $k) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $neg (type $1) (param $k i32) (param $p i32) (result f32) + ;; CHECK-BIN-NEXT: (local $n f32) + ;; CHECK-BIN-NEXT: (local.tee $n + ;; CHECK-BIN-NEXT: (f32.neg + ;; CHECK-BIN-NEXT: (block $label$1 (result f32) + ;; CHECK-BIN-NEXT: (i32.store + ;; CHECK-BIN-NEXT: (local.get $k) + ;; CHECK-BIN-NEXT: (local.get $p) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f32.load + ;; CHECK-BIN-NEXT: (local.get $k) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $neg (type $1) (param $k i32) (param $p i32) (result f32) + (local $n f32) + (local.tee $n + (f32.neg + (block $block0 (result f32) + (i32.store + (local.get $k) + (local.get $p) + ) + (f32.load + (local.get $k) + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $littleswitch (type $2) (param $x i32) (result i32) + ;; CHECK-TEXT-NEXT: (block $topmost (result i32) + ;; CHECK-TEXT-NEXT: (block $switch-case$2 + ;; CHECK-TEXT-NEXT: (block $switch-case$1 + ;; CHECK-TEXT-NEXT: (br_table $switch-case$1 $switch-case$2 $switch-case$1 + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $littleswitch (type $2) (param $x i32) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (block $label$3 + ;; CHECK-BIN-NEXT: (br_table $label$3 $label$2 $label$3 + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $littleswitch (type $2) (param $x i32) (result i32) + (block $topmost (result i32) + (block $switch-case$2 + (block $switch-case$1 + (br_table $switch-case$1 $switch-case$2 $switch-case$1 + (i32.sub + (local.get $x) + (i32.const 1) + ) + ) + ) + (br $topmost + (i32.const 1) + ) + ) + (br $topmost + (i32.const 2) + ) + (i32.const 0) + ) + ) + + ;; CHECK-TEXT: (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + ;; CHECK-TEXT-NEXT: (block $topmost (result i32) + ;; CHECK-TEXT-NEXT: (local.get $i3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + ;; CHECK-BIN-NEXT: (local.get $i3) + ;; CHECK-BIN-NEXT: ) + (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + (block $topmost (result i32) + (local.get $i3) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 f32) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 f32) +;; CHECK-BIN-NODEBUG-NEXT: (f32.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i32) (param $1 i32) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 f32) +;; CHECK-BIN-NODEBUG-NEXT: (local.tee $2 +;; CHECK-BIN-NODEBUG-NEXT: (f32.neg +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f32.load +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $2) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$3 $label$2 $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $3) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/multi-memories-atomics64.wast b/test/lit/basic/multi-memories-atomics64.wast new file mode 100644 index 00000000000..79afddb3b9b --- /dev/null +++ b/test/lit/basic/multi-memories-atomics64.wast @@ -0,0 +1,1421 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (memory $appMemory (shared i64 23 256)) + ;; CHECK-BIN: (memory $appMemory (shared i64 23 256)) + (memory $appMemory (shared i64 23 256)) + ;; CHECK-TEXT: (memory $dataMemory (shared i64 23 256)) + ;; CHECK-BIN: (memory $dataMemory (shared i64 23 256)) + (memory $dataMemory (shared i64 23 256)) + ;; CHECK-TEXT: (memory $instrumentMemory (shared i64 23 256)) + ;; CHECK-BIN: (memory $instrumentMemory (shared i64 23 256)) + (memory $instrumentMemory (shared i64 23 256)) + + ;; CHECK-TEXT: (func $atomic-loadstore (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load8_u $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load8_u $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load16_u $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load16_u $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.load $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load8_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load8_u $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load16_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load16_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load32_u $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load32_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.load $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store8 $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store8 $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store16 $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.store16 $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store8 $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store8 $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store16 $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store16 $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store32 $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i64.atomic.store32 $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-loadstore (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load8_u $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load8_u $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load16_u $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load16_u $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.load $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load8_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load8_u $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load16_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load16_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load32_u $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load32_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.load $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store8 $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store8 $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store16 $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.atomic.store16 $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store8 $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store8 $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store16 $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store16 $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store32 $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i64.atomic.store32 $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-loadstore + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.load8_u $appMemory offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load8_u $appMemory offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load16_u $dataMemory offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load16_u $instrumentMemory offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load $dataMemory offset=4 + (local.get $0) + ) + ) + (drop + (i32.atomic.load $appMemory offset=4 + (local.get $0) + ) + ) + (drop + (i64.atomic.load8_u $appMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load8_u $dataMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load16_u $appMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load16_u $appMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load32_u $instrumentMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load32_u $appMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load $appMemory + (local.get $0) + ) + ) + (drop + (i64.atomic.load $instrumentMemory + (local.get $0) + ) + ) + (i32.atomic.store $appMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store $appMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store8 $instrumentMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store8 $dataMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store16 $appMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i32.atomic.store16 $dataMemory offset=4 + (local.get $0) + (local.get $2) + ) + (i64.atomic.store $appMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store $appMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store8 $dataMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store8 $instrumentMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store16 $appMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store16 $appMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store32 $instrumentMemory offset=4 + (local.get $0) + (local.get $1) + ) + (i64.atomic.store32 $dataMemory offset=4 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $atomic-rmw (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.add $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.add $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw16.and_u $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw16.and_u $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.or_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.or_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.xchg_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.xchg_u $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-rmw (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.add $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.add $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw16.and_u $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw16.and_u $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.or_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.or_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.xchg_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.xchg_u $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-rmw + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.rmw.add $dataMemory offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw.add $instrumentMemory offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.add_u $appMemory offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.add_u $appMemory offset=4 + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw16.and_u $dataMemory + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw16.and_u $instrumentMemory + (local.get $0) + (local.get $2) + ) + ) + (drop + (i64.atomic.rmw32.or_u $appMemory + (local.get $0) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw32.or_u $appMemory + (local.get $0) + (local.get $1) + ) + ) + (drop + (i32.atomic.rmw8.xchg_u $appMemory + (local.get $0) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.xchg_u $dataMemory + (local.get $0) + (local.get $2) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-cmpxchg (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw.cmpxchg $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw.cmpxchg $dataMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.cmpxchg_u $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.atomic.rmw32.cmpxchg_u $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-cmpxchg (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.cmpxchg $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw.cmpxchg $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw.cmpxchg $dataMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.cmpxchg_u $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.atomic.rmw32.cmpxchg_u $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-cmpxchg + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (i32.atomic.rmw.cmpxchg $appMemory offset=4 + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.cmpxchg_u $appMemory + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i32.atomic.rmw8.cmpxchg_u $appMemory + (local.get $0) + (local.get $2) + (local.get $2) + ) + ) + (drop + (i64.atomic.rmw.cmpxchg $appMemory offset=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw.cmpxchg $dataMemory offset=4 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw32.cmpxchg_u $instrumentMemory + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (i64.atomic.rmw32.cmpxchg_u $dataMemory + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-wait-notify (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i64) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (local $2 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 $appMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait32 $instrumentMemory offset=4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify $dataMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify $appMemory offset=24 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.notify $dataMemory offset=24 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 $instrumentMemory + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 $appMemory offset=16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 $appMemory offset=16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-wait-notify (type $0) + ;; CHECK-BIN-NEXT: (local $0 i64) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 $appMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait32 $instrumentMemory offset=4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify $dataMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify $appMemory offset=24 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.notify $dataMemory offset=24 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 $instrumentMemory + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 $appMemory offset=16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (memory.atomic.wait64 $appMemory offset=16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $atomic-wait-notify + (local $0 i64) + (local $1 i64) + (local $2 i32) + (drop + (memory.atomic.wait32 $dataMemory + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait32 $instrumentMemory + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait32 $appMemory offset=4 + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait32 $instrumentMemory offset=4 + (local.get $0) + (local.get $2) + (local.get $1) + ) + ) + (drop + (memory.atomic.notify $dataMemory + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.notify $dataMemory + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.notify $appMemory offset=24 + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.notify $dataMemory offset=24 + (local.get $0) + (local.get $2) + ) + ) + (drop + (memory.atomic.wait64 $instrumentMemory + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait64 $instrumentMemory + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait64 $appMemory offset=16 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + (drop + (memory.atomic.wait64 $appMemory offset=16 + (local.get $0) + (local.get $1) + (local.get $1) + ) + ) + ) + + ;; CHECK-TEXT: (func $atomic-fence (type $0) + ;; CHECK-TEXT-NEXT: (atomic.fence) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $atomic-fence (type $0) + ;; CHECK-BIN-NEXT: (atomic.fence) + ;; CHECK-BIN-NEXT: ) + (func $atomic-fence + (atomic.fence) + ) +) +;; CHECK-BIN-NODEBUG: (memory $0 (shared i64 23 256)) + +;; CHECK-BIN-NODEBUG: (memory $1 (shared i64 23 256)) + +;; CHECK-BIN-NODEBUG: (memory $2 (shared i64 23 256)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load8_u $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load8_u $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load16_u $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load16_u $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.load $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load8_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load8_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load16_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load16_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load32_u $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load32_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.load $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store8 $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store8 $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store16 $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.store16 $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store8 $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store8 $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store16 $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store16 $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store32 $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.store32 $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.add $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.add $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.add_u $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.add_u $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw16.and_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw16.and_u $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.or_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.or_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.xchg_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.xchg_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.cmpxchg $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw.cmpxchg $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.cmpxchg_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.atomic.rmw8.cmpxchg_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw.cmpxchg $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw.cmpxchg $1 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.cmpxchg_u $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.atomic.rmw32.cmpxchg_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 $0 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait32 $2 offset=4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify $0 offset=24 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.notify $1 offset=24 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 $0 offset=16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (memory.atomic.wait64 $0 offset=16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (atomic.fence) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/multi-memories-basics.wast b/test/lit/basic/multi-memories-basics.wast new file mode 100644 index 00000000000..c9e4d6c7ed8 --- /dev/null +++ b/test/lit/basic/multi-memories-basics.wast @@ -0,0 +1,490 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $none_=>_none (func)) + ;; CHECK-BIN: (type $none_=>_none (func)) + (type $none_=>_none (func)) + ;; CHECK-TEXT: (type $none_=>_i32 (func (result i32))) + ;; CHECK-BIN: (type $none_=>_i32 (func (result i32))) + (type $none_=>_i32 (func (result i32))) + ;; CHECK-TEXT: (import "env" "memory" (memory $importedMemory 1 1)) + ;; CHECK-BIN: (import "env" "memory" (memory $importedMemory 1 1)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + + ;; CHECK-BIN-NODEBUG: (type $1 (func (result i32))) + + ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) + (import "env" "memory" (memory $importedMemory 1 1)) + ;; CHECK-TEXT: (memory $memory1 1 500) + ;; CHECK-BIN: (memory $memory1 1 500) + (memory $memory1 1 500) + ;; CHECK-TEXT: (memory $memory2 1 800) + ;; CHECK-BIN: (memory $memory2 1 800) + (memory $memory2 1 800) + ;; CHECK-TEXT: (memory $memory3 1 400) + ;; CHECK-BIN: (memory $memory3 1 400) + (memory $memory3 1 400) + (data (i32.const 0) "abcd") + + ;; CHECK-TEXT: (data $0 (i32.const 0) "abcd") + + ;; CHECK-TEXT: (func $memory.fill (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (memory.fill $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (data $0 (i32.const 0) "abcd") + + ;; CHECK-BIN: (func $memory.fill (type $none_=>_none) + ;; CHECK-BIN-NEXT: (memory.fill $memory2 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.fill + (memory.fill $memory2 + (i32.const 0) + (i32.const 1) + (i32.const 2) + ) + ) + + ;; CHECK-TEXT: (func $memory.copy (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (memory.copy $memory2 $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 512) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.copy (type $none_=>_none) + ;; CHECK-BIN-NEXT: (memory.copy $memory2 $memory3 + ;; CHECK-BIN-NEXT: (i32.const 512) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.copy + (memory.copy $memory2 $memory3 + (i32.const 512) + (i32.const 0) + (i32.const 12) + ) + ) + + ;; CHECK-TEXT: (func $memory.init (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (memory.init $memory1 $0 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 45) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.init (type $none_=>_none) + ;; CHECK-BIN-NEXT: (memory.init $memory1 $0 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 45) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.init + (memory.init $memory1 0 + (i32.const 0) + (i32.const 0) + (i32.const 45) + ) + ) + + ;; CHECK-TEXT: (func $memory.grow (type $none_=>_i32) (result i32) + ;; CHECK-TEXT-NEXT: (memory.grow $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.grow (type $none_=>_i32) (result i32) + ;; CHECK-BIN-NEXT: (memory.grow $memory3 + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.grow (result i32) + (memory.grow $memory3 + (i32.const 10) + ) + ) + + ;; CHECK-TEXT: (func $memory.size (type $none_=>_i32) (result i32) + ;; CHECK-TEXT-NEXT: (memory.size $memory3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.size (type $none_=>_i32) (result i32) + ;; CHECK-BIN-NEXT: (memory.size $memory3) + ;; CHECK-BIN-NEXT: ) + (func $memory.size (result i32) + (memory.size $memory3) + ) + + ;; CHECK-TEXT: (func $loads (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load $memory1 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load16_s $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load16_s $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load8_s $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load8_s $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load16_u $memory1 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load16_u $memory1 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load8_u $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.load8_u $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $loads (type $none_=>_none) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load $memory1 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load $memory3 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load16_s $memory2 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load16_s $memory2 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load8_s $memory3 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load8_s $memory3 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load16_u $memory1 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load16_u $memory1 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load8_u $memory2 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.load8_u $memory2 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $loads + (drop + (i32.load $memory1 + (i32.const 12) + ) + ) + (drop + (i32.load $memory3 + (i32.const 12) + ) + ) + (drop + (i32.load16_s $memory2 + (i32.const 12) + ) + ) + (drop + (i32.load16_s $memory2 + (i32.const 12) + ) + ) + (drop + (i32.load8_s $memory3 + (i32.const 12) + ) + ) + (drop + (i32.load8_s $memory3 + (i32.const 12) + ) + ) + (drop + (i32.load16_u $memory1 + (i32.const 12) + ) + ) + (drop + (i32.load16_u $memory1 + (i32.const 12) + ) + ) + (drop + (i32.load8_u $memory2 + (i32.const 12) + ) + ) + (drop + (i32.load8_u $memory2 + (i32.const 12) + ) + ) + ) + + ;; CHECK-TEXT: (func $stores (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (i32.store $memory1 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: (i32.const 115) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.store $memory1 + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: (i32.const 115) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.store16 $memory2 + ;; CHECK-TEXT-NEXT: (i32.const 20) + ;; CHECK-TEXT-NEXT: (i32.const 31353) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.store16 $importedMemory + ;; CHECK-TEXT-NEXT: (i32.const 20) + ;; CHECK-TEXT-NEXT: (i32.const 31353) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.store8 $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 23) + ;; CHECK-TEXT-NEXT: (i32.const 120) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.store8 $memory3 + ;; CHECK-TEXT-NEXT: (i32.const 23) + ;; CHECK-TEXT-NEXT: (i32.const 120) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $stores (type $none_=>_none) + ;; CHECK-BIN-NEXT: (i32.store $memory1 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: (i32.const 115) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.store $memory1 + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: (i32.const 115) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.store16 $memory2 + ;; CHECK-BIN-NEXT: (i32.const 20) + ;; CHECK-BIN-NEXT: (i32.const 31353) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.store16 $importedMemory + ;; CHECK-BIN-NEXT: (i32.const 20) + ;; CHECK-BIN-NEXT: (i32.const 31353) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.store8 $memory3 + ;; CHECK-BIN-NEXT: (i32.const 23) + ;; CHECK-BIN-NEXT: (i32.const 120) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.store8 $memory3 + ;; CHECK-BIN-NEXT: (i32.const 23) + ;; CHECK-BIN-NEXT: (i32.const 120) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $stores + (i32.store $memory1 + (i32.const 12) + (i32.const 115) + ) + (i32.store $memory1 + (i32.const 12) + (i32.const 115) + ) + (i32.store16 $memory2 + (i32.const 20) + (i32.const 31353) + ) + (i32.store16 $importedMemory + (i32.const 20) + (i32.const 31353) + ) + (i32.store8 $memory3 + (i32.const 23) + (i32.const 120) + ) + (i32.store8 $memory3 + (i32.const 23) + (i32.const 120) + ) + ) +) +;; CHECK-BIN-NODEBUG: (memory $0 1 500) + +;; CHECK-BIN-NODEBUG: (memory $1 1 800) + +;; CHECK-BIN-NODEBUG: (memory $2 1 400) + +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 0) "abcd") + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.fill $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.copy $1 $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 512) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.init $0 $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 45) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $1) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (memory.grow $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $1) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (memory.size $2) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load16_s $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load16_s $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load8_s $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load8_s $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load16_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load16_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load8_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.load8_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 115) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 115) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store16 $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 20) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 31353) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store16 $mimport$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 20) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 31353) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store8 $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 23) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 120) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.store8 $2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 23) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 120) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/multi-memories-simd.wast b/test/lit/basic/multi-memories-simd.wast new file mode 100644 index 00000000000..edc2bb8745a --- /dev/null +++ b/test/lit/basic/multi-memories-simd.wast @@ -0,0 +1,1399 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $i32_=>_v128 (func (param i32) (result v128))) + ;; CHECK-BIN: (type $i32_=>_v128 (func (param i32) (result v128))) + (type $i32_=>_v128 (func (param i32) (result v128))) + ;; CHECK-TEXT: (type $i32_v128_=>_none (func (param i32 v128))) + ;; CHECK-BIN: (type $i32_v128_=>_none (func (param i32 v128))) + (type $i32_v128_=>_none (func (param i32 v128))) + ;; CHECK-TEXT: (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) + ;; CHECK-BIN: (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) + (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) + ;; CHECK-TEXT: (memory $memorya 1 1) + ;; CHECK-BIN: (memory $memorya 1 1) + (memory $memorya 1 1) + ;; CHECK-TEXT: (memory $memoryb 1 1) + ;; CHECK-BIN: (memory $memoryb 1 1) + (memory $memoryb 1 1) + ;; CHECK-TEXT: (memory $memoryc 1 1) + ;; CHECK-BIN: (memory $memoryc 1 1) + (memory $memoryc 1 1) + ;; CHECK-TEXT: (memory $memoryd 1 1) + ;; CHECK-BIN: (memory $memoryd 1 1) + (memory $memoryd 1 1) + + ;; CHECK-TEXT: (func $v128.load (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load (param $0 i32) (result v128) + (v128.load $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load2 (param $0 i32) (result v128) + (v128.load $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_s $memoryc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_s $memoryc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_s (param $0 i32) (result v128) + (v128.load8x8_s $memoryc + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_s $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_s $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_s2 (param $0 i32) (result v128) + (v128.load8x8_s $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_u $memoryd + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_u $memoryd + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_u (param $0 i32) (result v128) + (v128.load8x8_u $memoryd + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_u $memoryd + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_u $memoryd + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_u2 (param $0 i32) (result v128) + (v128.load8x8_u $memoryd + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_s $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_s $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_s (param $0 i32) (result v128) + (v128.load16x4_s $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_s $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_s $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_s2 (param $0 i32) (result v128) + (v128.load16x4_s $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_u $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_u $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_u (param $0 i32) (result v128) + (v128.load16x4_u $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_u $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_u $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_u2 (param $0 i32) (result v128) + (v128.load16x4_u $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_s $memoryc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_s (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_s $memoryc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_s (param $0 i32) (result v128) + (v128.load32x2_s $memoryc + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_s $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_s2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_s $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_s2 (param $0 i32) (result v128) + (v128.load32x2_s $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_u $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_u (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_u $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_u (param $0 i32) (result v128) + (v128.load32x2_u $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_u $memoryc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_u2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_u $memoryc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_u2 (param $0 i32) (result v128) + (v128.load32x2_u $memoryc + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_splat $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_splat $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_splat (param $0 i32) (result v128) + (v128.load8_splat $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_splat $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_splat $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_splat2 (param $0 i32) (result v128) + (v128.load8_splat $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_splat $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_splat $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_splat (param $0 i32) (result v128) + (v128.load16_splat $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_splat $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_splat $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_splat2 (param $0 i32) (result v128) + (v128.load16_splat $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_splat $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_splat $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_splat (param $0 i32) (result v128) + (v128.load32_splat $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_splat $memoryd + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_splat $memoryd + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_splat2 (param $0 i32) (result v128) + (v128.load32_splat $memoryd + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_splat $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_splat (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_splat $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_splat (param $0 i32) (result v128) + (v128.load64_splat $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_splat $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_splat $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_splat2 (param $0 i32) (result v128) + (v128.load64_splat $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.store (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store (param $0 i32) (param $1 v128) + (v128.store $memorya + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store2 (param $0 i32) (param $1 v128) + (v128.store $memoryb + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_lane $memorya 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_lane $memorya 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load8_lane $memorya 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_lane2 (param $0 i32) (param $1 v128) (result v128) + (v128.load8_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load16_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_lane $memoryd 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_lane $memoryd 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_lane2 (param $0 i32) (param $1 v128) (result v128) + (v128.load16_lane $memoryd 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_lane $memorya 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_lane $memorya 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load32_lane $memorya 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_lane2 (param $0 i32) (param $1 v128) (result v128) + (v128.load32_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryd 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryd 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryd 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane2 (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memorya align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memorya align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memorya align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryb align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryb align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align2 (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryb align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryc offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryc offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryc offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryb offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryb offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_offset2 (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryb offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memorya offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memorya offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memorya offset=32 align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane $memoryd offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane $memoryd offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align_offset2 (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane $memoryd offset=32 align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store8_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store8_lane $memorya 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store8_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store8_lane $memorya 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store8_lane (param $0 i32) (param $1 v128) + (v128.store8_lane $memorya 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store8_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store8_lane $memoryd 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store8_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store8_lane $memoryd 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store8_lane2 (param $0 i32) (param $1 v128) + (v128.store8_lane $memoryd 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store16_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store16_lane $memorya 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store16_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store16_lane $memorya 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store16_lane (param $0 i32) (param $1 v128) + (v128.store16_lane $memorya 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store16_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store16_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store16_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store16_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store16_lane2 (param $0 i32) (param $1 v128) + (v128.store16_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store32_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store32_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store32_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store32_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store32_lane (param $0 i32) (param $1 v128) + (v128.store32_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store32_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store32_lane $memoryc 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store32_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store32_lane $memoryc 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store32_lane2 (param $0 i32) (param $1 v128) + (v128.store32_lane $memoryc 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryc 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryc 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryc 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryb 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryb 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane2 (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryb 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryb align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryb align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryb align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memorya align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memorya align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align2 (param $0 i32) (param $1 v128) + (v128.store64_lane $memorya align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryd offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryd offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryd offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memorya offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memorya offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_offset2 (param $0 i32) (param $1 v128) + (v128.store64_lane $memorya offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryb offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryb offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryb offset=32 align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane $memoryd offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane $memoryd offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align_offset2 (param $0 i32) (param $1 v128) + (v128.store64_lane $memoryd offset=32 align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_zero (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_zero $memorya + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_zero (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_zero $memorya + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_zero (param $0 i32) (result v128) + (v128.load32_zero $memorya + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_zero $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_zero $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_zero2 (param $0 i32) (result v128) + (v128.load32_zero $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_zero (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_zero $memoryb + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_zero (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_zero $memoryb + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_zero (param $0 i32) (result v128) + (v128.load64_zero $memoryb + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_zero $memoryc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_zero $memoryc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_zero2 (param $0 i32) (result v128) + (v128.load64_zero $memoryc + (local.get $0) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (param i32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 v128))) + +;; CHECK-BIN-NODEBUG: (type $2 (func (param i32 v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (memory $0 1 1) + +;; CHECK-BIN-NODEBUG: (memory $1 1 1) + +;; CHECK-BIN-NODEBUG: (memory $2 1 1) + +;; CHECK-BIN-NODEBUG: (memory $3 1 1) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_s $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_s $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_u $3 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_u $3 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_s $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_s $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_u $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_s $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_s $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_u $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_u $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_splat $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_splat $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_splat $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_splat $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_splat $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_splat $3 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_splat $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_splat $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $24 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_lane $0 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $25 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $26 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $27 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_lane $3 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $28 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_lane $0 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $29 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $30 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $3 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $31 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $32 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $0 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $33 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $1 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $34 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $2 offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $35 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $1 offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $36 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $0 offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $37 (type $2) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane $3 offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $38 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store8_lane $0 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $39 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store8_lane $3 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $40 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store16_lane $0 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $41 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store16_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $42 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store32_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $43 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store32_lane $2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $44 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $45 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $46 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $1 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $47 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $0 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $48 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $3 offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $49 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $0 offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $50 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $1 offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $51 (type $1) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane $3 offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $52 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_zero $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $53 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_zero $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $54 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_zero $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $55 (type $0) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_zero $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/multi-table.wast b/test/lit/basic/multi-table.wast new file mode 100644 index 00000000000..d5c7b10aa83 --- /dev/null +++ b/test/lit/basic/multi-table.wast @@ -0,0 +1,163 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $none_=>_none (func)) + ;; CHECK-BIN: (type $none_=>_none (func)) + (type $none_=>_none (func)) + (type $A (struct)) + ;; CHECK-TEXT: (import "a" "b" (table $t1 1 10 funcref)) + + ;; CHECK-TEXT: (global $g1 (ref null $none_=>_none) (ref.func $f)) + ;; CHECK-BIN: (import "a" "b" (table $t1 1 10 funcref)) + + ;; CHECK-BIN: (global $g1 (ref null $none_=>_none) (ref.func $f)) + (global $g1 (ref null $none_=>_none) (ref.func $f)) + ;; CHECK-TEXT: (global $g2 i32 (i32.const 0)) + ;; CHECK-BIN: (global $g2 i32 (i32.const 0)) + (global $g2 i32 (i32.const 0)) + + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + + ;; CHECK-BIN-NODEBUG: (import "a" "b" (table $timport$0 1 10 funcref)) + (import "a" "b" (table $t1 1 10 funcref)) + ;; CHECK-TEXT: (table $t2 3 3 funcref) + ;; CHECK-BIN: (table $t2 3 3 funcref) + (table $t2 3 3 funcref) + ;; CHECK-TEXT: (table $t3 4 4 funcref) + ;; CHECK-BIN: (table $t3 4 4 funcref) + (table $t3 4 4 funcref) + ;; CHECK-TEXT: (table $textern 0 externref) + ;; CHECK-BIN: (table $textern 0 externref) + (table $textern 0 externref) + + ;; A table with a typed function references specialized type. + ;; CHECK-TEXT: (table $tspecial 5 5 (ref null $none_=>_none)) + ;; CHECK-BIN: (table $tspecial 5 5 (ref null $none_=>_none)) + (table $tspecial 5 5 (ref null $none_=>_none)) + + ;; add to $t1 + (elem (i32.const 0) $f) + + ;; add to $t2 + (elem (table $t2) (i32.const 0) func $f) + ;; CHECK-TEXT: (elem $0 (table $t1) (i32.const 0) func $f) + + ;; CHECK-TEXT: (elem $1 (table $t2) (i32.const 0) func $f) + + ;; CHECK-TEXT: (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) + ;; CHECK-BIN: (elem $0 (table $t1) (i32.const 0) func $f) + + ;; CHECK-BIN: (elem $1 (table $t2) (i32.const 0) func $f) + + ;; CHECK-BIN: (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) + (elem $activeNonZeroOffset (table $t2) (offset (i32.const 1)) func $f $g) + + ;; CHECK-TEXT: (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) + ;; CHECK-BIN: (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) + (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null func)) + ;; CHECK-TEXT: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) + ;; CHECK-BIN: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) + (elem $e3-2 (table $t3) (offset (i32.const 2)) (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g))) + + ;; CHECK-TEXT: (elem $passive-1 func $f $g) + ;; CHECK-BIN: (elem $passive-1 func $f $g) + (elem $passive-1 func $f $g) + ;; CHECK-TEXT: (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) + ;; CHECK-BIN: (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) + (elem $passive-2 funcref (item ref.func $f) (item (ref.func $g)) (ref.null func)) + ;; CHECK-TEXT: (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) + ;; CHECK-BIN: (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) + (elem $passive-3 (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g)) (ref.null $none_=>_none) (global.get $g1)) + ;; CHECK-TEXT: (elem $empty func) + ;; CHECK-BIN: (elem $empty func) + (elem $empty func) + (elem $declarative declare func $h) + + ;; This elem will be emitted as usesExpressions because of the type of the + ;; table. + ;; CHECK-TEXT: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) + ;; CHECK-BIN: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) + (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) $f $h) + + ;; CHECK-TEXT: (func $f (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.func $h) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f (type $none_=>_none) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.func $h) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f (drop (ref.func $h))) + + ;; CHECK-TEXT: (func $g (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $g (type $none_=>_none) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $g) + + ;; CHECK-TEXT: (func $h (type $none_=>_none) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $h (type $none_=>_none) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $h) +) +;; CHECK-BIN-NODEBUG: (global $global$0 (ref null $0) (ref.func $0)) + +;; CHECK-BIN-NODEBUG: (global $global$1 i32 (i32.const 0)) + +;; CHECK-BIN-NODEBUG: (table $0 3 3 funcref) + +;; CHECK-BIN-NODEBUG: (table $1 4 4 funcref) + +;; CHECK-BIN-NODEBUG: (table $2 0 externref) + +;; CHECK-BIN-NODEBUG: (table $3 5 5 (ref null $0)) + +;; CHECK-BIN-NODEBUG: (elem $0 (table $timport$0) (i32.const 0) func $0) + +;; CHECK-BIN-NODEBUG: (elem $1 (table $0) (i32.const 0) func $0) + +;; CHECK-BIN-NODEBUG: (elem $2 (table $0) (i32.const 1) func $0 $1) + +;; CHECK-BIN-NODEBUG: (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null nofunc)) + +;; CHECK-BIN-NODEBUG: (elem $4 (table $1) (i32.const 2) (ref null $0) (ref.func $0) (ref.func $1)) + +;; CHECK-BIN-NODEBUG: (elem $5 func $0 $1) + +;; CHECK-BIN-NODEBUG: (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null nofunc)) + +;; CHECK-BIN-NODEBUG: (elem $7 (ref null $0) (ref.func $0) (ref.func $1) (ref.null nofunc) (global.get $global$0)) + +;; CHECK-BIN-NODEBUG: (elem $8 func) + +;; CHECK-BIN-NODEBUG: (elem $9 (table $3) (i32.const 0) (ref null $0) (ref.func $0) (ref.func $2)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/mutable-global.wast b/test/lit/basic/mutable-global.wast new file mode 100644 index 00000000000..154a40a191f --- /dev/null +++ b/test/lit/basic/mutable-global.wast @@ -0,0 +1,54 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (import "env" "global-mut" (global $global-mut (mut i32))) + ;; CHECK-BIN: (import "env" "global-mut" (global $global-mut (mut i32))) + ;; CHECK-BIN-NODEBUG: (import "env" "global-mut" (global $gimport$0 (mut i32))) + (import "env" "global-mut" (global $global-mut (mut i32))) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (global.set $global-mut + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (global.get $global-mut) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (global.set $global-mut + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (global.get $global-mut) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $foo (type $0) + (global.set $global-mut + (i32.add + (global.get $global-mut) + (i32.const 1) + ) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $gimport$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (global.get $gimport$0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/newsyntax.wast b/test/lit/basic/newsyntax.wast new file mode 100644 index 00000000000..0811ec07e8d --- /dev/null +++ b/test/lit/basic/newsyntax.wast @@ -0,0 +1,80 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (type $1 (func (param i32 f64) (result i32))) + + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (type $1 (func (param i32 f64) (result i32))) + + ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + + ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f64) (result i32))) + + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) + (import "env" "table" (table 9 9 funcref)) + + (func "call_indirect" + (drop + (call_indirect (param i32) (param f64) (result i32) (i32.const 10) (f64.const 20) (i32.const 30)) + ) + (call_indirect (i32.const 1)) + ) +) +;; CHECK-TEXT: (export "call_indirect" (func $0)) + +;; CHECK-TEXT: (func $0 (type $0) +;; CHECK-TEXT-NEXT: (drop +;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $1) +;; CHECK-TEXT-NEXT: (i32.const 10) +;; CHECK-TEXT-NEXT: (f64.const 20) +;; CHECK-TEXT-NEXT: (i32.const 30) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $0) +;; CHECK-TEXT-NEXT: (i32.const 1) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: ) + +;; CHECK-BIN: (export "call_indirect" (func $0)) + +;; CHECK-BIN: (func $0 (type $0) +;; CHECK-BIN-NEXT: (drop +;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $1) +;; CHECK-BIN-NEXT: (i32.const 10) +;; CHECK-BIN-NEXT: (f64.const 20) +;; CHECK-BIN-NEXT: (i32.const 30) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $0) +;; CHECK-BIN-NEXT: (i32.const 1) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: ) + +;; CHECK-BIN-NODEBUG: (export "call_indirect" (func $0)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $timport$0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 10) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 20) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 30) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $timport$0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/nonspec-bulk-memory.wast b/test/lit/basic/nonspec-bulk-memory.wast new file mode 100644 index 00000000000..980598f5d91 --- /dev/null +++ b/test/lit/basic/nonspec-bulk-memory.wast @@ -0,0 +1,137 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (memory 1024 1024 + (segment 0 "hello, world") + ) + + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (memory $0 1024 1024) + + ;; CHECK-TEXT: (data $0 (i32.const 0) "hello, world") + + ;; CHECK-TEXT: (func $memory.init (type $0) + ;; CHECK-TEXT-NEXT: (memory.init $0 + ;; CHECK-TEXT-NEXT: (i32.const 512) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (memory $0 1024 1024) + + ;; CHECK-BIN: (data $0 (i32.const 0) "hello, world") + + ;; CHECK-BIN: (func $memory.init (type $0) + ;; CHECK-BIN-NEXT: (memory.init $0 + ;; CHECK-BIN-NEXT: (i32.const 512) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.init + (memory.init 0 + (i32.const 512) + (i32.const 0) + (i32.const 12) + ) + ) + + ;; CHECK-TEXT: (func $data.drop (type $0) + ;; CHECK-TEXT-NEXT: (data.drop $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $data.drop (type $0) + ;; CHECK-BIN-NEXT: (data.drop $0) + ;; CHECK-BIN-NEXT: ) + (func $data.drop + (data.drop 0) + ) + + ;; CHECK-TEXT: (func $memory.copy (type $0) + ;; CHECK-TEXT-NEXT: (memory.copy + ;; CHECK-TEXT-NEXT: (i32.const 512) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 12) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.copy (type $0) + ;; CHECK-BIN-NEXT: (memory.copy + ;; CHECK-BIN-NEXT: (i32.const 512) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.copy + (memory.copy + (i32.const 512) + (i32.const 0) + (i32.const 12) + ) + ) + + ;; CHECK-TEXT: (func $memory.fill (type $0) + ;; CHECK-TEXT-NEXT: (memory.fill + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 42) + ;; CHECK-TEXT-NEXT: (i32.const 1024) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $memory.fill (type $0) + ;; CHECK-BIN-NEXT: (memory.fill + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 42) + ;; CHECK-BIN-NEXT: (i32.const 1024) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $memory.fill + (memory.fill + (i32.const 0) + (i32.const 42) + (i32.const 1024) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (memory $0 1024 1024) + +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 0) "hello, world") + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.init $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 512) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (data.drop $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.copy +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 512) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (memory.fill +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 42) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1024) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/polymorphic_stack.wast b/test/lit/basic/polymorphic_stack.wast new file mode 100644 index 00000000000..f91847817e6 --- /dev/null +++ b/test/lit/basic/polymorphic_stack.wast @@ -0,0 +1,449 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result i32))) + + ;; CHECK-TEXT: (type $FUNCSIG$ii (func (param i32) (result i32))) + ;; CHECK-BIN: (type $0 (func (result i32))) + + ;; CHECK-BIN: (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + ;; CHECK-TEXT: (type $2 (func)) + + ;; CHECK-TEXT: (type $3 (func (param i32))) + + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN: (type $2 (func)) + + ;; CHECK-BIN: (type $3 (func (param i32))) + + ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + + ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result i32))) + + ;; CHECK-BIN-NODEBUG: (type $2 (func)) + + ;; CHECK-BIN-NODEBUG: (type $3 (func (param i32))) + + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) + (import "env" "table" (table 9 9 funcref)) + + ;; CHECK-TEXT: (func $break-and-binary (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (block $x (result i32) + ;; CHECK-TEXT-NEXT: (f32.add + ;; CHECK-TEXT-NEXT: (br_if $x + ;; CHECK-TEXT-NEXT: (i32.trunc_f64_u + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.trunc_f64_u + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $break-and-binary (type $0) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $break-and-binary (result i32) + (block $x (result i32) + (f32.add + (br_if $x + (i32.trunc_f64_u + (unreachable) + ) + (i32.trunc_f64_u + (unreachable) + ) + ) + (f32.const 1) + ) + ) + ) + + ;; CHECK-TEXT: (func $call-and-unary (type $FUNCSIG$ii) (param $0 i32) (result i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (call $call-and-unary + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (i32.eqz + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $FUNCSIG$ii) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $call-and-unary (type $FUNCSIG$ii) (param $0 i32) (result i32) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $call-and-unary (param i32) (result i32) + (drop + (i64.eqz + (call $call-and-unary + (unreachable) + ) + ) + ) + (drop + (i64.eqz + (i32.eqz + (unreachable) + ) + ) + ) + (drop + (i64.eqz + (call_indirect (type $FUNCSIG$ii) + (unreachable) + (unreachable) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $tee (type $3) (param $x i32) + ;; CHECK-TEXT-NEXT: (local $y f32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (local.tee $x + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (local.tee $y + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $tee (type $3) (param $x i32) + ;; CHECK-BIN-NEXT: (local $y f32) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $tee (param $x i32) + (local $y f32) + (drop + (i64.eqz + (local.tee $x + (unreachable) + ) + ) + ) + (drop + (local.tee $y + (i64.eqz + (unreachable) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $tee2 (type $2) + ;; CHECK-TEXT-NEXT: (local $0 f32) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 259) + ;; CHECK-TEXT-NEXT: (local.tee $0 + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $tee2 (type $2) + ;; CHECK-BIN-NEXT: (local $0 f32) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 259) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $tee2 + (local $0 f32) + (if + (i32.const 259) + (local.set $0 + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $select (type $2) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.eqz + ;; CHECK-TEXT-NEXT: (select + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $select (type $2) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $select + (drop + (i64.eqz + (select + (unreachable) + (i32.const 1) + (i32.const 2) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $untaken-break-should-have-value (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (block $x (result i32) + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (br_if $x + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $untaken-break-should-have-value (type $0) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $untaken-break-should-have-value (result i32) + (block $x (result i32) + (block + (br_if $x + (i32.const 0) + (unreachable) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 127) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $label$0 (result i32) + ;; CHECK-TEXT-NEXT: (br_if $label$0 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const -32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 127) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$2 (result i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const -32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-in-block-but-code-before (param $0 i32) (result i32) + (if + (local.get $0) + (return + (i32.const 127) + ) + ) + (block $label$0 (result i32) + (br_if $label$0 + (i32.const 0) + (return + (i32.const -32) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $br_table_unreachable_to_also_unreachable (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (block $a (result i32) + ;; CHECK-TEXT-NEXT: (block $b (result i32) + ;; CHECK-TEXT-NEXT: (br_table $a $b + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $br_table_unreachable_to_also_unreachable (type $0) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 (result i32) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $br_table_unreachable_to_also_unreachable (result i32) + (block $a (result i32) + (block $b (result i32) + (br_table $a $b ;; seems to send a value, but is not taken + (unreachable) + (unreachable) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $untaken-br_if (type $0) (result i32) + ;; CHECK-TEXT-NEXT: (block $label$8 (result i32) + ;; CHECK-TEXT-NEXT: (block $label$9 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (br_if $label$8 + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $untaken-br_if (type $0) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $untaken-br_if (result i32) + (block $label$8 (result i32) + (block $label$9 + (drop + (if + (i32.const 0) + (br_if $label$8 + (unreachable) + (i32.const 0) + ) + (unreachable) + ) + ) + ) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $3) (param $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 f32) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 f32) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 259) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $1) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 127) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const -32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast new file mode 100644 index 00000000000..9a3a5c663c9 --- /dev/null +++ b/test/lit/basic/reference-types.wast @@ -0,0 +1,2470 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result anyref))) + + ;; CHECK-TEXT: (type $sig_anyref (func (param anyref))) + + ;; CHECK-TEXT: (type $sig_funcref (func (param funcref))) + + ;; CHECK-TEXT: (type $3 (func (result funcref))) + + ;; CHECK-TEXT: (type $sig_eqref (func (param eqref))) + ;; CHECK-BIN: (type $0 (func (result anyref))) + + ;; CHECK-BIN: (type $sig_anyref (func (param anyref))) + + ;; CHECK-BIN: (type $sig_funcref (func (param funcref))) + + ;; CHECK-BIN: (type $3 (func (result funcref))) + + ;; CHECK-BIN: (type $sig_eqref (func (param eqref))) + (type $sig_eqref (func (param eqref))) + (type $sig_funcref (func (param funcref))) + (type $sig_anyref (func (param anyref))) + + ;; CHECK-TEXT: (type $5 (func)) + + ;; CHECK-TEXT: (type $6 (func (result eqref))) + + ;; CHECK-TEXT: (type $7 (func (param i32))) + + ;; CHECK-TEXT: (type $8 (func (param eqref) (result funcref))) + + ;; CHECK-TEXT: (import "env" "import_global" (global $import_global eqref)) + + ;; CHECK-TEXT: (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref))) + + ;; CHECK-TEXT: (global $global_eqref (mut eqref) (ref.null none)) + + ;; CHECK-TEXT: (global $global_funcref (mut funcref) (ref.null nofunc)) + + ;; CHECK-TEXT: (global $global_funcref_func (mut funcref) (ref.func $foo)) + + ;; CHECK-TEXT: (global $global_anyref (mut anyref) (ref.null none)) + + ;; CHECK-TEXT: (global $global_anyref2 (mut anyref) (ref.null none)) + + ;; CHECK-TEXT: (table $0 3 3 funcref) + + ;; CHECK-TEXT: (elem $0 (i32.const 0) $take_eqref $take_funcref $take_anyref) + + ;; CHECK-TEXT: (elem declare func $foo $ref-taken-but-not-in-table) + + ;; CHECK-TEXT: (tag $e-i32 (param i32)) + + ;; CHECK-TEXT: (export "export_func" (func $import_func)) + + ;; CHECK-TEXT: (export "export_global" (global $import_global)) + + ;; CHECK-TEXT: (func $take_eqref (type $sig_eqref) (param $0 eqref) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $5 (func)) + + ;; CHECK-BIN: (type $6 (func (result eqref))) + + ;; CHECK-BIN: (type $7 (func (param i32))) + + ;; CHECK-BIN: (type $8 (func (param eqref) (result funcref))) + + ;; CHECK-BIN: (import "env" "import_global" (global $import_global eqref)) + + ;; CHECK-BIN: (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref))) + + ;; CHECK-BIN: (global $global_eqref (mut eqref) (ref.null none)) + + ;; CHECK-BIN: (global $global_funcref (mut funcref) (ref.null nofunc)) + + ;; CHECK-BIN: (global $global_funcref_func (mut funcref) (ref.func $foo)) + + ;; CHECK-BIN: (global $global_anyref (mut anyref) (ref.null none)) + + ;; CHECK-BIN: (global $global_anyref2 (mut anyref) (ref.null none)) + + ;; CHECK-BIN: (table $0 3 3 funcref) + + ;; CHECK-BIN: (elem $0 (i32.const 0) $take_eqref $take_funcref $take_anyref) + + ;; CHECK-BIN: (elem declare func $foo $ref-taken-but-not-in-table) + + ;; CHECK-BIN: (tag $e-i32 (param i32)) + + ;; CHECK-BIN: (export "export_func" (func $import_func)) + + ;; CHECK-BIN: (export "export_global" (global $import_global)) + + ;; CHECK-BIN: (func $take_eqref (type $sig_eqref) (param $0 eqref) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $take_eqref (param eqref)) + + ;; CHECK-TEXT: (func $take_funcref (type $sig_funcref) (param $0 funcref) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $take_funcref (type $sig_funcref) (param $0 funcref) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $take_funcref (param funcref)) + + ;; CHECK-TEXT: (func $take_anyref (type $sig_anyref) (param $0 anyref) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $take_anyref (type $sig_anyref) (param $0 anyref) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $take_anyref (param anyref)) + + ;; CHECK-TEXT: (func $foo (type $5) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $5) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo) + + (table funcref (elem $take_eqref $take_funcref $take_anyref)) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result anyref))) + + ;; CHECK-BIN-NODEBUG: (type $1 (func (param anyref))) + + ;; CHECK-BIN-NODEBUG: (type $2 (func (param funcref))) + + ;; CHECK-BIN-NODEBUG: (type $3 (func (result funcref))) + + ;; CHECK-BIN-NODEBUG: (type $4 (func (param eqref))) + + ;; CHECK-BIN-NODEBUG: (type $5 (func)) + + ;; CHECK-BIN-NODEBUG: (type $6 (func (result eqref))) + + ;; CHECK-BIN-NODEBUG: (type $7 (func (param i32))) + + ;; CHECK-BIN-NODEBUG: (type $8 (func (param eqref) (result funcref))) + + ;; CHECK-BIN-NODEBUG: (import "env" "import_global" (global $gimport$0 eqref)) + + ;; CHECK-BIN-NODEBUG: (import "env" "import_func" (func $fimport$0 (type $8) (param eqref) (result funcref))) + + ;; CHECK-BIN-NODEBUG: (global $global$0 (mut eqref) (ref.null none)) + + ;; CHECK-BIN-NODEBUG: (global $global$1 (mut funcref) (ref.null nofunc)) + + ;; CHECK-BIN-NODEBUG: (global $global$2 (mut funcref) (ref.func $3)) + + ;; CHECK-BIN-NODEBUG: (global $global$3 (mut anyref) (ref.null none)) + + ;; CHECK-BIN-NODEBUG: (global $global$4 (mut anyref) (ref.null none)) + + ;; CHECK-BIN-NODEBUG: (table $0 3 3 funcref) + + ;; CHECK-BIN-NODEBUG: (elem $0 (i32.const 0) $0 $1 $2) + + ;; CHECK-BIN-NODEBUG: (elem declare func $23 $3) + (elem declare func $ref-taken-but-not-in-table) + + (import "env" "import_func" (func $import_func (param eqref) (result funcref))) + (import "env" "import_global" (global $import_global eqref)) + ;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + + ;; CHECK-BIN-NODEBUG: (export "export_func" (func $fimport$0)) + (export "export_func" (func $import_func (param eqref) (result funcref))) + ;; CHECK-BIN-NODEBUG: (export "export_global" (global $gimport$0)) + (export "export_global" (global $import_global)) + + ;; Test global initializer expressions + (global $global_eqref (mut eqref) (ref.null eq)) + (global $global_funcref (mut funcref) (ref.null func)) + (global $global_funcref_func (mut funcref) (ref.func $foo)) + (global $global_anyref (mut anyref) (ref.null any)) + + ;; Test subtype relationship in global initializer expressions + (global $global_anyref2 (mut anyref) (ref.null eq)) + + (tag $e-i32 (param i32)) + + ;; CHECK-TEXT: (func $test (type $5) + ;; CHECK-TEXT-NEXT: (local $local_eqref eqref) + ;; CHECK-TEXT-NEXT: (local $local_funcref funcref) + ;; CHECK-TEXT-NEXT: (local $local_anyref anyref) + ;; CHECK-TEXT-NEXT: (local.set $local_eqref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_eqref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_eqref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_funcref + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_funcref + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_funcref + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_funcref + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $local_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_eqref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_eqref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_eqref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_funcref + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_funcref + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_funcref + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_funcref + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (global.set $global_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_eqref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_eqref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_eqref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_funcref + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_funcref + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_funcref + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_funcref + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $take_anyref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block (result eqref) + ;; CHECK-TEXT-NEXT: (br_if $block + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block0 (result eqref) + ;; CHECK-TEXT-NEXT: (br_if $block0 + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block1 (result eqref) + ;; CHECK-TEXT-NEXT: (br_if $block1 + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block2 (result funcref) + ;; CHECK-TEXT-NEXT: (br_if $block2 + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block3 (result funcref) + ;; CHECK-TEXT-NEXT: (br_if $block3 + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block4 (result funcref) + ;; CHECK-TEXT-NEXT: (br_if $block4 + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block5 (result funcref) + ;; CHECK-TEXT-NEXT: (br_if $block5 + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block6 (result anyref) + ;; CHECK-TEXT-NEXT: (br_if $block6 + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block7 (result anyref) + ;; CHECK-TEXT-NEXT: (br_if $block7 + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block8 (result anyref) + ;; CHECK-TEXT-NEXT: (br_if $block8 + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block9 (result anyref) + ;; CHECK-TEXT-NEXT: (br_if $block9 + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $block10 (result anyref) + ;; CHECK-TEXT-NEXT: (br_if $block10 + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in (result eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in11 (result eqref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in12 (result eqref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in13 (result funcref) + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in14 (result funcref) + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in15 (result funcref) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in16 (result funcref) + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in17 (result anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in18 (result anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in19 (result anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in20 (result anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in21 (result anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (loop $loop-in22 (result anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result eqref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result funcref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (if (result anyref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (ref.i31 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (try $try (result eqref) + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (try $try28 (result funcref) + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (try $try29 (result anyref) + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (try $try30 (result anyref) + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (select (result eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (select (result funcref) + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (select + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (select (result anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (ref.i31 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.is_null + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $test (type $5) + ;; CHECK-BIN-NEXT: (local $local_eqref eqref) + ;; CHECK-BIN-NEXT: (local $local_funcref funcref) + ;; CHECK-BIN-NEXT: (local $local_anyref anyref) + ;; CHECK-BIN-NEXT: (local.set $local_eqref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_eqref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_eqref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_funcref + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_funcref + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_funcref + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_funcref + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $local_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_eqref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_eqref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_eqref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_funcref + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_funcref + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_funcref + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_funcref + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (global.set $global_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_eqref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_eqref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_eqref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_funcref + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_funcref + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_funcref + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_funcref + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $take_anyref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_eqref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_funcref) + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $sig_anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$1 (result eqref) + ;; CHECK-BIN-NEXT: (br_if $label$1 + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$2 (result eqref) + ;; CHECK-BIN-NEXT: (br_if $label$2 + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$3 (result eqref) + ;; CHECK-BIN-NEXT: (br_if $label$3 + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$4 (result funcref) + ;; CHECK-BIN-NEXT: (br_if $label$4 + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$5 (result funcref) + ;; CHECK-BIN-NEXT: (br_if $label$5 + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$6 (result funcref) + ;; CHECK-BIN-NEXT: (br_if $label$6 + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$7 (result funcref) + ;; CHECK-BIN-NEXT: (br_if $label$7 + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$8 (result anyref) + ;; CHECK-BIN-NEXT: (br_if $label$8 + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$9 (result anyref) + ;; CHECK-BIN-NEXT: (br_if $label$9 + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$10 (result anyref) + ;; CHECK-BIN-NEXT: (br_if $label$10 + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$11 (result anyref) + ;; CHECK-BIN-NEXT: (br_if $label$11 + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$12 (result anyref) + ;; CHECK-BIN-NEXT: (br_if $label$12 + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$13 (result eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$14 (result eqref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$15 (result eqref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$16 (result funcref) + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$17 (result funcref) + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$18 (result funcref) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$19 (result funcref) + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$20 (result anyref) + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$21 (result anyref) + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$22 (result anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$23 (result anyref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$24 (result anyref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (loop $label$25 (result anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result eqref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result funcref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (if (result anyref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (ref.i31 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (try $label$40 (result eqref) + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (try $label$43 (result funcref) + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (try $label$46 (result anyref) + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (try $label$49 (result anyref) + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (select (result eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (select (result funcref) + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (select + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (select (result anyref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (ref.i31 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.is_null + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $test + (local $local_eqref eqref) + (local $local_funcref funcref) + (local $local_anyref anyref) + + ;; Test types for local.get/set + (local.set $local_eqref (local.get $local_eqref)) + (local.set $local_eqref (global.get $global_eqref)) + (local.set $local_eqref (ref.null eq)) + (local.set $local_funcref (local.get $local_funcref)) + (local.set $local_funcref (global.get $global_funcref)) + (local.set $local_funcref (ref.null func)) + (local.set $local_funcref (ref.func $foo)) + (local.set $local_anyref (local.get $local_anyref)) + (local.set $local_anyref (global.get $global_anyref)) + (local.set $local_anyref (ref.null any)) + + ;; Test subtype relationship for local.set + (local.set $local_anyref (local.get $local_eqref)) + (local.set $local_anyref (global.get $global_eqref)) + (local.set $local_anyref (ref.null eq)) + + ;; Test types for global.get/set + (global.set $global_eqref (global.get $global_eqref)) + (global.set $global_eqref (local.get $local_eqref)) + (global.set $global_eqref (ref.null eq)) + (global.set $global_funcref (global.get $global_funcref)) + (global.set $global_funcref (local.get $local_funcref)) + (global.set $global_funcref (ref.null func)) + (global.set $global_funcref (ref.func $foo)) + (global.set $global_anyref (global.get $global_anyref)) + (global.set $global_anyref (local.get $local_anyref)) + (global.set $global_anyref (ref.null any)) + + ;; Test subtype relationship for global.set + (global.set $global_anyref (global.get $global_eqref)) + (global.set $global_anyref (local.get $local_eqref)) + (global.set $global_anyref (ref.null eq)) + + ;; Test function call params + (call $take_eqref (local.get $local_eqref)) + (call $take_eqref (global.get $global_eqref)) + (call $take_eqref (ref.null eq)) + (call $take_funcref (local.get $local_funcref)) + (call $take_funcref (global.get $global_funcref)) + (call $take_funcref (ref.null func)) + (call $take_funcref (ref.func $foo)) + (call $take_anyref (local.get $local_anyref)) + (call $take_anyref (global.get $global_anyref)) + (call $take_anyref (ref.null any)) + + ;; Test subtype relationship for function call params + (call $take_anyref (local.get $local_eqref)) + (call $take_anyref (global.get $global_eqref)) + (call $take_anyref (ref.null eq)) + + ;; Test call_indirect params + (call_indirect (type $sig_eqref) (local.get $local_eqref) (i32.const 0)) + (call_indirect (type $sig_eqref) (global.get $global_eqref) (i32.const 0)) + (call_indirect (type $sig_eqref) (ref.null eq) (i32.const 0)) + (call_indirect (type $sig_funcref) (local.get $local_funcref) (i32.const 1)) + (call_indirect (type $sig_funcref) (global.get $global_funcref) (i32.const 1)) + (call_indirect (type $sig_funcref) (ref.null func) (i32.const 1)) + (call_indirect (type $sig_funcref) (ref.func $foo) (i32.const 1)) + (call_indirect (type $sig_anyref) (local.get $local_anyref) (i32.const 3)) + (call_indirect (type $sig_anyref) (global.get $global_anyref) (i32.const 3)) + (call_indirect (type $sig_anyref) (ref.null any) (i32.const 3)) + + ;; Test subtype relationship for call_indirect params + (call_indirect (type $sig_anyref) (local.get $local_eqref) (i32.const 3)) + (call_indirect (type $sig_anyref) (global.get $global_eqref) (i32.const 3)) + (call_indirect (type $sig_anyref) (ref.null eq) (i32.const 3)) + + ;; Test block return type + (drop + (block (result eqref) + (br_if 0 (local.get $local_eqref) (i32.const 1)) + ) + ) + (drop + (block (result eqref) + (br_if 0 (global.get $global_eqref) (i32.const 1)) + ) + ) + (drop + (block (result eqref) + (br_if 0 (ref.null eq) (i32.const 1)) + ) + ) + (drop + (block (result funcref) + (br_if 0 (local.get $local_funcref) (i32.const 1)) + ) + ) + (drop + (block (result funcref) + (br_if 0 (global.get $global_funcref) (i32.const 1)) + ) + ) + (drop + (block (result funcref) + (br_if 0 (ref.null func) (i32.const 1)) + ) + ) + (drop + (block (result funcref) + (br_if 0 (ref.func $foo) (i32.const 1)) + ) + ) + (drop + (block (result anyref) + (br_if 0 (local.get $local_anyref) (i32.const 1)) + ) + ) + (drop + (block (result anyref) + (br_if 0 (global.get $global_anyref) (i32.const 1)) + ) + ) + (drop + (block (result anyref) + (br_if 0 (ref.null any) (i32.const 1)) + ) + ) + + ;; Test subtype relationship for block return type + (drop + (block (result anyref) + (br_if 0 (local.get $local_eqref) (i32.const 1)) + ) + ) + (drop + (block (result anyref) + (br_if 0 (ref.null eq) (i32.const 1)) + ) + ) + + ;; Test loop return type + (drop + (loop (result eqref) + (local.get $local_eqref) + ) + ) + (drop + (loop (result eqref) + (global.get $global_eqref) + ) + ) + (drop + (loop (result eqref) + (ref.null eq) + ) + ) + (drop + (loop (result funcref) + (local.get $local_funcref) + ) + ) + (drop + (loop (result funcref) + (global.get $global_funcref) + ) + ) + (drop + (loop (result funcref) + (ref.null func) + ) + ) + (drop + (loop (result funcref) + (ref.func $foo) + ) + ) + (drop + (loop (result anyref) + (local.get $local_anyref) + ) + ) + (drop + (loop (result anyref) + (global.get $global_anyref) + ) + ) + (drop + (loop (result anyref) + (ref.null any) + ) + ) + + ;; Test subtype relationship for loop return type + (drop + (loop (result anyref) + (local.get $local_eqref) + ) + ) + (drop + (loop (result anyref) + (global.get $global_eqref) + ) + ) + (drop + (loop (result anyref) + (ref.null eq) + ) + ) + + ;; Test if return type + (drop + (if (result eqref) + (i32.const 1) + (local.get $local_eqref) + (ref.null eq) + ) + ) + (drop + (if (result funcref) + (i32.const 1) + (local.get $local_funcref) + (ref.null func) + ) + ) + (drop + (if (result anyref) + (i32.const 1) + (local.get $local_anyref) + (ref.null any) + ) + ) + + ;; Test subtype relationship for if return type + (drop + (if (result anyref) + (i32.const 1) + (local.get $local_eqref) + (local.get $local_eqref) + ) + ) + (drop + (if (result anyref) + (i32.const 1) + (ref.null eq) + (ref.null i31) + ) + ) + (drop + (if (result anyref) + (i32.const 1) + (ref.i31 + (i32.const 0) + ) + (ref.null eq) + ) + ) + + ;; Test try return type + (drop + (try (result eqref) + (do + (local.get $local_eqref) + ) + (catch $e-i32 + (drop (pop i32)) + (ref.null eq) + ) + ) + ) + (drop + (try (result funcref) + (do + (ref.func $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (ref.null func) + ) + ) + ) + + ;; Test subtype relationship for try return type + (drop + (try (result anyref) + (do + (local.get $local_eqref) + ) + (catch $e-i32 + (drop (pop i32)) + (ref.null any) + ) + ) + ) + (drop + (try (result anyref) + (do + (ref.null eq) + ) + (catch $e-i32 + (drop (pop i32)) + (local.get $local_eqref) + ) + ) + ) + + ;; Test typed select + (drop + (select (result eqref) + (local.get $local_eqref) + (ref.null eq) + (i32.const 1) + ) + ) + (drop + (select (result funcref) + (local.get $local_funcref) + (ref.null func) + (i32.const 1) + ) + ) + (drop + (select (result i32) + (i32.const 0) + (i32.const 2) + (i32.const 1) + ) + ) + + ;; Test subtype relationship for typed select + (drop + (select (result anyref) + (local.get $local_eqref) + (ref.i31 + (i32.const 0) + ) + (i32.const 1) + ) + ) + + ;; ref.is_null takes any reference types + (drop (ref.is_null (local.get $local_eqref))) + (drop (ref.is_null (global.get $global_eqref))) + (drop (ref.is_null (ref.null eq))) + (drop (ref.is_null (local.get $local_funcref))) + (drop (ref.is_null (global.get $global_funcref))) + (drop (ref.is_null (ref.null func))) + (drop (ref.is_null (ref.func $foo))) + (drop (ref.is_null (local.get $local_anyref))) + (drop (ref.is_null (global.get $global_anyref))) + (drop (ref.is_null (ref.null any))) + ) + + ;; Test function return type + + ;; CHECK-TEXT: (func $return_eqref_local (type $6) (result eqref) + ;; CHECK-TEXT-NEXT: (local $local_eqref eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_eqref_local (type $6) (result eqref) + ;; CHECK-BIN-NEXT: (local $local_eqref eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + (func $return_eqref_local (result eqref) + (local $local_eqref eqref) + (local.get $local_eqref) + ) + + ;; CHECK-TEXT: (func $return_eqref_global (type $6) (result eqref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_eqref_global (type $6) (result eqref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + (func $return_eqref_global (result eqref) + (global.get $global_eqref) + ) + + ;; CHECK-TEXT: (func $return_eqref_null (type $6) (result eqref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_eqref_null (type $6) (result eqref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + (func $return_eqref_null (result eqref) + (ref.null eq) + ) + + ;; CHECK-TEXT: (func $return_funcref_local (type $3) (result funcref) + ;; CHECK-TEXT-NEXT: (local $local_funcref funcref) + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_funcref_local (type $3) (result funcref) + ;; CHECK-BIN-NEXT: (local $local_funcref funcref) + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + (func $return_funcref_local (result funcref) + (local $local_funcref funcref) + (local.get $local_funcref) + ) + + ;; CHECK-TEXT: (func $return_funcref_global (type $3) (result funcref) + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_funcref_global (type $3) (result funcref) + ;; CHECK-BIN-NEXT: (global.get $global_funcref) + ;; CHECK-BIN-NEXT: ) + (func $return_funcref_global (result funcref) + (global.get $global_funcref) + ) + + ;; CHECK-TEXT: (func $return_funcref_null (type $3) (result funcref) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_funcref_null (type $3) (result funcref) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + (func $return_funcref_null (result funcref) + (ref.null func) + ) + + ;; CHECK-TEXT: (func $return_funcref_func (type $3) (result funcref) + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_funcref_func (type $3) (result funcref) + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + (func $return_funcref_func (result funcref) + (ref.func $foo) + ) + + ;; CHECK-TEXT: (func $return_anyref_local (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (local $local_anyref anyref) + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref_local (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (local $local_anyref anyref) + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref_local (result anyref) + (local $local_anyref anyref) + (local.get $local_anyref) + ) + + ;; CHECK-TEXT: (func $return_anyref_global (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref_global (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (global.get $global_anyref) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref_global (result anyref) + (global.get $global_anyref) + ) + + ;; CHECK-TEXT: (func $return_anyref_null (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref_null (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref_null (result anyref) + (ref.null any) + ) + + ;; Test subtype relationship in function return type + + ;; CHECK-TEXT: (func $return_anyref2 (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (local $local_eqref eqref) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref2 (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (local $local_eqref eqref) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref2 (result anyref) + (local $local_eqref eqref) + (local.get $local_eqref) + ) + + ;; CHECK-TEXT: (func $return_anyref3 (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref3 (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (global.get $global_eqref) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref3 (result anyref) + (global.get $global_eqref) + ) + + ;; CHECK-TEXT: (func $return_anyref4 (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return_anyref4 (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + (func $return_anyref4 (result anyref) + (ref.null eq) + ) + + ;; Test returns + + ;; CHECK-TEXT: (func $returns_eqref (type $6) (result eqref) + ;; CHECK-TEXT-NEXT: (local $local_eqref eqref) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $returns_eqref (type $6) (result eqref) + ;; CHECK-BIN-NEXT: (local $local_eqref eqref) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $returns_eqref (result eqref) + (local $local_eqref eqref) + (return (local.get $local_eqref)) + (return (global.get $global_eqref)) + (return (ref.null eq)) + ) + + ;; CHECK-TEXT: (func $returns_funcref (type $3) (result funcref) + ;; CHECK-TEXT-NEXT: (local $local_funcref funcref) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (global.get $global_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $returns_funcref (type $3) (result funcref) + ;; CHECK-BIN-NEXT: (local $local_funcref funcref) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $returns_funcref (result funcref) + (local $local_funcref funcref) + (return (local.get $local_funcref)) + (return (global.get $global_funcref)) + (return (ref.func $foo)) + (return (ref.null func)) + ) + + ;; CHECK-TEXT: (func $returns_anyref (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (local $local_anyref anyref) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (global.get $global_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $returns_anyref (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (local $local_anyref anyref) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $returns_anyref (result anyref) + (local $local_anyref anyref) + (return (local.get $local_anyref)) + (return (global.get $global_anyref)) + (return (ref.null any)) + ) + + ;; Test subtype relationship in returns + + ;; CHECK-TEXT: (func $returns_anyref2 (type $0) (result anyref) + ;; CHECK-TEXT-NEXT: (local $local_eqref eqref) + ;; CHECK-TEXT-NEXT: (local $local_funcref funcref) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (global.get $global_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $returns_anyref2 (type $0) (result anyref) + ;; CHECK-BIN-NEXT: (local $local_eqref eqref) + ;; CHECK-BIN-NEXT: (local $local_funcref funcref) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $returns_anyref2 (result anyref) + (local $local_eqref eqref) + (local $local_funcref funcref) + (return (local.get $local_eqref)) + (return (global.get $global_eqref)) + (return (ref.null eq)) + ) + + ;; CHECK-TEXT: (func $ref-user (type $5) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (ref.func $ref-taken-but-not-in-table) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-user (type $5) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (ref.func $ref-taken-but-not-in-table) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $ref-user + (drop + ;; an "elem declare func" must be emitted for this ref.func which is not + ;; in the table + (ref.func $ref-taken-but-not-in-table) + ) + ) + + ;; CHECK-TEXT: (func $ref-taken-but-not-in-table (type $5) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $ref-taken-but-not-in-table (type $5) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $ref-taken-but-not-in-table) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $4) (param $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $2) (param $0 funcref) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $1) (param $0 anyref) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $5) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $5) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$0 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$0 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$1 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (global.set $global$3 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $0 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $0 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $1 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $1 +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $2 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $4) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $4) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $4) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$6 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$7 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$8 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$8 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$9 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$9 +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$10 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$11 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$11 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$12 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$12 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$13 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$14 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$15 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$16 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$17 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$18 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$19 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$20 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$21 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$22 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$23 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$24 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$25 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.i31 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (try $label$40 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (try $label$43 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (try $label$46 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (try $label$49 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (select (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (select (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (select +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (select (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (ref.i31 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.is_null +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $6) (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $6) (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $6) (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $3) (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $3) (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$1) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $3) (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $3) (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$3) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (global.get $global$0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $6) (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $3) (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 funcref) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 anyref) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $0) (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 eqref) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 funcref) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $5) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $23) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $5) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/reg_switch.wast b/test/lit/basic/reg_switch.wast new file mode 100644 index 00000000000..5f9dd5d7f6b --- /dev/null +++ b/test/lit/basic/reg_switch.wast @@ -0,0 +1,62 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (memory $0 0) + (memory $0 0) + + ;; CHECK-TEXT: (func $0 (type $0) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (block $A + ;; CHECK-TEXT-NEXT: (br_table $A + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $0 (type $0) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (br_table $label$2 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) + ;; CHECK-BIN-NODEBUG-NEXT: (if + ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) + ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 + ;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$2 + ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) + ;; CHECK-BIN-NODEBUG-NEXT: ) + ;; CHECK-BIN-NODEBUG-NEXT: ) + ;; CHECK-BIN-NODEBUG-NEXT: ) + ;; CHECK-BIN-NODEBUG-NEXT: ) + (func $0 (type $0) + (if + (i32.const 0) + (block $A + (br_table $A + (i32.const 0) + ) + ) + ) + ) +) diff --git a/test/lit/basic/segment-overlap.wast b/test/lit/basic/segment-overlap.wast new file mode 100644 index 00000000000..a4d7e11cc4a --- /dev/null +++ b/test/lit/basic/segment-overlap.wast @@ -0,0 +1,30 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (memory $0 10) + ;; CHECK-BIN: (memory $0 10) + ;; CHECK-BIN-NODEBUG: (memory $0 10) + (memory $0 10) + (data (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") ;; overlaps with the next + (data (i32.const 104) "\00\00\00\00") +) +;; CHECK-TEXT: (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") + +;; CHECK-TEXT: (data $1 (i32.const 104) "\00\00\00\00") + +;; CHECK-BIN: (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") + +;; CHECK-BIN: (data $1 (i32.const 104) "\00\00\00\00") + +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") + +;; CHECK-BIN-NODEBUG: (data $1 (i32.const 104) "\00\00\00\00") diff --git a/test/lit/basic/signext.wast b/test/lit/basic/signext.wast new file mode 100644 index 00000000000..495ef958a55 --- /dev/null +++ b/test/lit/basic/signext.wast @@ -0,0 +1,114 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + + ;; CHECK-TEXT: (func $signext (type $0) + ;; CHECK-TEXT-NEXT: (local $0 i32) + ;; CHECK-TEXT-NEXT: (local $1 i64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.extend8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.extend16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.extend8_s + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.extend16_s + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i64.extend32_s + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $signext (type $0) + ;; CHECK-BIN-NEXT: (local $0 i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.extend8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.extend16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.extend8_s + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.extend16_s + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i64.extend32_s + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $signext (type $0) + (local $0 i32) + (local $1 i64) + (drop (i32.extend8_s (local.get $0))) + (drop (i32.extend16_s (local.get $0))) + (drop (i64.extend8_s (local.get $1))) + (drop (i64.extend16_s (local.get $1))) + (drop (i64.extend32_s (local.get $1))) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.extend8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.extend16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.extend8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.extend16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i64.extend32_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/simd.wast b/test/lit/basic/simd.wast new file mode 100644 index 00000000000..483caefca2f --- /dev/null +++ b/test/lit/basic/simd.wast @@ -0,0 +1,6087 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (memory 1 1) + + ;; CHECK-TEXT: (type $0 (func (param v128 v128) (result v128))) + + ;; CHECK-TEXT: (type $1 (func (param v128) (result v128))) + + ;; CHECK-TEXT: (type $2 (func (param i32) (result v128))) + + ;; CHECK-TEXT: (type $3 (func (param v128 i32) (result v128))) + + ;; CHECK-TEXT: (type $4 (func (param v128) (result i32))) + + ;; CHECK-TEXT: (type $5 (func (param i32 v128))) + + ;; CHECK-TEXT: (type $6 (func (param i32 v128) (result v128))) + + ;; CHECK-TEXT: (type $7 (func (result v128))) + + ;; CHECK-TEXT: (type $8 (func (param f32) (result v128))) + + ;; CHECK-TEXT: (type $9 (func (param f64) (result v128))) + + ;; CHECK-TEXT: (type $10 (func (param v128) (result i64))) + + ;; CHECK-TEXT: (type $11 (func (param v128 i64) (result v128))) + + ;; CHECK-TEXT: (type $12 (func (param v128) (result f32))) + + ;; CHECK-TEXT: (type $13 (func (param v128 f32) (result v128))) + + ;; CHECK-TEXT: (type $14 (func (param v128) (result f64))) + + ;; CHECK-TEXT: (type $15 (func (param v128 f64) (result v128))) + + ;; CHECK-TEXT: (type $16 (func (param v128 v128 v128) (result v128))) + + ;; CHECK-TEXT: (memory $0 1 1) + + ;; CHECK-TEXT: (func $v128.load (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func (param v128 v128) (result v128))) + + ;; CHECK-BIN: (type $1 (func (param v128) (result v128))) + + ;; CHECK-BIN: (type $2 (func (param i32) (result v128))) + + ;; CHECK-BIN: (type $3 (func (param v128 i32) (result v128))) + + ;; CHECK-BIN: (type $4 (func (param v128) (result i32))) + + ;; CHECK-BIN: (type $5 (func (param i32 v128))) + + ;; CHECK-BIN: (type $6 (func (param i32 v128) (result v128))) + + ;; CHECK-BIN: (type $7 (func (result v128))) + + ;; CHECK-BIN: (type $8 (func (param f32) (result v128))) + + ;; CHECK-BIN: (type $9 (func (param f64) (result v128))) + + ;; CHECK-BIN: (type $10 (func (param v128) (result i64))) + + ;; CHECK-BIN: (type $11 (func (param v128 i64) (result v128))) + + ;; CHECK-BIN: (type $12 (func (param v128) (result f32))) + + ;; CHECK-BIN: (type $13 (func (param v128 f32) (result v128))) + + ;; CHECK-BIN: (type $14 (func (param v128) (result f64))) + + ;; CHECK-BIN: (type $15 (func (param v128 f64) (result v128))) + + ;; CHECK-BIN: (type $16 (func (param v128 v128 v128) (result v128))) + + ;; CHECK-BIN: (memory $0 1 1) + + ;; CHECK-BIN: (func $v128.load (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load (param $0 i32) (result v128) + (v128.load offset=0 align=16 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_s (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_s (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_s (param $0 i32) (result v128) + (v128.load8x8_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_u (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_u (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_u (param $0 i32) (result v128) + (v128.load8x8_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_s (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_s (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_s (param $0 i32) (result v128) + (v128.load16x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_u (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_u (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_u (param $0 i32) (result v128) + (v128.load16x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_s (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_s (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_s (param $0 i32) (result v128) + (v128.load32x2_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_u (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_u (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_u (param $0 i32) (result v128) + (v128.load32x2_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_splat (param $0 i32) (result v128) + (v128.load8_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_splat (param $0 i32) (result v128) + (v128.load16_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_splat (param $0 i32) (result v128) + (v128.load32_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_splat (param $0 i32) (result v128) + (v128.load64_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.store (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store (param $0 i32) (param $1 v128) + (v128.store offset=0 align=16 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.const.i8x16 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.i8x16 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.i8x16 (result v128) + (v128.const i8x16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) + ) + + ;; CHECK-TEXT: (func $v128.const.i16x8 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.i16x8 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.i16x8 (result v128) + (v128.const i16x8 1 2 3 4 5 6 7 8) + ) + + ;; CHECK-TEXT: (func $v128.const.i32x4 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.i32x4 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.i32x4 (result v128) + (v128.const i32x4 1 2 3 4) + ) + + ;; CHECK-TEXT: (func $v128.const.i64x2 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.i64x2 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.i64x2 (result v128) + (v128.const i64x2 1 2) + ) + + ;; CHECK-TEXT: (func $v128.const.f32x4 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.f32x4 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.f32x4 (result v128) + (v128.const f32x4 1.0 2 3 4) + ) + + ;; CHECK-TEXT: (func $v128.const.f64x2 (type $7) (result v128) + ;; CHECK-TEXT-NEXT: (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.const.f64x2 (type $7) (result v128) + ;; CHECK-BIN-NEXT: (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) + ;; CHECK-BIN-NEXT: ) + (func $v128.const.f64x2 (result v128) + (v128.const f64x2 1.0 2) + ) + + ;; CHECK-TEXT: (func $i8x16.shuffle (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.shuffle (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.shuffle (param $0 v128) (param $1 v128) (result v128) + (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.swizzle (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.swizzle + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.swizzle (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.swizzle + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.swizzle (param $0 v128) (param $1 v128) (result v128) + (i8x16.swizzle + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.splat (param $0 i32) (result v128) + (i8x16.splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.splat (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.splat (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.splat (param $0 i32) (result v128) + (i16x8.splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.splat (type $8) (param $0 f32) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.splat (type $8) (param $0 f32) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.splat (param $0 f32) (result v128) + (f32x4.splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.splat (type $9) (param $0 f64) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.splat (type $9) (param $0 f64) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.splat (param $0 f64) (result v128) + (f64x2.splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.extract_lane_s (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i8x16.extract_lane_s 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.extract_lane_s (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i8x16.extract_lane_s 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.extract_lane_s (param $0 v128) (result i32) + (i8x16.extract_lane_s 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.extract_lane_u (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i8x16.extract_lane_u 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.extract_lane_u (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i8x16.extract_lane_u 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.extract_lane_u (param $0 v128) (result i32) + (i8x16.extract_lane_u 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.replace_lane (param $0 v128) (param $1 i32) (result v128) + (i8x16.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extract_lane_s (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i16x8.extract_lane_s 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extract_lane_s (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i16x8.extract_lane_s 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extract_lane_s (param $0 v128) (result i32) + (i16x8.extract_lane_s 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extract_lane_u (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i16x8.extract_lane_u 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extract_lane_u (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i16x8.extract_lane_u 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extract_lane_u (param $0 v128) (result i32) + (i16x8.extract_lane_u 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.replace_lane (param $0 v128) (param $1 i32) (result v128) + (i16x8.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extract_lane (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i32x4.extract_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extract_lane (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i32x4.extract_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extract_lane (param $0 v128) (result i32) + (i32x4.extract_lane 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.replace_lane (param $0 v128) (param $1 i32) (result v128) + (i32x4.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extract_lane (type $10) (param $0 v128) (result i64) + ;; CHECK-TEXT-NEXT: (i64x2.extract_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extract_lane (type $10) (param $0 v128) (result i64) + ;; CHECK-BIN-NEXT: (i64x2.extract_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extract_lane (param $0 v128) (result i64) + (i64x2.extract_lane 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.replace_lane (type $11) (param $0 v128) (param $1 i64) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.replace_lane (type $11) (param $0 v128) (param $1 i64) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.replace_lane (param $0 v128) (param $1 i64) (result v128) + (i64x2.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.extract_lane (type $12) (param $0 v128) (result f32) + ;; CHECK-TEXT-NEXT: (f32x4.extract_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.extract_lane (type $12) (param $0 v128) (result f32) + ;; CHECK-BIN-NEXT: (f32x4.extract_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.extract_lane (param $0 v128) (result f32) + (f32x4.extract_lane 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.replace_lane (type $13) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.replace_lane (type $13) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.replace_lane (param $0 v128) (param $1 f32) (result v128) + (f32x4.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.extract_lane (type $14) (param $0 v128) (result f64) + ;; CHECK-TEXT-NEXT: (f64x2.extract_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.extract_lane (type $14) (param $0 v128) (result f64) + ;; CHECK-BIN-NEXT: (f64x2.extract_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.extract_lane (param $0 v128) (result f64) + (f64x2.extract_lane 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.replace_lane (type $15) (param $0 v128) (param $1 f64) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.replace_lane (type $15) (param $0 v128) (param $1 f64) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.replace_lane (param $0 v128) (param $1 f64) (result v128) + (f64x2.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.eq (param $0 v128) (param $1 v128) (result v128) + (i8x16.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.ne (param $0 v128) (param $1 v128) (result v128) + (i8x16.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.lt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.lt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.lt_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.lt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.lt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.lt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.lt_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.lt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.gt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.gt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.gt_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.gt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.gt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.gt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.gt_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.gt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.le_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.le_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.le_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.le_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.le_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.le_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.le_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.le_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.ge_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.ge_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.ge_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.ge_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.ge_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.ge_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.ge_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.ge_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.eq (param $0 v128) (param $1 v128) (result v128) + (i16x8.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.ne (param $0 v128) (param $1 v128) (result v128) + (i16x8.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.lt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.lt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.lt_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.lt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.lt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.lt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.lt_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.lt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.gt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.gt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.gt_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.gt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.gt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.gt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.gt_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.gt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.le_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.le_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.le_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.le_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.le_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.le_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.le_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.le_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.ge_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.ge_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.ge_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.ge_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.ge_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.ge_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.ge_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.ge_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.eq (param $0 v128) (param $1 v128) (result v128) + (i32x4.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.ne (param $0 v128) (param $1 v128) (result v128) + (i32x4.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.lt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.lt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.lt_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.lt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.lt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.lt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.lt_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.lt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.gt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.gt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.gt_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.gt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.gt_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.gt_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.gt_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.gt_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.le_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.le_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.le_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.le_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.le_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.le_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.le_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.le_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.ge_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.ge_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.ge_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.ge_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.ge_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.ge_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.ge_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.ge_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.eq (param $0 v128) (param $1 v128) (result v128) + (f32x4.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.ne (param $0 v128) (param $1 v128) (result v128) + (f32x4.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.lt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.lt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.lt (param $0 v128) (param $1 v128) (result v128) + (f32x4.lt + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.gt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.gt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.gt (param $0 v128) (param $1 v128) (result v128) + (f32x4.gt + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.le + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.le + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.le (param $0 v128) (param $1 v128) (result v128) + (f32x4.le + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.ge + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.ge + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.ge (param $0 v128) (param $1 v128) (result v128) + (f32x4.ge + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.eq (param $0 v128) (param $1 v128) (result v128) + (f64x2.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.ne (param $0 v128) (param $1 v128) (result v128) + (f64x2.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.lt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.lt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.lt (param $0 v128) (param $1 v128) (result v128) + (f64x2.lt + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.gt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.gt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.gt (param $0 v128) (param $1 v128) (result v128) + (f64x2.gt + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.le + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.le + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.le (param $0 v128) (param $1 v128) (result v128) + (f64x2.le + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.ge + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.ge + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.ge (param $0 v128) (param $1 v128) (result v128) + (f64x2.ge + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.not (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.not + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.not (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.not + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.not (param $0 v128) (result v128) + (v128.not + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.and (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.and + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.and (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.and + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.and (param $0 v128) (param $1 v128) (result v128) + (v128.and + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.andnot (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.andnot + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.andnot (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.andnot + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.andnot (param $0 v128) (param $1 v128) (result v128) + (v128.andnot + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.or (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.or + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.or (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.or + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.or (param $0 v128) (param $1 v128) (result v128) + (v128.or + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.xor (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.xor + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.xor (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.xor + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.xor (param $0 v128) (param $1 v128) (result v128) + (v128.xor + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.bitselect (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.bitselect + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: (local.get $2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.bitselect (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.bitselect + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.bitselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + (v128.bitselect + (local.get $0) + (local.get $1) + (local.get $2) + ) + ) + + ;; CHECK-TEXT: (func $v128.any_true (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (v128.any_true + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.any_true (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (v128.any_true + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.any_true (param $0 v128) (result i32) + (v128.any_true + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load8_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load16_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load32_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_offset (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_offset (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_lane_align_offset (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_lane offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_lane_align_offset (type $6) (param $0 i32) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_lane offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) + (v128.load64_lane align=1 offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store8_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store8_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store8_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store8_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store8_lane (param $0 i32) (param $1 v128) + (v128.store8_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store16_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store16_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store16_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store16_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store16_lane (param $0 i32) (param $1 v128) + (v128.store16_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store32_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store32_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store32_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store32_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store32_lane (param $0 i32) (param $1 v128) + (v128.store32_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane (param $0 i32) (param $1 v128) + (v128.store64_lane 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align (param $0 i32) (param $1 v128) + (v128.store64_lane align=1 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_offset (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane offset=32 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_offset (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane offset=32 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) + (v128.store64_lane offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.store64_lane_align_offset (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store64_lane offset=32 align=1 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store64_lane_align_offset (type $5) (param $0 i32) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store64_lane offset=32 align=1 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) + (v128.store64_lane align=1 offset=32 0 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_zero (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_zero (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_zero (param $0 i32) (result v128) + (v128.load32_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_zero (type $2) (param $0 i32) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_zero (type $2) (param $0 i32) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_zero (param $0 i32) (result v128) + (v128.load64_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.demote_f64x2_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.demote_f64x2_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.demote_f64x2_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.demote_f64x2_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.demote_f64x2_zero (param $0 v128) (result v128) + (f32x4.demote_f64x2_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.promote_low_f32x4 (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.promote_low_f32x4 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.promote_low_f32x4 (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.promote_low_f32x4 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.promote_low_f32x4 (param $0 v128) (result v128) + (f64x2.promote_low_f32x4 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.abs (param $0 v128) (result v128) + (i8x16.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.neg (param $0 v128) (result v128) + (i8x16.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.popcnt (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.popcnt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.popcnt (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.popcnt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.popcnt (param $0 v128) (result v128) + (i8x16.popcnt + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i8x16.all_true + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i8x16.all_true + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.all_true (param $0 v128) (result i32) + (i8x16.all_true + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i8x16.bitmask + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i8x16.bitmask + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.bitmask (param $0 v128) (result i32) + (i8x16.bitmask + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.narrow_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.narrow_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.narrow_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.narrow_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.narrow_i16x8_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.narrow_i16x8_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.narrow_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.narrow_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.narrow_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.narrow_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.narrow_i16x8_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.narrow_i16x8_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.ceil + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.ceil + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.ceil (param $0 v128) (result v128) + (f32x4.ceil + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.floor + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.floor + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.floor (param $0 v128) (result v128) + (f32x4.floor + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.trunc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.trunc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.trunc (param $0 v128) (result v128) + (f32x4.trunc + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.nearest + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.nearest + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.nearest (param $0 v128) (result v128) + (f32x4.nearest + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.shl + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.shl + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.shl (param $0 v128) (param $1 i32) (result v128) + (i8x16.shl + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.shr_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.shr_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.shr_s (param $0 v128) (param $1 i32) (result v128) + (i8x16.shr_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.shr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.shr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.shr_u (param $0 v128) (param $1 i32) (result v128) + (i8x16.shr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.add (param $0 v128) (param $1 v128) (result v128) + (i8x16.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.add_sat_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.add_sat_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.add_sat_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.add_sat_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.add_sat_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.add_sat_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.add_sat_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.add_sat_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.sub (param $0 v128) (param $1 v128) (result v128) + (i8x16.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.sub_sat_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.sub_sat_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.sub_sat_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.sub_sat_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.sub_sat_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.sub_sat_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.sub_sat_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.sub_sat_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.ceil + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.ceil + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.ceil (param $0 v128) (result v128) + (f64x2.ceil + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.floor + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.floor + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.floor (param $0 v128) (result v128) + (f64x2.floor + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.min_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.min_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.min_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.min_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.min_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.min_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.min_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.min_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.max_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.max_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.max_s (param $0 v128) (param $1 v128) (result v128) + (i8x16.max_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.max_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.max_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.max_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.max_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.trunc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.trunc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.trunc (param $0 v128) (result v128) + (f64x2.trunc + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i8x16.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i8x16.avgr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i8x16.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i8x16.avgr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i8x16.avgr_u (param $0 v128) (param $1 v128) (result v128) + (i8x16.avgr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extadd_pairwise_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extadd_pairwise_i8x16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extadd_pairwise_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extadd_pairwise_i8x16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extadd_pairwise_i8x16_s (param $0 v128) (result v128) + (i16x8.extadd_pairwise_i8x16_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extadd_pairwise_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extadd_pairwise_i8x16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extadd_pairwise_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extadd_pairwise_i8x16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extadd_pairwise_i8x16_u (param $0 v128) (result v128) + (i16x8.extadd_pairwise_i8x16_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extadd_pairwise_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extadd_pairwise_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extadd_pairwise_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extadd_pairwise_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extadd_pairwise_i16x8_s (param $0 v128) (result v128) + (i32x4.extadd_pairwise_i16x8_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extadd_pairwise_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extadd_pairwise_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extadd_pairwise_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extadd_pairwise_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extadd_pairwise_i16x8_u (param $0 v128) (result v128) + (i32x4.extadd_pairwise_i16x8_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.abs (param $0 v128) (result v128) + (i16x8.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.neg (param $0 v128) (result v128) + (i16x8.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.q15mulr_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.q15mulr_sat_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.q15mulr_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.q15mulr_sat_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.q15mulr_sat_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.q15mulr_sat_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i16x8.all_true + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i16x8.all_true + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.all_true (param $0 v128) (result i32) + (i16x8.all_true + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i16x8.bitmask + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i16x8.bitmask + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.bitmask (param $0 v128) (result i32) + (i16x8.bitmask + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.narrow_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.narrow_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.narrow_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.narrow_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.narrow_i32x4_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.narrow_i32x4_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.narrow_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.narrow_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.narrow_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.narrow_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.narrow_i32x4_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.narrow_i32x4_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extend_low_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extend_low_i8x16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extend_low_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extend_low_i8x16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extend_low_i8x16_s (param $0 v128) (result v128) + (i16x8.extend_low_i8x16_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extend_high_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extend_high_i8x16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extend_high_i8x16_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extend_high_i8x16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extend_high_i8x16_s (param $0 v128) (result v128) + (i16x8.extend_high_i8x16_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extend_low_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extend_low_i8x16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extend_low_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extend_low_i8x16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extend_low_i8x16_u (param $0 v128) (result v128) + (i16x8.extend_low_i8x16_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extend_high_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extend_high_i8x16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extend_high_i8x16_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extend_high_i8x16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extend_high_i8x16_u (param $0 v128) (result v128) + (i16x8.extend_high_i8x16_u + (local.get $0) + ) + ) + +;; CHECK-TEXT: (func $i16x8.shl (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-TEXT-NEXT: (i16x8.shl +;; CHECK-TEXT-NEXT: (local.get $0) +;; CHECK-TEXT-NEXT: (local.get $1) +;; CHECK-TEXT-NEXT: ) +;; CHECK-TEXT-NEXT: ) +;; CHECK-BIN: (func $i16x8.shl (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NEXT: (i16x8.shl +;; CHECK-BIN-NEXT: (local.get $0) +;; CHECK-BIN-NEXT: (local.get $1) +;; CHECK-BIN-NEXT: ) +;; CHECK-BIN-NEXT: ) +(func $i16x8.shl (param $0 v128) (param $1 i32) (result v128) + (i16x8.shl + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.shr_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.shr_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.shr_s (param $0 v128) (param $1 i32) (result v128) + (i16x8.shr_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.shr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.shr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.shr_u (param $0 v128) (param $1 i32) (result v128) + (i16x8.shr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.add (param $0 v128) (param $1 v128) (result v128) + (i16x8.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.add_sat_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.add_sat_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.add_sat_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.add_sat_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.add_sat_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.add_sat_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.add_sat_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.add_sat_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.sub (param $0 v128) (param $1 v128) (result v128) + (i16x8.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.sub_sat_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.sub_sat_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.sub_sat_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.sub_sat_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.sub_sat_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.sub_sat_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.sub_sat_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.sub_sat_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.nearest + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.nearest + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.nearest (param $0 v128) (result v128) + (f64x2.nearest + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.mul (param $0 v128) (param $1 v128) (result v128) + (i16x8.mul + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.min_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.min_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.min_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.min_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.min_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.min_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.min_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.min_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.max_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.max_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.max_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.max_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.max_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.max_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.max_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.max_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.avgr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.avgr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.avgr_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.avgr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extmul_low_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extmul_low_i8x16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extmul_low_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extmul_low_i8x16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extmul_low_i8x16_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.extmul_low_i8x16_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extmul_high_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extmul_high_i8x16_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extmul_high_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extmul_high_i8x16_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extmul_high_i8x16_s (param $0 v128) (param $1 v128) (result v128) + (i16x8.extmul_high_i8x16_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extmul_low_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extmul_low_i8x16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extmul_low_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extmul_low_i8x16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extmul_low_i8x16_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.extmul_low_i8x16_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i16x8.extmul_high_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i16x8.extmul_high_i8x16_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i16x8.extmul_high_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i16x8.extmul_high_i8x16_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i16x8.extmul_high_i8x16_u (param $0 v128) (param $1 v128) (result v128) + (i16x8.extmul_high_i8x16_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.abs (param $0 v128) (result v128) + (i32x4.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.neg (param $0 v128) (result v128) + (i32x4.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i32x4.all_true + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i32x4.all_true + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.all_true (param $0 v128) (result i32) + (i32x4.all_true + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i32x4.bitmask + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i32x4.bitmask + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.bitmask (param $0 v128) (result i32) + (i32x4.bitmask + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extend_low_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extend_low_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extend_low_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extend_low_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extend_low_i16x8_s (param $0 v128) (result v128) + (i32x4.extend_low_i16x8_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extend_high_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extend_high_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extend_high_i16x8_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extend_high_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extend_high_i16x8_s (param $0 v128) (result v128) + (i32x4.extend_high_i16x8_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extend_low_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extend_low_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extend_low_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extend_low_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extend_low_i16x8_u (param $0 v128) (result v128) + (i32x4.extend_low_i16x8_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extend_high_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extend_high_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extend_high_i16x8_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extend_high_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extend_high_i16x8_u (param $0 v128) (result v128) + (i32x4.extend_high_i16x8_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.shl + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.shl + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.shl (param $0 v128) (param $1 i32) (result v128) + (i32x4.shl + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.shr_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.shr_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.shr_s (param $0 v128) (param $1 i32) (result v128) + (i32x4.shr_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.shr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.shr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.shr_u (param $0 v128) (param $1 i32) (result v128) + (i32x4.shr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.add (param $0 v128) (param $1 v128) (result v128) + (i32x4.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.sub (param $0 v128) (param $1 v128) (result v128) + (i32x4.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.mul (param $0 v128) (param $1 v128) (result v128) + (i32x4.mul + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.min_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.min_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.min_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.min_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.min_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.min_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.min_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.min_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.max_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.max_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.max_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.max_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.max_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.max_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.max_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.max_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.dot_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.dot_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.dot_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.dot_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.dot_i16x8_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.dot_i16x8_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extmul_low_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extmul_low_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extmul_low_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extmul_low_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extmul_low_i16x8_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.extmul_low_i16x8_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extmul_high_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extmul_high_i16x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extmul_high_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extmul_high_i16x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extmul_high_i16x8_s (param $0 v128) (param $1 v128) (result v128) + (i32x4.extmul_high_i16x8_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extmul_low_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extmul_low_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extmul_low_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extmul_low_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extmul_low_i16x8_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.extmul_low_i16x8_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.extmul_high_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.extmul_high_i16x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.extmul_high_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.extmul_high_i16x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.extmul_high_i16x8_u (param $0 v128) (param $1 v128) (result v128) + (i32x4.extmul_high_i16x8_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.abs (param $0 v128) (result v128) + (i64x2.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.neg (param $0 v128) (result v128) + (i64x2.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i64x2.all_true + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.all_true (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i64x2.all_true + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.all_true (param $0 v128) (result i32) + (i64x2.all_true + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-TEXT-NEXT: (i64x2.bitmask + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.bitmask (type $4) (param $0 v128) (result i32) + ;; CHECK-BIN-NEXT: (i64x2.bitmask + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.bitmask (param $0 v128) (result i32) + (i64x2.bitmask + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extend_low_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extend_low_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extend_low_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extend_low_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extend_low_i32x4_s (param $0 v128) (result v128) + (i64x2.extend_low_i32x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extend_high_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extend_high_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extend_high_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extend_high_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extend_high_i32x4_s (param $0 v128) (result v128) + (i64x2.extend_high_i32x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extend_low_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extend_low_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extend_low_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extend_low_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extend_low_i32x4_u (param $0 v128) (result v128) + (i64x2.extend_low_i32x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extend_high_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extend_high_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extend_high_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extend_high_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extend_high_i32x4_u (param $0 v128) (result v128) + (i64x2.extend_high_i32x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.shl + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.shl (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.shl + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.shl (param $0 v128) (param $1 i32) (result v128) + (i64x2.shl + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.shr_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.shr_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.shr_s (param $0 v128) (param $1 i32) (result v128) + (i64x2.shr_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.shr_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.shr_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.shr_u (param $0 v128) (param $1 i32) (result v128) + (i64x2.shr_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.add (param $0 v128) (param $1 v128) (result v128) + (i64x2.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.sub (param $0 v128) (param $1 v128) (result v128) + (i64x2.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.mul (param $0 v128) (param $1 v128) (result v128) + (i64x2.mul + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.eq (param $0 v128) (param $1 v128) (result v128) + (i64x2.eq + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.ne (param $0 v128) (param $1 v128) (result v128) + (i64x2.ne + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.lt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.lt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.lt_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.lt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.gt_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.gt_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.gt_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.gt_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.le_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.le_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.le_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.le_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.ge_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.ge_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.ge_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.ge_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extmul_low_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extmul_low_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extmul_low_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extmul_low_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extmul_low_i32x4_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.extmul_low_i32x4_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extmul_high_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extmul_high_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extmul_high_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extmul_high_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extmul_high_i32x4_s (param $0 v128) (param $1 v128) (result v128) + (i64x2.extmul_high_i32x4_s + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extmul_low_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extmul_low_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extmul_low_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extmul_low_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extmul_low_i32x4_u (param $0 v128) (param $1 v128) (result v128) + (i64x2.extmul_low_i32x4_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i64x2.extmul_high_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i64x2.extmul_high_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64x2.extmul_high_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (i64x2.extmul_high_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64x2.extmul_high_i32x4_u (param $0 v128) (param $1 v128) (result v128) + (i64x2.extmul_high_i32x4_u + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.abs (param $0 v128) (result v128) + (f32x4.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.neg (param $0 v128) (result v128) + (f32x4.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.sqrt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.sqrt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.sqrt (param $0 v128) (result v128) + (f32x4.sqrt + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.add (param $0 v128) (param $1 v128) (result v128) + (f32x4.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.sub (param $0 v128) (param $1 v128) (result v128) + (f32x4.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.mul (param $0 v128) (param $1 v128) (result v128) + (f32x4.mul + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.div + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.div + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.div (param $0 v128) (param $1 v128) (result v128) + (f32x4.div + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.min + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.min + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.min (param $0 v128) (param $1 v128) (result v128) + (f32x4.min + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.max + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.max + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.max (param $0 v128) (param $1 v128) (result v128) + (f32x4.max + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.pmin + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.pmin + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.pmin (param $0 v128) (param $1 v128) (result v128) + (f32x4.pmin + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.pmax + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.pmax + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.pmax (param $0 v128) (param $1 v128) (result v128) + (f32x4.pmax + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.abs (param $0 v128) (result v128) + (f64x2.abs + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.neg (param $0 v128) (result v128) + (f64x2.neg + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.sqrt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.sqrt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.sqrt (param $0 v128) (result v128) + (f64x2.sqrt + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.add (param $0 v128) (param $1 v128) (result v128) + (f64x2.add + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.sub (param $0 v128) (param $1 v128) (result v128) + (f64x2.sub + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.mul (param $0 v128) (param $1 v128) (result v128) + (f64x2.mul + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.div + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.div + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.div (param $0 v128) (param $1 v128) (result v128) + (f64x2.div + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.min + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.min + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.min (param $0 v128) (param $1 v128) (result v128) + (f64x2.min + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.max + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.max + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.max (param $0 v128) (param $1 v128) (result v128) + (f64x2.max + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.pmin + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.pmin + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.pmin (param $0 v128) (param $1 v128) (result v128) + (f64x2.pmin + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.pmax + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.pmax + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.pmax (param $0 v128) (param $1 v128) (result v128) + (f64x2.pmax + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.trunc_sat_f32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.trunc_sat_f32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.trunc_sat_f32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.trunc_sat_f32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.trunc_sat_f32x4_s (param $0 v128) (result v128) + (i32x4.trunc_sat_f32x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.trunc_sat_f32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.trunc_sat_f32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.trunc_sat_f32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.trunc_sat_f32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.trunc_sat_f32x4_u (param $0 v128) (result v128) + (i32x4.trunc_sat_f32x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.convert_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.convert_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.convert_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.convert_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.convert_i32x4_s (param $0 v128) (result v128) + (f32x4.convert_i32x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f32x4.convert_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.convert_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32x4.convert_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.convert_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32x4.convert_i32x4_u (param $0 v128) (result v128) + (f32x4.convert_i32x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.trunc_sat_f64x2_s_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.trunc_sat_f64x2_s_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.trunc_sat_f64x2_s_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.trunc_sat_f64x2_s_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.trunc_sat_f64x2_s_zero (param $0 v128) (result v128) + (i32x4.trunc_sat_f64x2_s_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $i32x4.trunc_sat_f64x2_u_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (i32x4.trunc_sat_f64x2_u_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i32x4.trunc_sat_f64x2_u_zero (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (i32x4.trunc_sat_f64x2_u_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i32x4.trunc_sat_f64x2_u_zero (param $0 v128) (result v128) + (i32x4.trunc_sat_f64x2_u_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.convert_low_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.convert_low_i32x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.convert_low_i32x4_s (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.convert_low_i32x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.convert_low_i32x4_s (param $0 v128) (result v128) + (f64x2.convert_low_i32x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f64x2.convert_low_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.convert_low_i32x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f64x2.convert_low_i32x4_u (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.convert_low_i32x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f64x2.convert_low_i32x4_u (param $0 v128) (result v128) + (f64x2.convert_low_i32x4_u + (local.get $0) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (param v128 v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $2 (func (param i32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $3 (func (param v128 i32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $4 (func (param v128) (result i32))) + +;; CHECK-BIN-NODEBUG: (type $5 (func (param i32 v128))) + +;; CHECK-BIN-NODEBUG: (type $6 (func (param i32 v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $7 (func (result v128))) + +;; CHECK-BIN-NODEBUG: (type $8 (func (param f32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $9 (func (param f64) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $10 (func (param v128) (result i64))) + +;; CHECK-BIN-NODEBUG: (type $11 (func (param v128 i64) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $12 (func (param v128) (result f32))) + +;; CHECK-BIN-NODEBUG: (type $13 (func (param v128 f32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $14 (func (param v128) (result f64))) + +;; CHECK-BIN-NODEBUG: (type $15 (func (param v128 f64) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $16 (func (param v128 v128 v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (memory $0 1 1) + +;; CHECK-BIN-NODEBUG: (func $0 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $7) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.swizzle +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $8) (param $0 f32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $9) (param $0 f64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $24 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.extract_lane_s 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $25 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.extract_lane_u 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $26 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $27 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extract_lane_s 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $28 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extract_lane_u 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $29 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $30 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extract_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $31 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $32 (type $10) (param $0 v128) (result i64) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extract_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $33 (type $11) (param $0 v128) (param $1 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $34 (type $12) (param $0 v128) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.extract_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $35 (type $13) (param $0 v128) (param $1 f32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $36 (type $14) (param $0 v128) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.extract_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $37 (type $15) (param $0 v128) (param $1 f64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $38 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $39 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $40 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $41 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.lt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $42 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $43 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $44 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.le_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $45 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.le_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $46 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $47 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.ge_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $48 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $49 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $50 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $51 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.lt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $52 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $53 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $54 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.le_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $55 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.le_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $56 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $57 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.ge_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $58 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $59 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $60 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $61 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.lt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $62 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $63 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $64 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.le_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $65 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.le_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $66 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $67 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.ge_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $68 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $69 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $70 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.lt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $71 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.gt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $72 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.le +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $73 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.ge +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $74 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $75 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $76 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.lt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $77 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.gt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $78 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.le +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $79 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.ge +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $80 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.not +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $81 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.and +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $82 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.andnot +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $83 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.or +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $84 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.xor +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $85 (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.bitselect +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $86 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (v128.any_true +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $87 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $88 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $89 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $90 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $91 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $92 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $93 (type $6) (param $0 i32) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_lane offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $94 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store8_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $95 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store16_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $96 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store32_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $97 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $98 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $99 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane offset=32 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $100 (type $5) (param $0 i32) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store64_lane offset=32 align=1 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $101 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $102 (type $2) (param $0 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $103 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.demote_f64x2_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $104 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.promote_low_f32x4 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $105 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $106 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $107 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.popcnt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $108 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.all_true +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $109 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.bitmask +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $110 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.narrow_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $111 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.narrow_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $112 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.ceil +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $113 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.floor +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $114 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.trunc +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $115 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.nearest +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $116 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.shl +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $117 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $118 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $119 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $120 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.add_sat_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $121 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.add_sat_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $122 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $123 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.sub_sat_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $124 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.sub_sat_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $125 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.ceil +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $126 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.floor +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $127 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.min_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $128 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.min_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $129 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.max_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $130 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.max_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $131 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.trunc +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $132 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i8x16.avgr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $133 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extadd_pairwise_i8x16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $134 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extadd_pairwise_i8x16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $135 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extadd_pairwise_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $136 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extadd_pairwise_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $137 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $138 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $139 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.q15mulr_sat_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $140 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.all_true +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $141 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.bitmask +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $142 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.narrow_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $143 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.narrow_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $144 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extend_low_i8x16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $145 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extend_high_i8x16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $146 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extend_low_i8x16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $147 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extend_high_i8x16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $148 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.shl +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $149 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $150 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $151 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $152 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.add_sat_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $153 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.add_sat_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $154 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $155 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.sub_sat_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $156 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.sub_sat_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $157 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.nearest +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $158 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $159 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.min_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $160 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.min_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $161 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.max_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $162 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.max_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $163 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.avgr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $164 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extmul_low_i8x16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $165 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extmul_high_i8x16_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $166 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extmul_low_i8x16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $167 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i16x8.extmul_high_i8x16_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $168 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $169 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $170 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.all_true +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $171 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.bitmask +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $172 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extend_low_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $173 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extend_high_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $174 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extend_low_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $175 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extend_high_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $176 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.shl +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $177 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $178 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $179 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $180 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $181 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $182 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.min_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $183 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.min_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $184 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.max_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $185 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.max_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $186 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.dot_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $187 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extmul_low_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $188 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extmul_high_i16x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $189 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extmul_low_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $190 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.extmul_high_i16x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $191 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $192 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $193 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.all_true +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $194 (type $4) (param $0 v128) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.bitmask +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $195 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extend_low_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $196 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extend_high_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $197 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extend_low_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $198 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extend_high_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $199 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.shl +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $200 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.shr_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $201 (type $3) (param $0 v128) (param $1 i32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $202 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $203 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $204 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $205 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $206 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $207 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $208 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $209 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.le_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $210 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.ge_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $211 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extmul_low_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $212 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extmul_high_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $213 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extmul_low_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $214 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i64x2.extmul_high_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $215 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $216 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $217 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.sqrt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $218 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $219 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $220 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $221 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.div +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $222 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.min +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $223 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.max +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $224 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.pmin +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $225 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.pmax +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $226 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $227 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $228 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.sqrt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $229 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $230 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $231 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $232 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.div +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $233 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.min +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $234 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.max +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $235 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.pmin +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $236 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.pmax +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $237 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.trunc_sat_f32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $238 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.trunc_sat_f32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $239 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.convert_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $240 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.convert_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $241 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.trunc_sat_f64x2_s_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $242 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (i32x4.trunc_sat_f64x2_u_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $243 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.convert_low_i32x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $244 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.convert_low_i32x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/simd64.wast b/test/lit/basic/simd64.wast new file mode 100644 index 00000000000..ed4350b6384 --- /dev/null +++ b/test/lit/basic/simd64.wast @@ -0,0 +1,343 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (memory i64 1 1) + + ;; CHECK-TEXT: (type $0 (func (param i64) (result v128))) + + ;; CHECK-TEXT: (type $1 (func (param i64 v128))) + + ;; CHECK-TEXT: (memory $0 i64 1 1) + + ;; CHECK-TEXT: (func $v128.load (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func (param i64) (result v128))) + + ;; CHECK-BIN: (type $1 (func (param i64 v128))) + + ;; CHECK-BIN: (memory $0 i64 1 1) + + ;; CHECK-BIN: (func $v128.load (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load (param $0 i64) (result v128) + (v128.load offset=0 align=16 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.store (type $1) (param $0 i64) (param $1 v128) + ;; CHECK-TEXT-NEXT: (v128.store + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.store (type $1) (param $0 i64) (param $1 v128) + ;; CHECK-BIN-NEXT: (v128.store + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.store (param $0 i64) (param $1 v128) + (v128.store offset=0 align=16 + (local.get $0) + (local.get $1) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8_splat (param $0 i64) (result v128) + (v128.load8_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16_splat (param $0 i64) (result v128) + (v128.load16_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_splat (param $0 i64) (result v128) + (v128.load32_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_splat (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_splat (param $0 i64) (result v128) + (v128.load64_splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_u (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_u (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_u (param $0 i64) (result v128) + (v128.load8x8_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load8x8_s (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load8x8_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load8x8_s (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load8x8_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load8x8_s (param $0 i64) (result v128) + (v128.load8x8_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_s (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_s (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_s (param $0 i64) (result v128) + (v128.load16x4_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load16x4_u (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load16x4_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load16x4_u (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load16x4_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load16x4_u (param $0 i64) (result v128) + (v128.load16x4_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_s (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_s + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_s (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_s + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_s (param $0 i64) (result v128) + (v128.load32x2_s + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32x2_u (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32x2_u + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32x2_u (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32x2_u + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32x2_u (param $0 i64) (result v128) + (v128.load32x2_u + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load32_zero (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load32_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load32_zero (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load32_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load32_zero (param $0 i64) (result v128) + (v128.load32_zero + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $v128.load64_zero (type $0) (param $0 i64) (result v128) + ;; CHECK-TEXT-NEXT: (v128.load64_zero + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $v128.load64_zero (type $0) (param $0 i64) (result v128) + ;; CHECK-BIN-NEXT: (v128.load64_zero + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $v128.load64_zero (param $0 i64) (result v128) + (v128.load64_zero + (local.get $0) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (param i64) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i64 v128))) + +;; CHECK-BIN-NODEBUG: (memory $0 i64 1 1) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i64) (param $1 v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.store +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load8x8_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load16x4_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32x2_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load32_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) (param $0 i64) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (v128.load64_zero +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/subtypes.wast b/test/lit/basic/subtypes.wast new file mode 100644 index 00000000000..d283ebefa34 --- /dev/null +++ b/test/lit/basic/subtypes.wast @@ -0,0 +1,219 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +;; Test that we can roundtrip struct and array types +(module + ;; Arrays + ;; CHECK-TEXT: (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) + + ;; CHECK-TEXT: (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) + + ;; CHECK-TEXT: (type $vector-i32 (array i32)) + ;; CHECK-BIN: (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) + + ;; CHECK-BIN: (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) + + ;; CHECK-BIN: (type $vector-i32 (array i32)) + (type $vector-i32 (array i32)) + + ;; CHECK-TEXT: (type $struct-any (sub (struct (field (ref any))))) + + ;; CHECK-TEXT: (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) + + ;; CHECK-TEXT: (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) + + ;; CHECK-TEXT: (type $vector-any (sub (array (ref any)))) + ;; CHECK-BIN: (type $struct-any (sub (struct (field (ref any))))) + + ;; CHECK-BIN: (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) + + ;; CHECK-BIN: (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) + + ;; CHECK-BIN: (type $vector-any (sub (array (ref any)))) + (type $vector-any (sub (array (ref any)))) + ;; CHECK-TEXT: (type $vector-i31 (sub $vector-any (array (ref i31)))) + ;; CHECK-BIN: (type $vector-i31 (sub $vector-any (array (ref i31)))) + (type $vector-i31 (sub $vector-any (array (ref i31)))) + + ;; Structs + (type $struct-any (sub (struct + (field (ref any)) + ))) + (type $struct-i31 (sub $struct-any (struct + (field (ref i31)) + ))) + ;; CHECK-TEXT: (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) + + ;; CHECK-TEXT: (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) + + ;; CHECK-TEXT: (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) + ;; CHECK-BIN: (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) + + ;; CHECK-BIN: (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) + + ;; CHECK-BIN: (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) + (type $struct-i31_any (sub $struct-i31(struct + (field (ref i31)) + (field (ref any)) + ))) + + ;; Recursive structs + (type $struct-rec-one (sub (struct + (field (ref $struct-rec-one)) + ))) + (type $struct-rec-two (sub $struct-rec-one (struct + (field (ref $struct-rec-two)) + (field (ref $struct-rec-two)) + ))) + + ;; CHECK-TEXT: (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) + + ;; CHECK-TEXT: (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) + + ;; CHECK-TEXT: (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) + ;; CHECK-TEXT-NEXT: (local.set $yes-null + ;; CHECK-TEXT-NEXT: (local.get $no-null) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) + + ;; CHECK-BIN: (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) + + ;; CHECK-BIN: (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) + ;; CHECK-BIN-NEXT: (local.set $yes-null + ;; CHECK-BIN-NEXT: (local.get $no-null) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $foo (param $no-null (ref $vector-i32)) + (param $yes-null (ref null $vector-i32)) + ;; ok to set a non-nullable reference to a nullable target + (local.set $yes-null (local.get $no-null)) + ) + + ;; CHECK-TEXT: (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) + ;; CHECK-TEXT-NEXT: (local.set $v-any + ;; CHECK-TEXT-NEXT: (local.get $v-i31) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) + ;; CHECK-BIN-NEXT: (local.set $v-any + ;; CHECK-BIN-NEXT: (local.get $v-i31) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $bar (param $v-i31 (ref $vector-i31)) + (param $v-any (ref $vector-any)) + ;; ok to set a vector of (immutable) i31s to a vector of anyies + (local.set $v-any (local.get $v-i31)) + ) + + ;; CHECK-TEXT: (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) + ;; CHECK-TEXT-NEXT: (local.set $s-any + ;; CHECK-TEXT-NEXT: (local.get $s-i31) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) + ;; CHECK-BIN-NEXT: (local.set $s-any + ;; CHECK-BIN-NEXT: (local.get $s-i31) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $baz (param $s-i31 (ref $struct-i31)) + (param $s-any (ref $struct-any)) + ;; ok to set a struct of an (immutable) i31 to a one of an any + (local.set $s-any (local.get $s-i31)) + ) + + ;; CHECK-TEXT: (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) + ;; CHECK-TEXT-NEXT: (local.set $s-i31 + ;; CHECK-TEXT-NEXT: (local.get $s-i31_any) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) + ;; CHECK-BIN-NEXT: (local.set $s-i31 + ;; CHECK-BIN-NEXT: (local.get $s-i31_any) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $boo (param $s-i31 (ref $struct-i31)) + (param $s-i31_any (ref $struct-i31_any)) + ;; also ok to have extra fields + (local.set $s-i31 (local.get $s-i31_any)) + ) + + ;; CHECK-TEXT: (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) + ;; CHECK-TEXT-NEXT: (local.set $rec-one + ;; CHECK-TEXT-NEXT: (local.get $rec-two) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) + ;; CHECK-BIN-NEXT: (local.set $rec-one + ;; CHECK-BIN-NEXT: (local.get $rec-two) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $coinductive (param $rec-one (ref $struct-rec-one)) + (param $rec-two (ref $struct-rec-two)) + ;; Do not infinitely recurse when determining this subtype relation! + (local.set $rec-one (local.get $rec-two)) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (sub (struct (field (ref $0))))) + +;; CHECK-BIN-NODEBUG: (type $1 (sub $0 (struct (field (ref $1)) (field (ref $1))))) + +;; CHECK-BIN-NODEBUG: (type $2 (array i32)) + +;; CHECK-BIN-NODEBUG: (type $3 (sub (struct (field (ref any))))) + +;; CHECK-BIN-NODEBUG: (type $4 (sub $3 (struct (field (ref i31))))) + +;; CHECK-BIN-NODEBUG: (type $5 (func (param (ref $2) (ref null $2)))) + +;; CHECK-BIN-NODEBUG: (type $6 (sub (array (ref any)))) + +;; CHECK-BIN-NODEBUG: (type $7 (sub $6 (array (ref i31)))) + +;; CHECK-BIN-NODEBUG: (type $8 (func (param (ref $7) (ref $6)))) + +;; CHECK-BIN-NODEBUG: (type $9 (func (param (ref $4) (ref $3)))) + +;; CHECK-BIN-NODEBUG: (type $10 (sub $4 (struct (field (ref i31)) (field (ref any))))) + +;; CHECK-BIN-NODEBUG: (type $11 (func (param (ref $4) (ref $10)))) + +;; CHECK-BIN-NODEBUG: (type $12 (func (param (ref $0) (ref $1)))) + +;; CHECK-BIN-NODEBUG: (func $0 (type $5) (param $0 (ref $2)) (param $1 (ref null $2)) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $8) (param $0 (ref $7)) (param $1 (ref $6)) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $9) (param $0 (ref $4)) (param $1 (ref $3)) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $11) (param $0 (ref $4)) (param $1 (ref $10)) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $12) (param $0 (ref $0)) (param $1 (ref $1)) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/table-import.wast b/test/lit/basic/table-import.wast new file mode 100644 index 00000000000..347da5634ff --- /dev/null +++ b/test/lit/basic/table-import.wast @@ -0,0 +1,45 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-BIN: (type $0 (func)) + ;; CHECK-BIN-NODEBUG: (type $0 (func)) + (type $0 (func)) + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 1 1 funcref)) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 1 1 funcref)) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 1 1 funcref)) + (import "env" "table" (table 1 1 funcref)) + (elem (i32.const 0) $foo) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (memory $0 0) + (memory $0 0) + + ;; CHECK-TEXT: (elem $0 (i32.const 0) $foo) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (elem $0 (i32.const 0) $foo) + + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo (type $0) + (nop) + ) +) +;; CHECK-BIN-NODEBUG: (elem $0 (i32.const 0) $0) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/tags.wast b/test/lit/basic/tags.wast new file mode 100644 index 00000000000..e6c5d2ccc50 --- /dev/null +++ b/test/lit/basic/tags.wast @@ -0,0 +1,91 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +;; Test tags + +(module + (tag (param i32)) + ;; CHECK-TEXT: (type $0 (func (param i32 f32))) + + ;; CHECK-TEXT: (type $1 (func (param i32))) + + ;; CHECK-TEXT: (type $2 (func)) + + ;; CHECK-TEXT: (import "env" "im0" (tag $e-import (param i32))) + + ;; CHECK-TEXT: (import "env" "im1" (tag $eimport$1 (param i32 f32))) + + ;; CHECK-TEXT: (tag $2 (param i32)) + + ;; CHECK-TEXT: (tag $e (param i32 f32)) + ;; CHECK-BIN: (type $0 (func (param i32 f32))) + + ;; CHECK-BIN: (type $1 (func (param i32))) + + ;; CHECK-BIN: (type $2 (func)) + + ;; CHECK-BIN: (import "env" "im0" (tag $e-import (param i32))) + + ;; CHECK-BIN: (import "env" "im1" (tag $eimport$1 (param i32 f32))) + + ;; CHECK-BIN: (tag $tag$0 (param i32)) + + ;; CHECK-BIN: (tag $e (param i32 f32)) + (tag $e (param i32 f32)) + ;; CHECK-TEXT: (tag $empty) + ;; CHECK-BIN: (tag $empty) + (tag $empty) + + ;; CHECK-TEXT: (tag $e-params0 (param i32 f32)) + ;; CHECK-BIN: (tag $e-params0 (param i32 f32)) + (tag $e-params0 (param i32 f32)) + ;; CHECK-TEXT: (tag $e-params1 (param i32 f32)) + ;; CHECK-BIN: (tag $e-params1 (param i32 f32)) + (tag $e-params1 (param i32) (param f32)) + + ;; CHECK-TEXT: (tag $e-export (param i32)) + ;; CHECK-BIN: (tag $e-export (param i32)) + (tag $e-export (export "ex0") (param i32)) + (tag $e-import (import "env" "im0") (param i32)) + + ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32 f32))) + + ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) + + ;; CHECK-BIN-NODEBUG: (type $2 (func)) + + ;; CHECK-BIN-NODEBUG: (import "env" "im0" (tag $eimport$0 (param i32))) + (import "env" "im1" (tag (param i32 f32))) + ;; CHECK-TEXT: (export "ex0" (tag $e-export)) + + ;; CHECK-TEXT: (export "ex1" (tag $e)) + ;; CHECK-BIN: (export "ex0" (tag $e-export)) + + ;; CHECK-BIN: (export "ex1" (tag $e)) + ;; CHECK-BIN-NODEBUG: (import "env" "im1" (tag $eimport$1 (param i32 f32))) + + ;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + + ;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i32 f32)) + + ;; CHECK-BIN-NODEBUG: (tag $tag$2) + + ;; CHECK-BIN-NODEBUG: (tag $tag$3 (param i32 f32)) + + ;; CHECK-BIN-NODEBUG: (tag $tag$4 (param i32 f32)) + + ;; CHECK-BIN-NODEBUG: (tag $tag$5 (param i32)) + + ;; CHECK-BIN-NODEBUG: (export "ex0" (tag $tag$5)) + + ;; CHECK-BIN-NODEBUG: (export "ex1" (tag $tag$1)) + (export "ex1" (tag $e)) +) diff --git a/test/lit/basic/unit.wat b/test/lit/basic/unit.wat new file mode 100644 index 00000000000..8392a226948 --- /dev/null +++ b/test/lit/basic/unit.wat @@ -0,0 +1,2293 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wat -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wat +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wat +;; RUN: cat %t.text.wat | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wat | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wat | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $5 (func (result i32))) + + ;; CHECK-TEXT: (type $FUNCSIG$v (func)) + + ;; CHECK-TEXT: (type $FUNCSIG$vf (func (param f32))) + ;; CHECK-BIN: (type $5 (func (result i32))) + + ;; CHECK-BIN: (type $FUNCSIG$v (func)) + + ;; CHECK-BIN: (type $FUNCSIG$vf (func (param f32))) + (type $FUNCSIG$vf (func (param f32))) + (type $FUNCSIG$v (func)) + ;; CHECK-TEXT: (type $4 (func (result f64))) + + ;; CHECK-TEXT: (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + + ;; CHECK-TEXT: (type $FUNCSIG$id (func (param f64) (result i32))) + ;; CHECK-BIN: (type $4 (func (result f64))) + + ;; CHECK-BIN: (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + + ;; CHECK-BIN: (type $FUNCSIG$id (func (param f64) (result i32))) + (type $FUNCSIG$id (func (param f64) (result i32))) + (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + + ;; CHECK-BIN-NODEBUG: (type $1 (func)) + + ;; CHECK-BIN-NODEBUG: (type $2 (func (param f32))) + + ;; CHECK-BIN-NODEBUG: (type $3 (func (result f64))) + + ;; CHECK-BIN-NODEBUG: (type $4 (func (param f64 f64) (result f64))) + (type $4 (func (result f64))) + ;; CHECK-BIN-NODEBUG: (type $5 (func (param f64) (result i32))) + (type $5 (func (result i32))) + ;; CHECK-TEXT: (type $6 (func (param i32) (result i32))) + ;; CHECK-BIN: (type $6 (func (param i32) (result i32))) + ;; CHECK-BIN-NODEBUG: (type $6 (func (param i32) (result i32))) + (type $6 (func (param i32) (result i32))) + ;; CHECK-TEXT: (type $7 (func (param f64) (result f64))) + ;; CHECK-BIN: (type $7 (func (param f64) (result f64))) + ;; CHECK-BIN-NODEBUG: (type $7 (func (param f64) (result f64))) + (type $7 (func (param f64) (result f64))) + ;; CHECK-TEXT: (type $8 (func (result i64))) + ;; CHECK-BIN: (type $8 (func (result i64))) + ;; CHECK-BIN-NODEBUG: (type $8 (func (result i64))) + (type $8 (func (result i64))) + ;; CHECK-TEXT: (type $9 (func (param i32 i64))) + ;; CHECK-BIN: (type $9 (func (param i32 i64))) + ;; CHECK-BIN-NODEBUG: (type $9 (func (param i32 i64))) + (type $9 (func (param i32 i64))) + ;; CHECK-TEXT: (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi (type $FUNCSIG$v))) + ;; CHECK-BIN: (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi (type $FUNCSIG$v))) + ;; CHECK-BIN-NODEBUG: (import "env" "_emscripten_asm_const_vi" (func $fimport$0 (type $1))) + (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) + ;; CHECK-TEXT: (import "asm2wasm" "f64-to-int" (func $f64-to-int (type $FUNCSIG$id) (param f64) (result i32))) + ;; CHECK-BIN: (import "asm2wasm" "f64-to-int" (func $f64-to-int (type $FUNCSIG$id) (param f64) (result i32))) + ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-to-int" (func $fimport$1 (type $5) (param f64) (result i32))) + (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) + ;; CHECK-TEXT: (import "asm2wasm" "f64-rem" (func $f64-rem (type $FUNCSIG$ddd) (param f64 f64) (result f64))) + ;; CHECK-BIN: (import "asm2wasm" "f64-rem" (func $f64-rem (type $FUNCSIG$ddd) (param f64 f64) (result f64))) + ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-rem" (func $fimport$2 (type $4) (param f64 f64) (result f64))) + (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) + (table 10 funcref) + (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + ;; CHECK-TEXT: (memory $0 4096 4096) + ;; CHECK-BIN: (memory $0 4096 4096) + ;; CHECK-BIN-NODEBUG: (memory $0 4096 4096) + (memory $0 4096 4096) + (data (i32.const 1026) "\14\00") + ;; CHECK-TEXT: (data $0 (i32.const 1026) "\14\00") + + ;; CHECK-TEXT: (table $0 10 funcref) + + ;; CHECK-TEXT: (elem $0 (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + + ;; CHECK-TEXT: (export "big_negative" (func $big_negative)) + ;; CHECK-BIN: (data $0 (i32.const 1026) "\14\00") + + ;; CHECK-BIN: (table $0 10 funcref) + + ;; CHECK-BIN: (elem $0 (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + + ;; CHECK-BIN: (export "big_negative" (func $big_negative)) + ;; CHECK-BIN-NODEBUG: (data $0 (i32.const 1026) "\14\00") + + ;; CHECK-BIN-NODEBUG: (table $0 10 funcref) + + ;; CHECK-BIN-NODEBUG: (elem $0 (i32.const 0) $17 $0 $17 $17 $18 $18 $1 $18 $17 $15) + + ;; CHECK-BIN-NODEBUG: (export "big_negative" (func $0)) + (export "big_negative" (func $big_negative)) + ;; CHECK-TEXT: (func $big_negative (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $temp f64) + ;; CHECK-TEXT-NEXT: (block $block0 + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.const -2147483648) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.const -2147483648) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.const -21474836480) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.const 0.039625) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.const -0.039625) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $big_negative (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $temp f64) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.const -2147483648) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.const -2147483648) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.const -21474836480) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.const 0.039625) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.const -0.039625) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $big_negative (type $FUNCSIG$v) + (local $temp f64) + (block $block0 + (local.set $temp + (f64.const -2147483648) + ) + (local.set $temp + (f64.const -2147483648) + ) + (local.set $temp + (f64.const -21474836480) + ) + (local.set $temp + (f64.const 0.039625) + ) + (local.set $temp + (f64.const -0.039625) + ) + ) + ) + ;; CHECK-TEXT: (func $importedDoubles (type $4) (result f64) + ;; CHECK-TEXT-NEXT: (local $temp f64) + ;; CHECK-TEXT-NEXT: (block $topmost (result f64) + ;; CHECK-TEXT-NEXT: (local.set $temp + ;; CHECK-TEXT-NEXT: (f64.add + ;; CHECK-TEXT-NEXT: (f64.add + ;; CHECK-TEXT-NEXT: (f64.add + ;; CHECK-TEXT-NEXT: (f64.load + ;; CHECK-TEXT-NEXT: (i32.const 8) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.load + ;; CHECK-TEXT-NEXT: (i32.const 16) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.neg + ;; CHECK-TEXT-NEXT: (f64.load + ;; CHECK-TEXT-NEXT: (i32.const 16) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.neg + ;; CHECK-TEXT-NEXT: (f64.load + ;; CHECK-TEXT-NEXT: (i32.const 8) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.gt_s + ;; CHECK-TEXT-NEXT: (i32.load + ;; CHECK-TEXT-NEXT: (i32.const 24) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (f64.gt + ;; CHECK-TEXT-NEXT: (f64.load + ;; CHECK-TEXT-NEXT: (i32.const 32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.const 1.2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $importedDoubles (type $4) (result f64) + ;; CHECK-BIN-NEXT: (local $temp f64) + ;; CHECK-BIN-NEXT: (block $label$1 (result f64) + ;; CHECK-BIN-NEXT: (local.set $temp + ;; CHECK-BIN-NEXT: (f64.add + ;; CHECK-BIN-NEXT: (f64.add + ;; CHECK-BIN-NEXT: (f64.add + ;; CHECK-BIN-NEXT: (f64.load + ;; CHECK-BIN-NEXT: (i32.const 8) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.load + ;; CHECK-BIN-NEXT: (i32.const 16) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.neg + ;; CHECK-BIN-NEXT: (f64.load + ;; CHECK-BIN-NEXT: (i32.const 16) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.neg + ;; CHECK-BIN-NEXT: (f64.load + ;; CHECK-BIN-NEXT: (i32.const 8) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.gt_s + ;; CHECK-BIN-NEXT: (i32.load + ;; CHECK-BIN-NEXT: (i32.const 24) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (f64.gt + ;; CHECK-BIN-NEXT: (f64.load + ;; CHECK-BIN-NEXT: (i32.const 32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.const 1.2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $importedDoubles (type $4) (result f64) + (local $temp f64) + (block $topmost (result f64) + (local.set $temp + (f64.add + (f64.add + (f64.add + (f64.load + (i32.const 8) + ) + (f64.load + (i32.const 16) + ) + ) + (f64.neg + (f64.load + (i32.const 16) + ) + ) + ) + (f64.neg + (f64.load + (i32.const 8) + ) + ) + ) + ) + (if + (i32.gt_s + (i32.load + (i32.const 24) + ) + (i32.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (f64.gt + (f64.load + (i32.const 32) + ) + (f64.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (f64.const 1.2) + ) + ) + ;; CHECK-TEXT: (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) + ;; CHECK-TEXT-NEXT: (local $t f64) + ;; CHECK-TEXT-NEXT: (local $Int f64) + ;; CHECK-TEXT-NEXT: (local $Double i32) + ;; CHECK-TEXT-NEXT: (block $topmost (result f64) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (f64.gt + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (f64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 1.2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (f64.gt + ;; CHECK-TEXT-NEXT: (local.get $Int) + ;; CHECK-TEXT-NEXT: (f64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.gt_s + ;; CHECK-TEXT-NEXT: (local.get $Double) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (f64.lt + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (local.get $y) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $y) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) + ;; CHECK-BIN-NEXT: (local $t f64) + ;; CHECK-BIN-NEXT: (local $Int f64) + ;; CHECK-BIN-NEXT: (local $Double i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result f64) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (f64.gt + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (f64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 1.2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (f64.gt + ;; CHECK-BIN-NEXT: (local.get $Int) + ;; CHECK-BIN-NEXT: (f64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.gt_s + ;; CHECK-BIN-NEXT: (local.get $Double) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (f64.lt + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (local.get $y) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $y) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) + (local $t f64) + (local $Int f64) + (local $Double i32) + (block $topmost (result f64) + (if + (f64.gt + (local.get $x) + (f64.const 0) + ) + (br $topmost + (f64.const 1.2) + ) + ) + (if + (f64.gt + (local.get $Int) + (f64.const 0) + ) + (br $topmost + (f64.const -3.4) + ) + ) + (if + (i32.gt_s + (local.get $Double) + (i32.const 0) + ) + (br $topmost + (f64.const 5.6) + ) + ) + (if + (f64.lt + (local.get $x) + (local.get $y) + ) + (br $topmost + (local.get $x) + ) + ) + (local.get $y) + ) + ) + ;; CHECK-TEXT: (func $intOps (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (local $x i32) + ;; CHECK-TEXT-NEXT: (i32.eq + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $intOps (type $5) (result i32) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (i32.eq + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $intOps (type $5) (result i32) + (local $x i32) + (i32.eq + (local.get $x) + (i32.const 0) + ) + ) + ;; CHECK-TEXT: (func $hexLiterals (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 313249263) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const -19088752) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $hexLiterals (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 313249263) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const -19088752) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $hexLiterals (type $FUNCSIG$v) + (drop + (i32.add + (i32.add + (i32.const 0) + (i32.const 313249263) + ) + (i32.const -19088752) + ) + ) + ) + ;; CHECK-TEXT: (func $conversions (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $i i32) + ;; CHECK-TEXT-NEXT: (local $d f64) + ;; CHECK-TEXT-NEXT: (block $block0 + ;; CHECK-TEXT-NEXT: (local.set $i + ;; CHECK-TEXT-NEXT: (call $f64-to-int + ;; CHECK-TEXT-NEXT: (local.get $d) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $d + ;; CHECK-TEXT-NEXT: (f64.convert_i32_s + ;; CHECK-TEXT-NEXT: (local.get $i) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $d + ;; CHECK-TEXT-NEXT: (f64.convert_i32_u + ;; CHECK-TEXT-NEXT: (i32.shr_u + ;; CHECK-TEXT-NEXT: (local.get $i) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $conversions (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $i i32) + ;; CHECK-BIN-NEXT: (local $d f64) + ;; CHECK-BIN-NEXT: (local.set $i + ;; CHECK-BIN-NEXT: (call $f64-to-int + ;; CHECK-BIN-NEXT: (local.get $d) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $d + ;; CHECK-BIN-NEXT: (f64.convert_i32_s + ;; CHECK-BIN-NEXT: (local.get $i) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $d + ;; CHECK-BIN-NEXT: (f64.convert_i32_u + ;; CHECK-BIN-NEXT: (i32.shr_u + ;; CHECK-BIN-NEXT: (local.get $i) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $conversions (type $FUNCSIG$v) + (local $i i32) + (local $d f64) + (block $block0 + (local.set $i + (call $f64-to-int + (local.get $d) + ) + ) + (local.set $d + (f64.convert_i32_s + (local.get $i) + ) + ) + (local.set $d + (f64.convert_i32_u + (i32.shr_u + (local.get $i) + (i32.const 0) + ) + ) + ) + ) + ) + ;; CHECK-TEXT: (func $seq (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $J f64) + ;; CHECK-TEXT-NEXT: (local.set $J + ;; CHECK-TEXT-NEXT: (f64.sub + ;; CHECK-TEXT-NEXT: (block $block0 (result f64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.const 0.1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.const 5.1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $block1 (result f64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f64.const 3.2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f64.const 4.2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $seq (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $J f64) + ;; CHECK-BIN-NEXT: (local.set $J + ;; CHECK-BIN-NEXT: (f64.sub + ;; CHECK-BIN-NEXT: (block $label$1 (result f64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.const 0.1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.const 5.1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$2 (result f64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f64.const 3.2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (f64.const 4.2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $seq (type $FUNCSIG$v) + (local $J f64) + (local.set $J + (f64.sub + (block $block0 (result f64) + (drop + (f64.const 0.1) + ) + (f64.const 5.1) + ) + (block $block1 (result f64) + (drop + (f64.const 3.2) + ) + (f64.const 4.2) + ) + ) + ) + ) + ;; CHECK-TEXT: (func $switcher (type $6) (param $x i32) (result i32) + ;; CHECK-TEXT-NEXT: (block $topmost (result i32) + ;; CHECK-TEXT-NEXT: (block $switch$0 + ;; CHECK-TEXT-NEXT: (block $switch-default$3 + ;; CHECK-TEXT-NEXT: (block $switch-case$2 + ;; CHECK-TEXT-NEXT: (block $switch-case$1 + ;; CHECK-TEXT-NEXT: (br_table $switch-case$1 $switch-case$2 $switch-default$3 + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $switch$4 + ;; CHECK-TEXT-NEXT: (block $switch-default$7 + ;; CHECK-TEXT-NEXT: (block $switch-case$6 + ;; CHECK-TEXT-NEXT: (block $switch-case$5 + ;; CHECK-TEXT-NEXT: (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.const 5) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 121) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (i32.const 51) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $label$break$Lout + ;; CHECK-TEXT-NEXT: (block $switch-default$16 + ;; CHECK-TEXT-NEXT: (block $switch-case$15 + ;; CHECK-TEXT-NEXT: (block $switch-case$12 + ;; CHECK-TEXT-NEXT: (block $switch-case$9 + ;; CHECK-TEXT-NEXT: (block $switch-case$8 + ;; CHECK-TEXT-NEXT: (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $label$break$Lout) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $label$break$Lout) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $while-out$10 + ;; CHECK-TEXT-NEXT: (loop $while-in$11 + ;; CHECK-TEXT-NEXT: (block $block1 + ;; CHECK-TEXT-NEXT: (br $while-out$10) + ;; CHECK-TEXT-NEXT: (br $while-in$11) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $label$break$Lout) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $while-out$13 + ;; CHECK-TEXT-NEXT: (loop $while-in$14 + ;; CHECK-TEXT-NEXT: (block $block3 + ;; CHECK-TEXT-NEXT: (br $label$break$Lout) + ;; CHECK-TEXT-NEXT: (br $while-in$14) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $label$break$Lout) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $switcher (type $6) (param $x i32) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (block $label$3 + ;; CHECK-BIN-NEXT: (block $label$4 + ;; CHECK-BIN-NEXT: (block $label$5 + ;; CHECK-BIN-NEXT: (br_table $label$5 $label$4 $label$3 + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$6 + ;; CHECK-BIN-NEXT: (block $label$7 + ;; CHECK-BIN-NEXT: (block $label$8 + ;; CHECK-BIN-NEXT: (block $label$9 + ;; CHECK-BIN-NEXT: (br_table $label$8 $label$7 $label$7 $label$7 $label$7 $label$7 $label$7 $label$9 $label$7 + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.const 5) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 121) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (i32.const 51) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$10 + ;; CHECK-BIN-NEXT: (block $label$11 + ;; CHECK-BIN-NEXT: (block $label$12 + ;; CHECK-BIN-NEXT: (block $label$13 + ;; CHECK-BIN-NEXT: (block $label$14 + ;; CHECK-BIN-NEXT: (block $label$15 + ;; CHECK-BIN-NEXT: (br_table $label$12 $label$11 $label$11 $label$13 $label$11 $label$11 $label$11 $label$11 $label$14 $label$11 $label$15 $label$11 + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$16 + ;; CHECK-BIN-NEXT: (loop $label$17 + ;; CHECK-BIN-NEXT: (br $label$16) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$18 + ;; CHECK-BIN-NEXT: (loop $label$19 + ;; CHECK-BIN-NEXT: (br $label$10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $switcher (type $6) (param $x i32) (result i32) + (block $topmost (result i32) + (block $switch$0 + (block $switch-default$3 + (block $switch-case$2 + (block $switch-case$1 + (br_table $switch-case$1 $switch-case$2 $switch-default$3 + (i32.sub + (local.get $x) + (i32.const 1) + ) + ) + ) + (br $topmost + (i32.const 1) + ) + ) + (br $topmost + (i32.const 2) + ) + ) + (nop) + ) + (block $switch$4 + (block $switch-default$7 + (block $switch-case$6 + (block $switch-case$5 + (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 + (i32.sub + (local.get $x) + (i32.const 5) + ) + ) + ) + (br $topmost + (i32.const 121) + ) + ) + (br $topmost + (i32.const 51) + ) + ) + (nop) + ) + (block $label$break$Lout + (block $switch-default$16 + (block $switch-case$15 + (block $switch-case$12 + (block $switch-case$9 + (block $switch-case$8 + (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 + (i32.sub + (local.get $x) + (i32.const 2) + ) + ) + ) + (br $label$break$Lout) + ) + (br $label$break$Lout) + ) + (block $while-out$10 + (loop $while-in$11 + (block $block1 + (br $while-out$10) + (br $while-in$11) + ) + ) + (br $label$break$Lout) + ) + ) + (block $while-out$13 + (loop $while-in$14 + (block $block3 + (br $label$break$Lout) + (br $while-in$14) + ) + ) + (br $label$break$Lout) + ) + ) + (nop) + ) + (i32.const 0) + ) + ) + ;; CHECK-TEXT: (func $blocker (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (block $label$break$L + ;; CHECK-TEXT-NEXT: (br $label$break$L) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $blocker (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $blocker (type $FUNCSIG$v) + (block $label$break$L + (br $label$break$L) + ) + ) + ;; CHECK-TEXT: (func $frem (type $4) (result f64) + ;; CHECK-TEXT-NEXT: (call $f64-rem + ;; CHECK-TEXT-NEXT: (f64.const 5.5) + ;; CHECK-TEXT-NEXT: (f64.const 1.2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $frem (type $4) (result f64) + ;; CHECK-BIN-NEXT: (call $f64-rem + ;; CHECK-BIN-NEXT: (f64.const 5.5) + ;; CHECK-BIN-NEXT: (f64.const 1.2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $frem (type $4) (result f64) + (call $f64-rem + (f64.const 5.5) + (f64.const 1.2) + ) + ) + ;; CHECK-TEXT: (func $big_uint_div_u (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (local $x i32) + ;; CHECK-TEXT-NEXT: (block $topmost (result i32) + ;; CHECK-TEXT-NEXT: (local.set $x + ;; CHECK-TEXT-NEXT: (i32.and + ;; CHECK-TEXT-NEXT: (i32.div_u + ;; CHECK-TEXT-NEXT: (i32.const -1) + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const -1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $big_uint_div_u (type $5) (result i32) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (i32.and + ;; CHECK-BIN-NEXT: (i32.div_u + ;; CHECK-BIN-NEXT: (i32.const -1) + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const -1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + (func $big_uint_div_u (type $5) (result i32) + (local $x i32) + (block $topmost (result i32) + (local.set $x + (i32.and + (i32.div_u + (i32.const -1) + (i32.const 2) + ) + (i32.const -1) + ) + ) + (local.get $x) + ) + ) + ;; CHECK-TEXT: (func $fr (type $FUNCSIG$vf) (param $x f32) + ;; CHECK-TEXT-NEXT: (local $y f32) + ;; CHECK-TEXT-NEXT: (local $z f64) + ;; CHECK-TEXT-NEXT: (block $block0 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.demote_f64 + ;; CHECK-TEXT-NEXT: (local.get $z) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (local.get $y) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.const 5) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.const 5) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (f32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $fr (type $FUNCSIG$vf) (param $x f32) + ;; CHECK-BIN-NEXT: (local $y f32) + ;; CHECK-BIN-NEXT: (local $z f64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.demote_f64 + ;; CHECK-BIN-NEXT: (local.get $z) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (local.get $y) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 5) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 5) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $fr (type $FUNCSIG$vf) (param $x f32) + (local $y f32) + (local $z f64) + (block $block0 + (drop + (f32.demote_f64 + (local.get $z) + ) + ) + (drop + (local.get $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + ) + ) + ;; CHECK-TEXT: (func $negZero (type $4) (result f64) + ;; CHECK-TEXT-NEXT: (f64.const -0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $negZero (type $4) (result f64) + ;; CHECK-BIN-NEXT: (f64.const -0) + ;; CHECK-BIN-NEXT: ) + (func $negZero (type $4) (result f64) + (f64.const -0) + ) + ;; CHECK-TEXT: (func $abs (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $x i32) + ;; CHECK-TEXT-NEXT: (local $y f64) + ;; CHECK-TEXT-NEXT: (local $z f32) + ;; CHECK-TEXT-NEXT: (local $asm2wasm_i32_temp i32) + ;; CHECK-TEXT-NEXT: (block $block0 + ;; CHECK-TEXT-NEXT: (local.set $x + ;; CHECK-TEXT-NEXT: (block $block1 (result i32) + ;; CHECK-TEXT-NEXT: (local.set $asm2wasm_i32_temp + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (select + ;; CHECK-TEXT-NEXT: (i32.sub + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-TEXT-NEXT: (i32.lt_s + ;; CHECK-TEXT-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $y + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (f64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.set $z + ;; CHECK-TEXT-NEXT: (f32.abs + ;; CHECK-TEXT-NEXT: (f32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $abs (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (local $asm2wasm_i32_temp i32) + ;; CHECK-BIN-NEXT: (local $y f64) + ;; CHECK-BIN-NEXT: (local $z f32) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (local.set $asm2wasm_i32_temp + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (select + ;; CHECK-BIN-NEXT: (i32.sub + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-BIN-NEXT: (i32.lt_s + ;; CHECK-BIN-NEXT: (local.get $asm2wasm_i32_temp) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $y + ;; CHECK-BIN-NEXT: (f64.abs + ;; CHECK-BIN-NEXT: (f64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $z + ;; CHECK-BIN-NEXT: (f32.abs + ;; CHECK-BIN-NEXT: (f32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $abs (type $FUNCSIG$v) + (local $x i32) + (local $y f64) + (local $z f32) + (local $asm2wasm_i32_temp i32) + (block $block0 + (local.set $x + (block $block1 (result i32) + (local.set $asm2wasm_i32_temp + (i32.const 0) + ) + (select + (i32.sub + (i32.const 0) + (local.get $asm2wasm_i32_temp) + ) + (local.get $asm2wasm_i32_temp) + (i32.lt_s + (local.get $asm2wasm_i32_temp) + (i32.const 0) + ) + ) + ) + ) + (local.set $y + (f64.abs + (f64.const 0) + ) + ) + (local.set $z + (f32.abs + (f32.const 0) + ) + ) + ) + ) + ;; CHECK-TEXT: (func $neg (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $x f32) + ;; CHECK-TEXT-NEXT: (block $block0 + ;; CHECK-TEXT-NEXT: (local.set $x + ;; CHECK-TEXT-NEXT: (f32.neg + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $FUNCSIG$vf) + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (i32.and + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (i32.const 7) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 8) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $neg (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $x f32) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (f32.neg + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $FUNCSIG$vf) + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (i32.and + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (i32.const 7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 8) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $neg (type $FUNCSIG$v) + (local $x f32) + (block $block0 + (local.set $x + (f32.neg + (local.get $x) + ) + ) + (call_indirect (type $FUNCSIG$vf) + (local.get $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + ) + ;; CHECK-TEXT: (func $cneg (type $FUNCSIG$vf) (param $x f32) + ;; CHECK-TEXT-NEXT: (call_indirect $0 (type $FUNCSIG$vf) + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (i32.add + ;; CHECK-TEXT-NEXT: (i32.and + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (i32.const 7) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 8) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $cneg (type $FUNCSIG$vf) (param $x f32) + ;; CHECK-BIN-NEXT: (call_indirect $0 (type $FUNCSIG$vf) + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (i32.add + ;; CHECK-BIN-NEXT: (i32.and + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (i32.const 7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 8) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $cneg (type $FUNCSIG$vf) (param $x f32) + (call_indirect (type $FUNCSIG$vf) + (local.get $x) + (i32.add + (i32.and + (i32.const 1) + (i32.const 7) + ) + (i32.const 8) + ) + ) + ) + ;; CHECK-TEXT: (func $___syscall_ret (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (local $$0 i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.gt_u + ;; CHECK-TEXT-NEXT: (i32.shr_u + ;; CHECK-TEXT-NEXT: (local.get $$0) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const -4096) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $___syscall_ret (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (local $$0 i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.gt_u + ;; CHECK-BIN-NEXT: (i32.shr_u + ;; CHECK-BIN-NEXT: (local.get $$0) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const -4096) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $___syscall_ret (type $FUNCSIG$v) + (local $$0 i32) + (drop + (i32.gt_u + (i32.shr_u + (local.get $$0) + (i32.const 0) + ) + (i32.const -4096) + ) + ) + ) + ;; CHECK-TEXT: (func $z (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $z (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $z (type $FUNCSIG$v) + (nop) + ) + ;; CHECK-TEXT: (func $w (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $w (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $w (type $FUNCSIG$v) + (nop) + ) + ;; CHECK-TEXT: (func $block_and_after (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (block $waka + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $waka) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $block_and_after (type $5) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + (func $block_and_after (type $5) (result i32) + (block $waka + (drop + (i32.const 1) + ) + (br $waka) + ) + (i32.const 0) + ) + ;; CHECK-TEXT: (func $loop-roundtrip (type $7) (param $0 f64) (result f64) + ;; CHECK-TEXT-NEXT: (loop $loop-in1 (result f64) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $loop-roundtrip (type $7) (param $0 f64) (result f64) + ;; CHECK-BIN-NEXT: (loop $label$1 (result f64) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $loop-roundtrip (type $7) (param $0 f64) (result f64) + (loop $loop-in1 (result f64) + (drop + (local.get $0) + ) + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $big-i64 (type $8) (result i64) + ;; CHECK-TEXT-NEXT: (i64.const -9218868437227405313) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $big-i64 (type $8) (result i64) + ;; CHECK-BIN-NEXT: (i64.const -9218868437227405313) + ;; CHECK-BIN-NEXT: ) + (func $big-i64 (type $8) (result i64) + (i64.const -9218868437227405313) + ) + ;; CHECK-TEXT: (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) + ;; CHECK-TEXT-NEXT: (i64.store32 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) + ;; CHECK-BIN-NEXT: (i64.store32 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) + (i64.store32 + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $return-unreachable (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $return-unreachable (type $5) (result i32) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $return-unreachable (result i32) + (return (i32.const 1)) + ) + ;; CHECK-TEXT: (func $unreachable-block (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-block (type $5) (result i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-block (result i32) + (f64.abs + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (drop (i32.const 1)) + (return (i32.const 2)) + ) + ) + ) + ;; CHECK-TEXT: (func $unreachable-block-toplevel (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-block-toplevel (type $5) (result i32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-block-toplevel (result i32) + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (drop (i32.const 1)) + (return (i32.const 2)) + ) + ) + ;; CHECK-TEXT: (func $unreachable-block0 (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-block0 (type $5) (result i32) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-block0 (result i32) + (f64.abs + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 2)) + ) + ) + ) + ;; CHECK-TEXT: (func $unreachable-block0-toplevel (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-block0-toplevel (type $5) (result i32) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-block0-toplevel (result i32) + (block ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 2)) + ) + ) + ;; CHECK-TEXT: (func $unreachable-block-with-br (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (block $block + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $block) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-block-with-br (type $5) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-block-with-br (result i32) + (block $block ;; unreachable type due to last element having that type, but the block is exitable + (drop (i32.const 1)) + (br $block) + ) + (i32.const 1) + ) + ;; CHECK-TEXT: (func $unreachable-if (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-if (type $5) (result i32) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-if (result i32) + (f64.abs + (if ;; note no type - valid in binaryen IR, in wasm must be i32 + (i32.const 3) + (return (i32.const 2)) + (return (i32.const 1)) + ) + ) + ) + ;; CHECK-TEXT: (func $unreachable-if-toplevel (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-if-toplevel (type $5) (result i32) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-if-toplevel (result i32) + (if ;; note no type - valid in binaryen IR, in wasm must be i32 + (i32.const 3) + (return (i32.const 2)) + (return (i32.const 1)) + ) + ) + ;; CHECK-TEXT: (func $unreachable-loop (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (loop $loop-in + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-loop (type $5) (result i32) + ;; CHECK-BIN-NEXT: (loop $label$1 + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-loop (result i32) + (f64.abs + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (nop) + (return (i32.const 1)) + ) + ) + ) + ;; CHECK-TEXT: (func $unreachable-loop0 (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (f64.abs + ;; CHECK-TEXT-NEXT: (loop $loop-in + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-loop0 (type $5) (result i32) + ;; CHECK-BIN-NEXT: (loop $label$1 + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-loop0 (result i32) + (f64.abs + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 1)) + ) + ) + ) + ;; CHECK-TEXT: (func $unreachable-loop-toplevel (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (loop $loop-in + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-loop-toplevel (type $5) (result i32) + ;; CHECK-BIN-NEXT: (loop $label$1 + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-loop-toplevel (result i32) + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (nop) + (return (i32.const 1)) + ) + ) + ;; CHECK-TEXT: (func $unreachable-loop0-toplevel (type $5) (result i32) + ;; CHECK-TEXT-NEXT: (loop $loop-in + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-loop0-toplevel (type $5) (result i32) + ;; CHECK-BIN-NEXT: (loop $label$1 + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-loop0-toplevel (result i32) + (loop ;; note no type - valid in binaryen IR, in wasm must be i32 + (return (i32.const 1)) + ) + ) + ;; CHECK-TEXT: (func $unreachable-ifs (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-ifs (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-ifs + (if (unreachable) (nop)) + (if (unreachable) (unreachable)) + (if (unreachable) (nop) (nop)) + (if (unreachable) (unreachable) (nop)) + (if (unreachable) (nop) (unreachable)) + (if (unreachable) (unreachable) (unreachable)) + ;; + (if (i32.const 1) (unreachable) (nop)) + (if (i32.const 1) (nop) (unreachable)) + (if (i32.const 1) (unreachable) (unreachable)) + ) + ;; CHECK-TEXT: (func $unreachable-if-arm (type $FUNCSIG$v) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $unreachable-if-arm (type $FUNCSIG$v) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $unreachable-if-arm + (if + (i32.const 1) + (block + (nop) + ) + (block + (unreachable) + (drop + (i32.const 1) + ) + ) + ) + ) +) +;; CHECK-BIN-NODEBUG: (func $0 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -2147483648) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -2147483648) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -21474836480) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0.039625) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -0.039625) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $3) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 f64) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.add +;; CHECK-BIN-NODEBUG-NEXT: (f64.add +;; CHECK-BIN-NODEBUG-NEXT: (f64.add +;; CHECK-BIN-NODEBUG-NEXT: (f64.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 8) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 16) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.neg +;; CHECK-BIN-NODEBUG-NEXT: (f64.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 16) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.neg +;; CHECK-BIN-NODEBUG-NEXT: (f64.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 8) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (i32.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 24) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (f64.gt +;; CHECK-BIN-NODEBUG-NEXT: (f64.load +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $4) (param $0 f64) (param $1 f64) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local $4 i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (f64.gt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (f64.gt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.gt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $4) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (f64.lt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 313249263) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const -19088752) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (call $fimport$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i32_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.convert_i32_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f64.sub +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0.1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 3.2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 4.2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $6) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$5 $label$4 $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$8 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$9 +;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$8 $label$7 $label$7 $label$7 $label$7 $label$7 $label$7 $label$9 $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 5) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 121) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 51) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$11 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$12 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$13 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$14 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$15 +;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$12 $label$11 $label$11 $label$13 $label$11 $label$11 $label$11 $label$11 $label$14 $label$11 $label$15 $label$11 +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$16 +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$17 +;; CHECK-BIN-NODEBUG-NEXT: (br $label$16) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$18 +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$19 +;; CHECK-BIN-NODEBUG-NEXT: (br $label$10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $3) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (call $fimport$2 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.5) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.and +;; CHECK-BIN-NODEBUG-NEXT: (i32.div_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.const -1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const -1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $2) (param $0 f32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 f32) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 f64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.demote_f64 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 5) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 5) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $3) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 f64) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 f32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (select +;; CHECK-BIN-NODEBUG-NEXT: (i32.sub +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.lt_s +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (f64.abs +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 +;; CHECK-BIN-NODEBUG-NEXT: (f32.abs +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 f32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (f32.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (i32.and +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 8) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $2) (param $0 f32) +;; CHECK-BIN-NODEBUG-NEXT: (call_indirect $0 (type $2) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.add +;; CHECK-BIN-NODEBUG-NEXT: (i32.and +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 8) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.gt_u +;; CHECK-BIN-NODEBUG-NEXT: (i32.shr_u +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const -4096) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $7) (param $0 f64) (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$1 (result f64) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $8) (result i64) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const -9218868437227405313) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $9) (param $0 i32) (param $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (i64.store32 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $24 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $25 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $26 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $27 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $28 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $29 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $30 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $31 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $32 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $33 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $34 (type $0) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (loop $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $35 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $36 (type $1) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/unreachable-code.wast b/test/lit/basic/unreachable-code.wast new file mode 100644 index 00000000000..16ec691a56e --- /dev/null +++ b/test/lit/basic/unreachable-code.wast @@ -0,0 +1,355 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (func $a (type $0) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (func $a (type $0) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $a + (if (i32.const 1) + (unreachable) + ) + ) + + ;; CHECK-TEXT: (func $b (type $0) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $b (type $0) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $b + (if (i32.const 1) + (unreachable) + (unreachable) + ) + ) + + ;; CHECK-TEXT: (func $a-block (type $0) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $a-block (type $0) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $a-block + (block + (if (i32.const 1) + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $b-block (type $0) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $b-block (type $0) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $b-block + (block + (if (i32.const 1) + (unreachable) + (unreachable) + ) + ) + ) + + ;; CHECK-TEXT: (func $a-prepost (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $a-prepost (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $a-prepost + (nop) + (if (i32.const 1) + (unreachable) + ) + (nop) + ) + + ;; CHECK-TEXT: (func $b-prepost (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $b-prepost (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $b-prepost + (nop) + (if (i32.const 1) + (unreachable) + (unreachable) + ) + (nop) + ) + + ;; CHECK-TEXT: (func $a-block-prepost (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $a-block-prepost (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $a-block-prepost + (nop) + (block + (if (i32.const 1) + (unreachable) + ) + ) + (nop) + ) + + ;; CHECK-TEXT: (func $b-block-prepost (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $b-block-prepost (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $b-block-prepost + (nop) + (block + (if (i32.const 1) + (unreachable) + (unreachable) + ) + ) + (nop) + ) + + ;; CHECK-TEXT: (func $recurse (type $0) + ;; CHECK-TEXT-NEXT: (block $a + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (block $b + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (br $b) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $recurse (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $recurse + (block $a + (nop) + (block $b + (nop) + (br $b) + (nop) + ) + (nop) + ) + ) + + ;; CHECK-TEXT: (func $recurse-b (type $0) + ;; CHECK-TEXT-NEXT: (block $a + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (block $b + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (br $a) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $recurse-b (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $recurse-b + (block $a + (nop) + (block $b + (nop) + (br $a) + (nop) + ) + (nop) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/unreachable-instr-type.wast b/test/lit/basic/unreachable-instr-type.wast new file mode 100644 index 00000000000..ff6df8bac03 --- /dev/null +++ b/test/lit/basic/unreachable-instr-type.wast @@ -0,0 +1,81 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (memory (shared 1 1)) + + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (memory $0 (shared 1 1)) + + ;; CHECK-TEXT: (func $test (type $0) + ;; CHECK-TEXT-NEXT: (i32.load + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (f32.store + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (f32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.add + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (i32.atomic.rmw.cmpxchg + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: (i64.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (memory.atomic.wait64 + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (memory $0 (shared 1 1)) + + ;; CHECK-BIN: (func $test (type $0) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + (func $test + (f32.load (unreachable)) + + (f32.store + (unreachable) + (f32.const 0) + ) + + (i64.atomic.rmw.add + (unreachable) + (i64.const 0) + ) + + (i64.atomic.rmw.cmpxchg + (unreachable) + (i64.const 0) + (i64.const 1) + ) + + (memory.atomic.wait64 + (unreachable) + (i64.const 0) + (i64.const 0) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (memory $0 (shared 1 1)) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/untaken-br_if.wast b/test/lit/basic/untaken-br_if.wast new file mode 100644 index 00000000000..23063d79623 --- /dev/null +++ b/test/lit/basic/untaken-br_if.wast @@ -0,0 +1,67 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func (result f32))) + + ;; CHECK-TEXT: (func $binaryify-untaken-br_if (type $0) (result f32) + ;; CHECK-TEXT-NEXT: (if (result f32) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (block $label$1 (result f32) + ;; CHECK-TEXT-NEXT: (br_if $label$1 + ;; CHECK-TEXT-NEXT: (f32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func (result f32))) + + ;; CHECK-BIN: (func $binaryify-untaken-br_if (type $0) (result f32) + ;; CHECK-BIN-NEXT: (if (result f32) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (block $label$3 (result f32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $binaryify-untaken-br_if (result f32) + (if (result f32) + (i32.const 1) + (unreachable) + (block $label$1 (result f32) + (br_if $label$1 + (f32.const 1) + (unreachable) + ) + ) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (result f32))) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (if (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/multi-memories-atomics64.wast b/test/lit/multi-memories-atomics64.wast deleted file mode 100644 index 15941b12a87..00000000000 --- a/test/lit/multi-memories-atomics64.wast +++ /dev/null @@ -1,704 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; RUN: wasm-as %s -all -g -o %t.wasm -;; RUN: wasm-dis %t.wasm -o - | filecheck %s - -(module - ;; CHECK: (type $0 (func)) - (type $0 (func)) - ;; CHECK: (memory $appMemory (shared i64 23 256)) - (memory $appMemory (shared i64 23 256)) - ;; CHECK: (memory $dataMemory (shared i64 23 256)) - (memory $dataMemory (shared i64 23 256)) - ;; CHECK: (memory $instrumentMemory (shared i64 23 256)) - (memory $instrumentMemory (shared i64 23 256)) - ;; CHECK: (func $atomic-loadstore - ;; CHECK-NEXT: (local $0 i64) - ;; CHECK-NEXT: (local $1 i64) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load8_u $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load8_u $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load16_u $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load16_u $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.load $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load8_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load8_u $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load16_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load16_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load32_u $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load32_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.load $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store8 $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store8 $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store16 $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.store16 $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store8 $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store8 $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store16 $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store16 $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store32 $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store32 $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u 0 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u 1 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $instrumentMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load 1 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $dataMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u 2 - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load - (local.get $0) - ) - ) - (drop - (i64.atomic.load $instrumentMemory - (local.get $0) - ) - ) - (i32.atomic.store 0 offset=4 align=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store $appMemory offset=4 align=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 2 offset=4 align=1 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $dataMemory offset=4 align=1 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 0 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 1 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 2 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $atomic-rmw - ;; CHECK-NEXT: (local $0 i64) - ;; CHECK-NEXT: (local $1 i64) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw.add $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw.add $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.add_u $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw16.and_u $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw16.and_u $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw32.or_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw32.or_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.xchg_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.xchg_u $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.add 2 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u 0 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u 1 align=2 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $instrumentMemory align=2 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u 0 - (local.get $0) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u 0 align=1 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $dataMemory align=1 - (local.get $0) - (local.get $2) - ) - ) - ) - ;; CHECK: (func $atomic-cmpxchg - ;; CHECK-NEXT: (local $0 i64) - ;; CHECK-NEXT: (local $1 i64) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw.cmpxchg $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u $appMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw.cmpxchg $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw.cmpxchg $dataMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw32.cmpxchg_u $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.atomic.rmw32.cmpxchg_u $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg 0 offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $dataMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u 2 align=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $dataMemory align=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - ;; CHECK: (func $atomic-wait-notify - ;; CHECK-NEXT: (local $0 i64) - ;; CHECK-NEXT: (local $1 i64) - ;; CHECK-NEXT: (local $2 i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait32 $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait32 $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait32 $appMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait32 $instrumentMemory offset=4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.notify $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.notify $dataMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.notify $appMemory offset=24 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.notify $dataMemory offset=24 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait64 $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait64 $instrumentMemory - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait64 $appMemory offset=16 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.atomic.wait64 $appMemory offset=16 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 $dataMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 2 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $appMemory offset=4 align=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 2 offset=4 align=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify 1 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $appMemory offset=24 align=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify 1 offset=24 align=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 2 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory align=8 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 0 align=8 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - ;; CHECK: (func $atomic-fence - ;; CHECK-NEXT: (atomic.fence) - ;; CHECK-NEXT: ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/lit/multi-memories-basics.wast b/test/lit/multi-memories-basics.wast deleted file mode 100644 index b4d29f8b7be..00000000000 --- a/test/lit/multi-memories-basics.wast +++ /dev/null @@ -1,176 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; RUN: wasm-as %s -all -g -o %t.wasm -;; RUN: wasm-dis %t.wasm -o - | filecheck %s - -(module - ;; CHECK: (import "env" "memory" (memory $importedMemory 1 1)) - - ;; CHECK: (memory $memory1 1 500) - (memory $memory1 1 500) - ;; CHECK: (memory $memory2 1 800) - (memory $memory2 1 800) - ;; CHECK: (memory $memory3 1 400) - (memory $memory3 1 400) - ;; CHECK: (data $data1 (memory $memory1) (i32.const 0) "abcd") - (data $data1 (memory $memory1) (i32.const 0) "a" "" "bcd") - ;; CHECK: (data $data2 (memory $memory2) (i32.const 9) "w") - (data $data2 (memory $memory2) (i32.const 9) "w") - (import "env" "memory" (memory $importedMemory 1 1)) - ;; CHECK: (func $memory.fill - ;; CHECK-NEXT: (memory.fill $memory2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $memory.fill - (memory.fill 1 - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) - ) - ;; CHECK: (func $memory.copy - ;; CHECK-NEXT: (memory.copy $memory2 $memory3 - ;; CHECK-NEXT: (i32.const 512) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $memory.copy - (memory.copy 1 2 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - ;; CHECK: (func $memory.init - ;; CHECK-NEXT: (memory.init $memory1 $data1 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 45) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $memory.init - (memory.init 0 0 - (i32.const 0) - (i32.const 0) - (i32.const 45) - ) - ) - ;; CHECK: (func $memory.grow (result i32) - ;; CHECK-NEXT: (memory.grow $memory3 - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $memory.grow (result i32) - (memory.grow 2 - (i32.const 10) - ) - ) - ;; CHECK: (func $memory.size (result i32) - ;; CHECK-NEXT: (memory.size $memory3) - ;; CHECK-NEXT: ) - (func $memory.size (result i32) - (memory.size 2) - ) - ;; CHECK: (func $loads - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load $memory1 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load $memory3 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load16_s $memory2 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load16_s $memory2 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load8_s $memory3 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load8_s $memory3 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load16_u $memory1 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load16_u $memory1 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load8_u $memory2 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load8_u $memory2 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $loads - (drop (i32.load 0 (i32.const 12))) - (drop (i32.load $memory3 (i32.const 12))) - (drop (i32.load16_s 1 (i32.const 12))) - (drop (i32.load16_s $memory2 (i32.const 12))) - (drop (i32.load8_s 2 (i32.const 12))) - (drop (i32.load8_s $memory3 (i32.const 12))) - (drop (i32.load16_u 0 (i32.const 12))) - (drop (i32.load16_u $memory1 (i32.const 12))) - (drop (i32.load8_u 1 (i32.const 12))) - (drop (i32.load8_u $memory2 (i32.const 12))) - ) - ;; CHECK: (func $stores - ;; CHECK-NEXT: (i32.store $memory1 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: (i32.const 115) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store $memory1 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: (i32.const 115) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store16 $memory2 - ;; CHECK-NEXT: (i32.const 20) - ;; CHECK-NEXT: (i32.const 31353) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store16 $importedMemory - ;; CHECK-NEXT: (i32.const 20) - ;; CHECK-NEXT: (i32.const 31353) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 $memory3 - ;; CHECK-NEXT: (i32.const 23) - ;; CHECK-NEXT: (i32.const 120) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 $memory3 - ;; CHECK-NEXT: (i32.const 23) - ;; CHECK-NEXT: (i32.const 120) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $stores - (i32.store 0 (i32.const 12) (i32.const 115)) - (i32.store $memory1 (i32.const 12) (i32.const 115)) - (i32.store16 1 (i32.const 20) (i32.const 31353)) - (i32.store16 $importedMemory (i32.const 20) (i32.const 31353)) - (i32.store8 2 (i32.const 23) (i32.const 120)) - (i32.store8 $memory3 (i32.const 23) (i32.const 120)) - ) -) - diff --git a/test/lit/multi-memories-simd.wast b/test/lit/multi-memories-simd.wast deleted file mode 100644 index 184d98876fe..00000000000 --- a/test/lit/multi-memories-simd.wast +++ /dev/null @@ -1,635 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; RUN: wasm-as %s -all -g -o %t.wasm -;; RUN: wasm-dis %t.wasm -o - | filecheck %s - -(module - ;; CHECK: (memory $memorya 1 1) - (memory $memorya 1 1) - ;; CHECK: (memory $memoryb 1 1) - (memory $memoryb 1 1) - ;; CHECK: (memory $memoryc 1 1) - (memory $memoryc 1 1) - ;; CHECK: (memory $memoryd 1 1) - (memory $memoryd 1 1) - ;; CHECK: (func $v128.load (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load (param $0 i32) (result v128) - (v128.load offset=0 align=16 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load2 (param $0 i32) (result v128) - (v128.load $memoryb offset=0 align=16 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8x8_s (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8x8_s $memoryc - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8x8_s (param $0 i32) (result v128) - (v128.load8x8_s 2 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8x8_s2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8x8_s $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8x8_s2 (param $0 i32) (result v128) - (v128.load8x8_s 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8x8_u (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8x8_u $memoryd - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8x8_u (param $0 i32) (result v128) - (v128.load8x8_u 3 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8x8_u2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8x8_u $memoryd - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8x8_u2 (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16x4_s (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16x4_s $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16x4_s (param $0 i32) (result v128) - (v128.load16x4_s 0 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16x4_s2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16x4_s $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16x4_s2 (param $0 i32) (result v128) - (v128.load16x4_s $memoryb - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16x4_u (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16x4_u $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16x4_u (param $0 i32) (result v128) - (v128.load16x4_u 0 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16x4_u2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16x4_u $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16x4_u2 (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32x2_s (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32x2_s $memoryc - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32x2_s (param $0 i32) (result v128) - (v128.load32x2_s 2 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32x2_s2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32x2_s $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32x2_s2 (param $0 i32) (result v128) - (v128.load32x2_s $memoryb - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32x2_u (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32x2_u $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32x2_u (param $0 i32) (result v128) - (v128.load32x2_u 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32x2_u2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32x2_u $memoryc - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32x2_u2 (param $0 i32) (result v128) - (v128.load32x2_u $memoryc - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8_splat (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8_splat $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8_splat (param $0 i32) (result v128) - (v128.load8_splat 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load8_splat2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load8_splat $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8_splat2 (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16_splat (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16_splat $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16_splat (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load16_splat2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load16_splat $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16_splat2 (param $0 i32) (result v128) - (v128.load16_splat 0 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32_splat (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32_splat $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_splat (param $0 i32) (result v128) - (v128.load32_splat 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32_splat2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32_splat $memoryd - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_splat2 (param $0 i32) (result v128) - (v128.load32_splat $memoryd - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load64_splat (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load64_splat $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_splat (param $0 i32) (result v128) - (v128.load64_splat 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load64_splat2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load64_splat $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_splat2 (param $0 i32) (result v128) - (v128.load64_splat $memorya - (local.get $0) - ) - ) - ;; CHECK: (func $v128.store (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store (param $0 i32) (param $1 v128) - (v128.store 0 offset=0 align=16 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store2 (param $0 i32) (param $1 v128) - (v128.store 1 offset=0 align=16 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load8_lane $memorya 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane 0 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load8_lane2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load8_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load8_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load16_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane 1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load16_lane2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load16_lane $memoryd 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load16_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load32_lane $memorya 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load32_lane2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load32_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane 1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryd 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memorya align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 0 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_align2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryb align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_align2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryc offset=32 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 2 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_offset2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryb offset=32 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_offset2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memorya offset=32 align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load64_lane_align_offset2 (param $0 i32) (param $1 v128) (result v128) - ;; CHECK-NEXT: (v128.load64_lane $memoryd offset=32 align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_lane_align_offset2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store8_lane (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store8_lane $memorya 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store8_lane (param $0 i32) (param $1 v128) - (v128.store8_lane 0 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store8_lane2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store8_lane $memoryd 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store8_lane2 (param $0 i32) (param $1 v128) - (v128.store8_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store16_lane (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store16_lane $memorya 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store16_lane (param $0 i32) (param $1 v128) - (v128.store16_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store16_lane2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store16_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store16_lane2 (param $0 i32) (param $1 v128) - (v128.store16_lane 1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store32_lane (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store32_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store32_lane (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store32_lane2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store32_lane $memoryc 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store32_lane2 (param $0 i32) (param $1 v128) - (v128.store32_lane 2 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryc 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryb 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane2 (param $0 i32) (param $1 v128) - (v128.store64_lane 1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_align (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryb align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_align (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_align2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memorya align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_align2 (param $0 i32) (param $1 v128) - (v128.store64_lane 0 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryd offset=32 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) - (v128.store64_lane 3 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_offset2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memorya offset=32 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_offset2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryb offset=32 align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) - (v128.store64_lane 1 align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.store64_lane_align_offset2 (param $0 i32) (param $1 v128) - ;; CHECK-NEXT: (v128.store64_lane $memoryd offset=32 align=1 0 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.store64_lane_align_offset2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - ;; CHECK: (func $v128.load32_zero (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32_zero $memorya - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_zero (param $0 i32) (result v128) - (v128.load32_zero 0 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load32_zero2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load32_zero $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load32_zero2 (param $0 i32) (result v128) - (v128.load32_zero $memoryb - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load64_zero (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load64_zero $memoryb - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_zero (param $0 i32) (result v128) - (v128.load64_zero 1 - (local.get $0) - ) - ) - ;; CHECK: (func $v128.load64_zero2 (param $0 i32) (result v128) - ;; CHECK-NEXT: (v128.load64_zero $memoryc - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $v128.load64_zero2 (param $0 i32) (result v128) - (v128.load64_zero $memoryc - (local.get $0) - ) - ) -) - diff --git a/test/memory-import.wast b/test/memory-import.wast deleted file mode 100644 index d7e6e377048..00000000000 --- a/test/memory-import.wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i32.const 37) - ) - ) -) diff --git a/test/memory-import.wast.from-wast b/test/memory-import.wast.from-wast deleted file mode 100644 index 70fc97057b9..00000000000 --- a/test/memory-import.wast.from-wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i32.const 37) - ) - ) -) diff --git a/test/memory-import.wast.fromBinary b/test/memory-import.wast.fromBinary deleted file mode 100644 index b83ca836aac..00000000000 --- a/test/memory-import.wast.fromBinary +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i32.const 37) - ) - ) -) - diff --git a/test/memory-import.wast.fromBinary.noDebugInfo b/test/memory-import.wast.fromBinary.noDebugInfo deleted file mode 100644 index 26f8d46f469..00000000000 --- a/test/memory-import.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $mimport$0 1 1)) - (func $0 (type $0) (result i32) - (i32.load offset=13 - (i32.const 37) - ) - ) -) - diff --git a/test/memory-import64.wast b/test/memory-import64.wast deleted file mode 100644 index f84f394e732..00000000000 --- a/test/memory-import64.wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 i64 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i64.const 37) - ) - ) -) diff --git a/test/memory-import64.wast.from-wast b/test/memory-import64.wast.from-wast deleted file mode 100644 index cad69d49b07..00000000000 --- a/test/memory-import64.wast.from-wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 i64 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i64.const 37) - ) - ) -) diff --git a/test/memory-import64.wast.fromBinary b/test/memory-import64.wast.fromBinary deleted file mode 100644 index dca6e27b680..00000000000 --- a/test/memory-import64.wast.fromBinary +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $0 i64 1 1)) - (func $foo (type $0) (result i32) - (i32.load offset=13 - (i64.const 37) - ) - ) -) - diff --git a/test/memory-import64.wast.fromBinary.noDebugInfo b/test/memory-import64.wast.fromBinary.noDebugInfo deleted file mode 100644 index 1ceb12ec956..00000000000 --- a/test/memory-import64.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func (result i32))) - (import "env" "memory" (memory $mimport$0 i64 1 1)) - (func $0 (type $0) (result i32) - (i32.load offset=13 - (i64.const 37) - ) - ) -) - diff --git a/test/memory-shared.wast b/test/memory-shared.wast deleted file mode 100644 index ee02979b117..00000000000 --- a/test/memory-shared.wast +++ /dev/null @@ -1,3 +0,0 @@ -(module - (memory $0 (shared 23 256)) -) diff --git a/test/memory-shared.wast.from-wast b/test/memory-shared.wast.from-wast deleted file mode 100644 index ee02979b117..00000000000 --- a/test/memory-shared.wast.from-wast +++ /dev/null @@ -1,3 +0,0 @@ -(module - (memory $0 (shared 23 256)) -) diff --git a/test/memory-shared.wast.fromBinary b/test/memory-shared.wast.fromBinary deleted file mode 100644 index ea904d0850c..00000000000 --- a/test/memory-shared.wast.fromBinary +++ /dev/null @@ -1,4 +0,0 @@ -(module - (memory $0 (shared 23 256)) -) - diff --git a/test/memory-shared.wast.fromBinary.noDebugInfo b/test/memory-shared.wast.fromBinary.noDebugInfo deleted file mode 100644 index ea904d0850c..00000000000 --- a/test/memory-shared.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,4 +0,0 @@ -(module - (memory $0 (shared 23 256)) -) - diff --git a/test/min.wast b/test/min.wast deleted file mode 100644 index 4efd4608ba2..00000000000 --- a/test/min.wast +++ /dev/null @@ -1,57 +0,0 @@ -(module - (type $0 (func (param f32) (result f32))) - (type $1 (func (param i32 i32) (result f32))) - (type $2 (func (param i32) (result i32))) - (type $3 (func (param i32 i32 i32) (result i32))) - (memory $0 256 256) - (export "floats" (func $floats)) - (func $floats (type $0) (param $f f32) (result f32) - (local $t f32) - (f32.add - (local.get $t) - (local.get $f) - ) - ) - (func $neg (type $1) (param $k i32) (param $p i32) (result f32) - (local $n f32) - (local.tee $n - (f32.neg - (block $block0 (result f32) - (i32.store - (local.get $k) - (local.get $p) - ) - (f32.load - (local.get $k) - ) - ) - ) - ) - ) - (func $littleswitch (type $2) (param $x i32) (result i32) - (block $topmost (result i32) - (block $switch-case$2 - (block $switch-case$1 - (br_table $switch-case$1 $switch-case$2 $switch-case$1 - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - ) - (br $topmost - (i32.const 1) - ) - ) - (br $topmost - (i32.const 2) - ) - (i32.const 0) - ) - ) - (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) - (block $topmost (result i32) - (local.get $i3) - ) - ) -) diff --git a/test/min.wast.from-wast b/test/min.wast.from-wast deleted file mode 100644 index d8de52eddf3..00000000000 --- a/test/min.wast.from-wast +++ /dev/null @@ -1,57 +0,0 @@ -(module - (type $0 (func (param f32) (result f32))) - (type $1 (func (param i32 i32) (result f32))) - (type $2 (func (param i32) (result i32))) - (type $3 (func (param i32 i32 i32) (result i32))) - (memory $0 256 256) - (export "floats" (func $floats)) - (func $floats (type $0) (param $f f32) (result f32) - (local $t f32) - (f32.add - (local.get $t) - (local.get $f) - ) - ) - (func $neg (type $1) (param $k i32) (param $p i32) (result f32) - (local $n f32) - (local.tee $n - (f32.neg - (block $block0 (result f32) - (i32.store - (local.get $k) - (local.get $p) - ) - (f32.load - (local.get $k) - ) - ) - ) - ) - ) - (func $littleswitch (type $2) (param $x i32) (result i32) - (block $topmost (result i32) - (block $switch-case$2 - (block $switch-case$1 - (br_table $switch-case$1 $switch-case$2 $switch-case$1 - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - ) - (br $topmost - (i32.const 1) - ) - ) - (br $topmost - (i32.const 2) - ) - (i32.const 0) - ) - ) - (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) - (block $topmost (result i32) - (local.get $i3) - ) - ) -) diff --git a/test/min.wast.fromBinary b/test/min.wast.fromBinary deleted file mode 100644 index ca4d197f61f..00000000000 --- a/test/min.wast.fromBinary +++ /dev/null @@ -1,55 +0,0 @@ -(module - (type $0 (func (param f32) (result f32))) - (type $1 (func (param i32 i32) (result f32))) - (type $2 (func (param i32) (result i32))) - (type $3 (func (param i32 i32 i32) (result i32))) - (memory $0 256 256) - (export "floats" (func $floats)) - (func $floats (type $0) (param $f f32) (result f32) - (local $t f32) - (f32.add - (local.get $t) - (local.get $f) - ) - ) - (func $neg (type $1) (param $k i32) (param $p i32) (result f32) - (local $n f32) - (local.tee $n - (f32.neg - (block $label$1 (result f32) - (i32.store - (local.get $k) - (local.get $p) - ) - (f32.load - (local.get $k) - ) - ) - ) - ) - ) - (func $littleswitch (type $2) (param $x i32) (result i32) - (block $label$1 (result i32) - (block $label$2 - (block $label$3 - (br_table $label$3 $label$2 $label$3 - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - ) - (br $label$1 - (i32.const 1) - ) - ) - (br $label$1 - (i32.const 2) - ) - ) - ) - (func $f1 (type $3) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) - (local.get $i3) - ) -) - diff --git a/test/min.wast.fromBinary.noDebugInfo b/test/min.wast.fromBinary.noDebugInfo deleted file mode 100644 index 218526339e2..00000000000 --- a/test/min.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,55 +0,0 @@ -(module - (type $0 (func (param f32) (result f32))) - (type $1 (func (param i32 i32) (result f32))) - (type $2 (func (param i32) (result i32))) - (type $3 (func (param i32 i32 i32) (result i32))) - (memory $0 256 256) - (export "floats" (func $0)) - (func $0 (type $0) (param $0 f32) (result f32) - (local $1 f32) - (f32.add - (local.get $1) - (local.get $0) - ) - ) - (func $1 (type $1) (param $0 i32) (param $1 i32) (result f32) - (local $2 f32) - (local.tee $2 - (f32.neg - (block $label$1 (result f32) - (i32.store - (local.get $0) - (local.get $1) - ) - (f32.load - (local.get $0) - ) - ) - ) - ) - ) - (func $2 (type $2) (param $0 i32) (result i32) - (block $label$1 (result i32) - (block $label$2 - (block $label$3 - (br_table $label$3 $label$2 $label$3 - (i32.sub - (local.get $0) - (i32.const 1) - ) - ) - ) - (br $label$1 - (i32.const 1) - ) - ) - (br $label$1 - (i32.const 2) - ) - ) - ) - (func $3 (type $3) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local.get $2) - ) -) - diff --git a/test/multi-memories-atomics64.wast b/test/multi-memories-atomics64.wast deleted file mode 100644 index 565a5e63a85..00000000000 --- a/test/multi-memories-atomics64.wast +++ /dev/null @@ -1,352 +0,0 @@ -(module - (type $0 (func)) - (memory $appMemory (shared i64 23 256)) - (memory $dataMemory (shared i64 23 256)) - (memory $instrumentMemory (shared i64 23 256)) - (func $atomic-loadstore - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $instrumentMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $dataMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $instrumentMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $instrumentMemory - (local.get $0) - ) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.add $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $instrumentMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $appMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $dataMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $dataMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 $dataMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $appMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence - (atomic.fence) - ) -) - diff --git a/test/multi-memories-atomics64.wast.from-wast b/test/multi-memories-atomics64.wast.from-wast deleted file mode 100644 index 433602f8e1c..00000000000 --- a/test/multi-memories-atomics64.wast.from-wast +++ /dev/null @@ -1,351 +0,0 @@ -(module - (type $0 (func)) - (memory $appMemory (shared i64 23 256)) - (memory $dataMemory (shared i64 23 256)) - (memory $instrumentMemory (shared i64 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $instrumentMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $dataMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $instrumentMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $instrumentMemory - (local.get $0) - ) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.add $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $instrumentMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $appMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $dataMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $dataMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 $dataMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $appMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) diff --git a/test/multi-memories-atomics64.wast.fromBinary b/test/multi-memories-atomics64.wast.fromBinary deleted file mode 100644 index 2fa4dfd32ab..00000000000 --- a/test/multi-memories-atomics64.wast.fromBinary +++ /dev/null @@ -1,352 +0,0 @@ -(module - (type $0 (func)) - (memory $appMemory (shared i64 23 256)) - (memory $dataMemory (shared i64 23 256)) - (memory $instrumentMemory (shared i64 23 256)) - (func $atomic-loadstore (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load8_u $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $instrumentMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $dataMemory offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $appMemory offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $dataMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $instrumentMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $appMemory - (local.get $0) - ) - ) - (drop - (i64.atomic.load $instrumentMemory - (local.get $0) - ) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $appMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $instrumentMemory offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $dataMemory offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $atomic-rmw (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add $dataMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.add $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $appMemory offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $instrumentMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.or_u $appMemory - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $appMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $dataMemory - (local.get $0) - (local.get $2) - ) - ) - ) - (func $atomic-cmpxchg (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.cmpxchg $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $appMemory - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $appMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $dataMemory offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $dataMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-wait-notify (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 $dataMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $appMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $instrumentMemory offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $appMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $dataMemory offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $instrumentMemory - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $appMemory offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $atomic-fence (type $0) - (atomic.fence) - ) -) - diff --git a/test/multi-memories-atomics64.wast.fromBinary.noDebugInfo b/test/multi-memories-atomics64.wast.fromBinary.noDebugInfo deleted file mode 100644 index 01ba922f703..00000000000 --- a/test/multi-memories-atomics64.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,352 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared i64 23 256)) - (memory $1 (shared i64 23 256)) - (memory $2 (shared i64 23 256)) - (func $0 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.load8_u $0 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load8_u $0 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $1 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load16_u $2 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $1 offset=4 - (local.get $0) - ) - ) - (drop - (i32.atomic.load $0 offset=4 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $0 - (local.get $0) - ) - ) - (drop - (i64.atomic.load8_u $1 - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $0 - (local.get $0) - ) - ) - (drop - (i64.atomic.load16_u $0 - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $2 - (local.get $0) - ) - ) - (drop - (i64.atomic.load32_u $0 - (local.get $0) - ) - ) - (drop - (i64.atomic.load $0 - (local.get $0) - ) - ) - (drop - (i64.atomic.load $2 - (local.get $0) - ) - ) - (i32.atomic.store $0 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store $0 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $2 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store8 $1 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $0 offset=4 - (local.get $0) - (local.get $2) - ) - (i32.atomic.store16 $1 offset=4 - (local.get $0) - (local.get $2) - ) - (i64.atomic.store $0 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store $0 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $1 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store8 $2 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $0 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store16 $0 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $2 offset=4 - (local.get $0) - (local.get $1) - ) - (i64.atomic.store32 $1 offset=4 - (local.get $0) - (local.get $1) - ) - ) - (func $1 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.add $1 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.add $2 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $0 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.add_u $0 offset=4 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $1 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw16.and_u $2 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw32.or_u $0 - (local.get $0) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.or_u $0 - (local.get $0) - (local.get $1) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $0 - (local.get $0) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.xchg_u $1 - (local.get $0) - (local.get $2) - ) - ) - ) - (func $2 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (i32.atomic.rmw.cmpxchg $0 offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw.cmpxchg $2 offset=4 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $0 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u $0 - (local.get $0) - (local.get $2) - (local.get $2) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $0 offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw.cmpxchg $1 offset=4 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $2 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (i64.atomic.rmw32.cmpxchg_u $1 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $3 (type $0) - (local $0 i64) - (local $1 i64) - (local $2 i32) - (drop - (memory.atomic.wait32 $1 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $2 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $0 offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait32 $2 offset=4 - (local.get $0) - (local.get $2) - (local.get $1) - ) - ) - (drop - (memory.atomic.notify $1 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $1 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $0 offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.notify $1 offset=24 - (local.get $0) - (local.get $2) - ) - ) - (drop - (memory.atomic.wait64 $2 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $2 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $0 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - (drop - (memory.atomic.wait64 $0 offset=16 - (local.get $0) - (local.get $1) - (local.get $1) - ) - ) - ) - (func $4 (type $0) - (atomic.fence) - ) -) - diff --git a/test/multi-memories-basics.wast b/test/multi-memories-basics.wast deleted file mode 100644 index 62b926531b3..00000000000 --- a/test/multi-memories-basics.wast +++ /dev/null @@ -1,117 +0,0 @@ -(module - (type $none_=>_none (func)) - (type $none_=>_i32 (func (result i32))) - (import "env" "memory" (memory $importedMemory 1 1)) - (memory $memory1 1 500) - (memory $memory2 1 800) - (memory $memory3 1 400) - (data (i32.const 0) "abcd") - (func $memory.fill - (memory.fill $memory2 - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) - ) - (func $memory.copy - (memory.copy $memory2 $memory3 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.init - (memory.init $memory1 0 - (i32.const 0) - (i32.const 0) - (i32.const 45) - ) - ) - (func $memory.grow (result i32) - (memory.grow $memory3 - (i32.const 10) - ) - ) - (func $memory.size (result i32) - (memory.size $memory3) - ) - (func $loads - (drop - (i32.load $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - ) - (func $stores - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store16 $memory2 - (i32.const 20) - (i32.const 31353) - ) - (i32.store16 $importedMemory - (i32.const 20) - (i32.const 31353) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - ) -) - diff --git a/test/multi-memories-basics.wast.from-wast b/test/multi-memories-basics.wast.from-wast deleted file mode 100644 index 68a12858e9c..00000000000 --- a/test/multi-memories-basics.wast.from-wast +++ /dev/null @@ -1,116 +0,0 @@ -(module - (type $none_=>_none (func)) - (type $none_=>_i32 (func (result i32))) - (import "env" "memory" (memory $importedMemory 1 1)) - (memory $memory1 1 500) - (memory $memory2 1 800) - (memory $memory3 1 400) - (data $0 (i32.const 0) "abcd") - (func $memory.fill (type $none_=>_none) - (memory.fill $memory2 - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) - ) - (func $memory.copy (type $none_=>_none) - (memory.copy $memory2 $memory3 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.init (type $none_=>_none) - (memory.init $memory1 $0 - (i32.const 0) - (i32.const 0) - (i32.const 45) - ) - ) - (func $memory.grow (type $none_=>_i32) (result i32) - (memory.grow $memory3 - (i32.const 10) - ) - ) - (func $memory.size (type $none_=>_i32) (result i32) - (memory.size $memory3) - ) - (func $loads (type $none_=>_none) - (drop - (i32.load $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - ) - (func $stores (type $none_=>_none) - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store16 $memory2 - (i32.const 20) - (i32.const 31353) - ) - (i32.store16 $importedMemory - (i32.const 20) - (i32.const 31353) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - ) -) diff --git a/test/multi-memories-basics.wast.fromBinary b/test/multi-memories-basics.wast.fromBinary deleted file mode 100644 index 7ce313b82d8..00000000000 --- a/test/multi-memories-basics.wast.fromBinary +++ /dev/null @@ -1,117 +0,0 @@ -(module - (type $none_=>_none (func)) - (type $none_=>_i32 (func (result i32))) - (import "env" "memory" (memory $importedMemory 1 1)) - (memory $memory1 1 500) - (memory $memory2 1 800) - (memory $memory3 1 400) - (data $0 (i32.const 0) "abcd") - (func $memory.fill (type $none_=>_none) - (memory.fill $memory2 - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) - ) - (func $memory.copy (type $none_=>_none) - (memory.copy $memory2 $memory3 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.init (type $none_=>_none) - (memory.init $memory1 $0 - (i32.const 0) - (i32.const 0) - (i32.const 45) - ) - ) - (func $memory.grow (type $none_=>_i32) (result i32) - (memory.grow $memory3 - (i32.const 10) - ) - ) - (func $memory.size (type $none_=>_i32) (result i32) - (memory.size $memory3) - ) - (func $loads (type $none_=>_none) - (drop - (i32.load $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $memory3 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $memory1 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $memory2 - (i32.const 12) - ) - ) - ) - (func $stores (type $none_=>_none) - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store $memory1 - (i32.const 12) - (i32.const 115) - ) - (i32.store16 $memory2 - (i32.const 20) - (i32.const 31353) - ) - (i32.store16 $importedMemory - (i32.const 20) - (i32.const 31353) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - (i32.store8 $memory3 - (i32.const 23) - (i32.const 120) - ) - ) -) - diff --git a/test/multi-memories-basics.wast.fromBinary.noDebugInfo b/test/multi-memories-basics.wast.fromBinary.noDebugInfo deleted file mode 100644 index 7401787dcea..00000000000 --- a/test/multi-memories-basics.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,117 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (result i32))) - (import "env" "memory" (memory $mimport$0 1 1)) - (memory $0 1 500) - (memory $1 1 800) - (memory $2 1 400) - (data $0 (i32.const 0) "abcd") - (func $0 (type $0) - (memory.fill $1 - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) - ) - (func $1 (type $0) - (memory.copy $1 $2 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $2 (type $0) - (memory.init $0 $0 - (i32.const 0) - (i32.const 0) - (i32.const 45) - ) - ) - (func $3 (type $1) (result i32) - (memory.grow $2 - (i32.const 10) - ) - ) - (func $4 (type $1) (result i32) - (memory.size $2) - ) - (func $5 (type $0) - (drop - (i32.load $0 - (i32.const 12) - ) - ) - (drop - (i32.load $2 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $1 - (i32.const 12) - ) - ) - (drop - (i32.load16_s $1 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $2 - (i32.const 12) - ) - ) - (drop - (i32.load8_s $2 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $0 - (i32.const 12) - ) - ) - (drop - (i32.load16_u $0 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $1 - (i32.const 12) - ) - ) - (drop - (i32.load8_u $1 - (i32.const 12) - ) - ) - ) - (func $6 (type $0) - (i32.store $0 - (i32.const 12) - (i32.const 115) - ) - (i32.store $0 - (i32.const 12) - (i32.const 115) - ) - (i32.store16 $1 - (i32.const 20) - (i32.const 31353) - ) - (i32.store16 $mimport$0 - (i32.const 20) - (i32.const 31353) - ) - (i32.store8 $2 - (i32.const 23) - (i32.const 120) - ) - (i32.store8 $2 - (i32.const 23) - (i32.const 120) - ) - ) -) - diff --git a/test/multi-memories-simd.wast b/test/multi-memories-simd.wast deleted file mode 100644 index 48cde73c387..00000000000 --- a/test/multi-memories-simd.wast +++ /dev/null @@ -1,320 +0,0 @@ -(module - (type $i32_=>_v128 (func (param i32) (result v128))) - (type $i32_v128_=>_none (func (param i32 v128))) - (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) - (memory $memorya 1 1) - (memory $memoryb 1 1) - (memory $memoryc 1 1) - (memory $memoryd 1 1) - (func $v128.load (param $0 i32) (result v128) - (v128.load $memorya - (local.get $0) - ) - ) - (func $v128.load2 (param $0 i32) (result v128) - (v128.load $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_s (param $0 i32) (result v128) - (v128.load8x8_s $memoryc - (local.get $0) - ) - ) - (func $v128.load8x8_s2 (param $0 i32) (result v128) - (v128.load8x8_s $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_u (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load8x8_u2 (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load16x4_s (param $0 i32) (result v128) - (v128.load16x4_s $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_s2 (param $0 i32) (result v128) - (v128.load16x4_s $memoryb - (local.get $0) - ) - ) - (func $v128.load16x4_u (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_u2 (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load32x2_s (param $0 i32) (result v128) - (v128.load32x2_s $memoryc - (local.get $0) - ) - ) - (func $v128.load32x2_s2 (param $0 i32) (result v128) - (v128.load32x2_s $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u (param $0 i32) (result v128) - (v128.load32x2_u $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u2 (param $0 i32) (result v128) - (v128.load32x2_u $memoryc - (local.get $0) - ) - ) - (func $v128.load8_splat (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load8_splat2 (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load16_splat (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load16_splat2 (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load32_splat (param $0 i32) (result v128) - (v128.load32_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load32_splat2 (param $0 i32) (result v128) - (v128.load32_splat $memoryd - (local.get $0) - ) - ) - (func $v128.load64_splat (param $0 i32) (result v128) - (v128.load64_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load64_splat2 (param $0 i32) (result v128) - (v128.load64_splat $memorya - (local.get $0) - ) - ) - (func $v128.store (param $0 i32) (param $1 v128) - (v128.store $memorya - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store2 (param $0 i32) (param $1 v128) - (v128.store $memoryb - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryc offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset2 (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (param $0 i32) (param $1 v128) - (v128.store8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane2 (param $0 i32) (param $1 v128) - (v128.store8_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (param $0 i32) (param $1 v128) - (v128.store16_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane2 (param $0 i32) (param $1 v128) - (v128.store16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane2 (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset2 (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (param $0 i32) (result v128) - (v128.load32_zero $memorya - (local.get $0) - ) - ) - (func $v128.load32_zero2 (param $0 i32) (result v128) - (v128.load32_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero (param $0 i32) (result v128) - (v128.load64_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero2 (param $0 i32) (result v128) - (v128.load64_zero $memoryc - (local.get $0) - ) - ) -) - diff --git a/test/multi-memories-simd.wast.from-wast b/test/multi-memories-simd.wast.from-wast deleted file mode 100644 index e156e8e952b..00000000000 --- a/test/multi-memories-simd.wast.from-wast +++ /dev/null @@ -1,319 +0,0 @@ -(module - (type $i32_=>_v128 (func (param i32) (result v128))) - (type $i32_v128_=>_none (func (param i32 v128))) - (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) - (memory $memorya 1 1) - (memory $memoryb 1 1) - (memory $memoryc 1 1) - (memory $memoryd 1 1) - (func $v128.load (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load $memorya - (local.get $0) - ) - ) - (func $v128.load2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_s $memoryc - (local.get $0) - ) - ) - (func $v128.load8x8_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_s $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load8x8_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_s $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_s $memoryb - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_s $memoryc - (local.get $0) - ) - ) - (func $v128.load32x2_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_s $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_u $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_u $memoryc - (local.get $0) - ) - ) - (func $v128.load8_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load8_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load16_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load16_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load32_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load32_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_splat $memoryd - (local.get $0) - ) - ) - (func $v128.load64_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load64_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_splat $memorya - (local.get $0) - ) - ) - (func $v128.store (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store $memorya - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store $memoryb - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryc offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store8_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store16_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_zero $memorya - (local.get $0) - ) - ) - (func $v128.load32_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_zero $memoryc - (local.get $0) - ) - ) -) diff --git a/test/multi-memories-simd.wast.fromBinary b/test/multi-memories-simd.wast.fromBinary deleted file mode 100644 index 2d64362fde1..00000000000 --- a/test/multi-memories-simd.wast.fromBinary +++ /dev/null @@ -1,320 +0,0 @@ -(module - (type $i32_=>_v128 (func (param i32) (result v128))) - (type $i32_v128_=>_none (func (param i32 v128))) - (type $i32_v128_=>_v128 (func (param i32 v128) (result v128))) - (memory $memorya 1 1) - (memory $memoryb 1 1) - (memory $memoryc 1 1) - (memory $memoryd 1 1) - (func $v128.load (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load $memorya - (local.get $0) - ) - ) - (func $v128.load2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_s $memoryc - (local.get $0) - ) - ) - (func $v128.load8x8_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_s $memoryb - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load8x8_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8x8_u $memoryd - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_s $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_s $memoryb - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load16x4_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16x4_u $memorya - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_s $memoryc - (local.get $0) - ) - ) - (func $v128.load32x2_s2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_s $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_u $memoryb - (local.get $0) - ) - ) - (func $v128.load32x2_u2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32x2_u $memoryc - (local.get $0) - ) - ) - (func $v128.load8_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load8_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load8_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load16_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load16_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load16_splat $memorya - (local.get $0) - ) - ) - (func $v128.load32_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load32_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_splat $memoryd - (local.get $0) - ) - ) - (func $v128.load64_splat (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_splat $memoryb - (local.get $0) - ) - ) - (func $v128.load64_splat2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_splat $memorya - (local.get $0) - ) - ) - (func $v128.store (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store $memorya - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store $memoryb - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryc offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryb offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memorya offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset2 (type $i32_v128_=>_v128) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store8_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store8_lane $memoryd 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store16_lane $memorya 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store16_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store32_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryc 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memorya offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryb offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset2 (type $i32_v128_=>_none) (param $0 i32) (param $1 v128) - (v128.store64_lane $memoryd offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_zero $memorya - (local.get $0) - ) - ) - (func $v128.load32_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load32_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_zero $memoryb - (local.get $0) - ) - ) - (func $v128.load64_zero2 (type $i32_=>_v128) (param $0 i32) (result v128) - (v128.load64_zero $memoryc - (local.get $0) - ) - ) -) - diff --git a/test/multi-memories-simd.wast.fromBinary.noDebugInfo b/test/multi-memories-simd.wast.fromBinary.noDebugInfo deleted file mode 100644 index 3c2609d9ae1..00000000000 --- a/test/multi-memories-simd.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,320 +0,0 @@ -(module - (type $0 (func (param i32) (result v128))) - (type $1 (func (param i32 v128))) - (type $2 (func (param i32 v128) (result v128))) - (memory $0 1 1) - (memory $1 1 1) - (memory $2 1 1) - (memory $3 1 1) - (func $0 (type $0) (param $0 i32) (result v128) - (v128.load $0 - (local.get $0) - ) - ) - (func $1 (type $0) (param $0 i32) (result v128) - (v128.load $1 - (local.get $0) - ) - ) - (func $2 (type $0) (param $0 i32) (result v128) - (v128.load8x8_s $2 - (local.get $0) - ) - ) - (func $3 (type $0) (param $0 i32) (result v128) - (v128.load8x8_s $1 - (local.get $0) - ) - ) - (func $4 (type $0) (param $0 i32) (result v128) - (v128.load8x8_u $3 - (local.get $0) - ) - ) - (func $5 (type $0) (param $0 i32) (result v128) - (v128.load8x8_u $3 - (local.get $0) - ) - ) - (func $6 (type $0) (param $0 i32) (result v128) - (v128.load16x4_s $0 - (local.get $0) - ) - ) - (func $7 (type $0) (param $0 i32) (result v128) - (v128.load16x4_s $1 - (local.get $0) - ) - ) - (func $8 (type $0) (param $0 i32) (result v128) - (v128.load16x4_u $0 - (local.get $0) - ) - ) - (func $9 (type $0) (param $0 i32) (result v128) - (v128.load16x4_u $0 - (local.get $0) - ) - ) - (func $10 (type $0) (param $0 i32) (result v128) - (v128.load32x2_s $2 - (local.get $0) - ) - ) - (func $11 (type $0) (param $0 i32) (result v128) - (v128.load32x2_s $1 - (local.get $0) - ) - ) - (func $12 (type $0) (param $0 i32) (result v128) - (v128.load32x2_u $1 - (local.get $0) - ) - ) - (func $13 (type $0) (param $0 i32) (result v128) - (v128.load32x2_u $2 - (local.get $0) - ) - ) - (func $14 (type $0) (param $0 i32) (result v128) - (v128.load8_splat $1 - (local.get $0) - ) - ) - (func $15 (type $0) (param $0 i32) (result v128) - (v128.load8_splat $1 - (local.get $0) - ) - ) - (func $16 (type $0) (param $0 i32) (result v128) - (v128.load16_splat $0 - (local.get $0) - ) - ) - (func $17 (type $0) (param $0 i32) (result v128) - (v128.load16_splat $0 - (local.get $0) - ) - ) - (func $18 (type $0) (param $0 i32) (result v128) - (v128.load32_splat $1 - (local.get $0) - ) - ) - (func $19 (type $0) (param $0 i32) (result v128) - (v128.load32_splat $3 - (local.get $0) - ) - ) - (func $20 (type $0) (param $0 i32) (result v128) - (v128.load64_splat $1 - (local.get $0) - ) - ) - (func $21 (type $0) (param $0 i32) (result v128) - (v128.load64_splat $0 - (local.get $0) - ) - ) - (func $22 (type $1) (param $0 i32) (param $1 v128) - (v128.store $0 - (local.get $0) - (local.get $1) - ) - ) - (func $23 (type $1) (param $0 i32) (param $1 v128) - (v128.store $1 - (local.get $0) - (local.get $1) - ) - ) - (func $24 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $0 0 - (local.get $0) - (local.get $1) - ) - ) - (func $25 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $26 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $27 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $3 0 - (local.get $0) - (local.get $1) - ) - ) - (func $28 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $0 0 - (local.get $0) - (local.get $1) - ) - ) - (func $29 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $30 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $3 0 - (local.get $0) - (local.get $1) - ) - ) - (func $31 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $32 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $0 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $33 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $1 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $34 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $2 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $35 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $36 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $0 offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $37 (type $2) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane $3 offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $38 (type $1) (param $0 i32) (param $1 v128) - (v128.store8_lane $0 0 - (local.get $0) - (local.get $1) - ) - ) - (func $39 (type $1) (param $0 i32) (param $1 v128) - (v128.store8_lane $3 0 - (local.get $0) - (local.get $1) - ) - ) - (func $40 (type $1) (param $0 i32) (param $1 v128) - (v128.store16_lane $0 0 - (local.get $0) - (local.get $1) - ) - ) - (func $41 (type $1) (param $0 i32) (param $1 v128) - (v128.store16_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $42 (type $1) (param $0 i32) (param $1 v128) - (v128.store32_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $43 (type $1) (param $0 i32) (param $1 v128) - (v128.store32_lane $2 0 - (local.get $0) - (local.get $1) - ) - ) - (func $44 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $2 0 - (local.get $0) - (local.get $1) - ) - ) - (func $45 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $46 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $1 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $47 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $0 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $48 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $3 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $49 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $0 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $50 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $1 offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $51 (type $1) (param $0 i32) (param $1 v128) - (v128.store64_lane $3 offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $52 (type $0) (param $0 i32) (result v128) - (v128.load32_zero $0 - (local.get $0) - ) - ) - (func $53 (type $0) (param $0 i32) (result v128) - (v128.load32_zero $1 - (local.get $0) - ) - ) - (func $54 (type $0) (param $0 i32) (result v128) - (v128.load64_zero $1 - (local.get $0) - ) - ) - (func $55 (type $0) (param $0 i32) (result v128) - (v128.load64_zero $2 - (local.get $0) - ) - ) -) - diff --git a/test/multi-table.wast b/test/multi-table.wast deleted file mode 100644 index 6d4610aad97..00000000000 --- a/test/multi-table.wast +++ /dev/null @@ -1,38 +0,0 @@ -(module - (type $none_=>_none (func)) - (type $A (struct)) - (global $g1 (ref null $none_=>_none) (ref.func $f)) - (global $g2 i32 (i32.const 0)) - - (import "a" "b" (table $t1 1 10 funcref)) - (table $t2 3 3 funcref) - (table $t3 4 4 funcref) - (table $textern 0 externref) - - ;; A table with a typed function references specialized type. - (table $tspecial 5 5 (ref null $none_=>_none)) - - ;; add to $t1 - (elem (i32.const 0) $f) - - ;; add to $t2 - (elem (table $t2) (i32.const 0) func $f) - (elem $activeNonZeroOffset (table $t2) (offset (i32.const 1)) func $f $g) - - (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null func)) - (elem $e3-2 (table $t3) (offset (i32.const 2)) (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g))) - - (elem $passive-1 func $f $g) - (elem $passive-2 funcref (item ref.func $f) (item (ref.func $g)) (ref.null func)) - (elem $passive-3 (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g)) (ref.null $none_=>_none) (global.get $g1)) - (elem $empty func) - (elem $declarative declare func $h) - - ;; This elem will be emitted as usesExpressions because of the type of the - ;; table. - (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) $f $h) - - (func $f (drop (ref.func $h))) - (func $g) - (func $h) -) diff --git a/test/multi-table.wast.from-wast b/test/multi-table.wast.from-wast deleted file mode 100644 index 426f474e5b6..00000000000 --- a/test/multi-table.wast.from-wast +++ /dev/null @@ -1,31 +0,0 @@ -(module - (type $none_=>_none (func)) - (import "a" "b" (table $t1 1 10 funcref)) - (global $g1 (ref null $none_=>_none) (ref.func $f)) - (global $g2 i32 (i32.const 0)) - (table $t2 3 3 funcref) - (table $t3 4 4 funcref) - (table $textern 0 externref) - (table $tspecial 5 5 (ref null $none_=>_none)) - (elem $0 (table $t1) (i32.const 0) func $f) - (elem $1 (table $t2) (i32.const 0) func $f) - (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) - (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) - (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) - (elem $passive-1 func $f $g) - (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) - (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) - (elem $empty func) - (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) - (func $f (type $none_=>_none) - (drop - (ref.func $h) - ) - ) - (func $g (type $none_=>_none) - (nop) - ) - (func $h (type $none_=>_none) - (nop) - ) -) diff --git a/test/multi-table.wast.fromBinary b/test/multi-table.wast.fromBinary deleted file mode 100644 index c27ec806f5c..00000000000 --- a/test/multi-table.wast.fromBinary +++ /dev/null @@ -1,32 +0,0 @@ -(module - (type $none_=>_none (func)) - (import "a" "b" (table $t1 1 10 funcref)) - (global $g1 (ref null $none_=>_none) (ref.func $f)) - (global $g2 i32 (i32.const 0)) - (table $t2 3 3 funcref) - (table $t3 4 4 funcref) - (table $textern 0 externref) - (table $tspecial 5 5 (ref null $none_=>_none)) - (elem $0 (table $t1) (i32.const 0) func $f) - (elem $1 (table $t2) (i32.const 0) func $f) - (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) - (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) - (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) - (elem $passive-1 func $f $g) - (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) - (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) - (elem $empty func) - (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) - (func $f (type $none_=>_none) - (drop - (ref.func $h) - ) - ) - (func $g (type $none_=>_none) - (nop) - ) - (func $h (type $none_=>_none) - (nop) - ) -) - diff --git a/test/multi-table.wast.fromBinary.noDebugInfo b/test/multi-table.wast.fromBinary.noDebugInfo deleted file mode 100644 index c2a5ef858a5..00000000000 --- a/test/multi-table.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,32 +0,0 @@ -(module - (type $0 (func)) - (import "a" "b" (table $timport$0 1 10 funcref)) - (global $global$0 (ref null $0) (ref.func $0)) - (global $global$1 i32 (i32.const 0)) - (table $0 3 3 funcref) - (table $1 4 4 funcref) - (table $2 0 externref) - (table $3 5 5 (ref null $0)) - (elem $0 (table $timport$0) (i32.const 0) func $0) - (elem $1 (table $0) (i32.const 0) func $0) - (elem $2 (table $0) (i32.const 1) func $0 $1) - (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null nofunc)) - (elem $4 (table $1) (i32.const 2) (ref null $0) (ref.func $0) (ref.func $1)) - (elem $5 func $0 $1) - (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null nofunc)) - (elem $7 (ref null $0) (ref.func $0) (ref.func $1) (ref.null nofunc) (global.get $global$0)) - (elem $8 func) - (elem $9 (table $3) (i32.const 0) (ref null $0) (ref.func $0) (ref.func $2)) - (func $0 (type $0) - (drop - (ref.func $2) - ) - ) - (func $1 (type $0) - (nop) - ) - (func $2 (type $0) - (nop) - ) -) - diff --git a/test/mutable-global.wast b/test/mutable-global.wast deleted file mode 100644 index 1cb59de1196..00000000000 --- a/test/mutable-global.wast +++ /dev/null @@ -1,12 +0,0 @@ -(module - (type $0 (func)) - (import "env" "global-mut" (global $global-mut (mut i32))) - (func $foo (type $0) - (global.set $global-mut - (i32.add - (global.get $global-mut) - (i32.const 1) - ) - ) - ) -) diff --git a/test/mutable-global.wast.from-wast b/test/mutable-global.wast.from-wast deleted file mode 100644 index 1a8e121cd5f..00000000000 --- a/test/mutable-global.wast.from-wast +++ /dev/null @@ -1,12 +0,0 @@ -(module - (type $0 (func)) - (import "env" "global-mut" (global $global-mut (mut i32))) - (func $foo (type $0) - (global.set $global-mut - (i32.add - (global.get $global-mut) - (i32.const 1) - ) - ) - ) -) diff --git a/test/mutable-global.wast.fromBinary b/test/mutable-global.wast.fromBinary deleted file mode 100644 index c115bbd4c06..00000000000 --- a/test/mutable-global.wast.fromBinary +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $0 (func)) - (import "env" "global-mut" (global $global-mut (mut i32))) - (func $foo (type $0) - (global.set $global-mut - (i32.add - (global.get $global-mut) - (i32.const 1) - ) - ) - ) -) - diff --git a/test/mutable-global.wast.fromBinary.noDebugInfo b/test/mutable-global.wast.fromBinary.noDebugInfo deleted file mode 100644 index 69db53f3f3a..00000000000 --- a/test/mutable-global.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $0 (func)) - (import "env" "global-mut" (global $gimport$0 (mut i32))) - (func $0 (type $0) - (global.set $gimport$0 - (i32.add - (global.get $gimport$0) - (i32.const 1) - ) - ) - ) -) - diff --git a/test/newsyntax.wast b/test/newsyntax.wast deleted file mode 100644 index 8fc1440a2bf..00000000000 --- a/test/newsyntax.wast +++ /dev/null @@ -1,10 +0,0 @@ -(module - (import "env" "table" (table 9 9 funcref)) - (func "call_indirect" - (drop - (call_indirect (param i32) (param f64) (result i32) (i32.const 10) (f64.const 20) (i32.const 30)) - ) - (call_indirect (i32.const 1)) - ) -) - diff --git a/test/newsyntax.wast.from-wast b/test/newsyntax.wast.from-wast deleted file mode 100644 index 997180e4f0c..00000000000 --- a/test/newsyntax.wast.from-wast +++ /dev/null @@ -1,18 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32 f64) (result i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (export "call_indirect" (func $0)) - (func $0 (type $0) - (drop - (call_indirect $timport$0 (type $1) - (i32.const 10) - (f64.const 20) - (i32.const 30) - ) - ) - (call_indirect $timport$0 (type $0) - (i32.const 1) - ) - ) -) diff --git a/test/newsyntax.wast.fromBinary b/test/newsyntax.wast.fromBinary deleted file mode 100644 index 8d14c6360f9..00000000000 --- a/test/newsyntax.wast.fromBinary +++ /dev/null @@ -1,19 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32 f64) (result i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (export "call_indirect" (func $0)) - (func $0 (type $0) - (drop - (call_indirect $timport$0 (type $1) - (i32.const 10) - (f64.const 20) - (i32.const 30) - ) - ) - (call_indirect $timport$0 (type $0) - (i32.const 1) - ) - ) -) - diff --git a/test/newsyntax.wast.fromBinary.noDebugInfo b/test/newsyntax.wast.fromBinary.noDebugInfo deleted file mode 100644 index 8d14c6360f9..00000000000 --- a/test/newsyntax.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,19 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (param i32 f64) (result i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (export "call_indirect" (func $0)) - (func $0 (type $0) - (drop - (call_indirect $timport$0 (type $1) - (i32.const 10) - (f64.const 20) - (i32.const 30) - ) - ) - (call_indirect $timport$0 (type $0) - (i32.const 1) - ) - ) -) - diff --git a/test/nonspec-bulk-memory.wast b/test/nonspec-bulk-memory.wast deleted file mode 100644 index 91f8c23a2a5..00000000000 --- a/test/nonspec-bulk-memory.wast +++ /dev/null @@ -1,29 +0,0 @@ -(module - (memory 1024 1024 - (segment 0 "hello, world") - ) - (func $memory.init - (memory.init 0 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $data.drop - (data.drop 0) - ) - (func $memory.copy - (memory.copy - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.fill - (memory.fill - (i32.const 0) - (i32.const 42) - (i32.const 1024) - ) - ) -) diff --git a/test/nonspec-bulk-memory.wast.from-wast b/test/nonspec-bulk-memory.wast.from-wast deleted file mode 100644 index 8c4b98b1d33..00000000000 --- a/test/nonspec-bulk-memory.wast.from-wast +++ /dev/null @@ -1,29 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1024 1024) - (data $0 (i32.const 0) "hello, world") - (func $memory.init (type $0) - (memory.init $0 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $data.drop (type $0) - (data.drop $0) - ) - (func $memory.copy (type $0) - (memory.copy - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.fill (type $0) - (memory.fill - (i32.const 0) - (i32.const 42) - (i32.const 1024) - ) - ) -) diff --git a/test/nonspec-bulk-memory.wast.fromBinary b/test/nonspec-bulk-memory.wast.fromBinary deleted file mode 100644 index f2c4c0c5e30..00000000000 --- a/test/nonspec-bulk-memory.wast.fromBinary +++ /dev/null @@ -1,30 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1024 1024) - (data $0 (i32.const 0) "hello, world") - (func $memory.init (type $0) - (memory.init $0 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $data.drop (type $0) - (data.drop $0) - ) - (func $memory.copy (type $0) - (memory.copy - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $memory.fill (type $0) - (memory.fill - (i32.const 0) - (i32.const 42) - (i32.const 1024) - ) - ) -) - diff --git a/test/nonspec-bulk-memory.wast.fromBinary.noDebugInfo b/test/nonspec-bulk-memory.wast.fromBinary.noDebugInfo deleted file mode 100644 index 9f1d63f2431..00000000000 --- a/test/nonspec-bulk-memory.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,30 +0,0 @@ -(module - (type $0 (func)) - (memory $0 1024 1024) - (data $0 (i32.const 0) "hello, world") - (func $0 (type $0) - (memory.init $0 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $1 (type $0) - (data.drop $0) - ) - (func $2 (type $0) - (memory.copy - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - (func $3 (type $0) - (memory.fill - (i32.const 0) - (i32.const 42) - (i32.const 1024) - ) - ) -) - diff --git a/test/polymorphic_stack.wast b/test/polymorphic_stack.wast deleted file mode 100644 index c832655518a..00000000000 --- a/test/polymorphic_stack.wast +++ /dev/null @@ -1,133 +0,0 @@ -(module - (type $FUNCSIG$ii (func (param i32) (result i32))) - (import "env" "table" (table 9 9 funcref)) - (func $break-and-binary (result i32) - (block $x (result i32) - (f32.add - (br_if $x - (i32.trunc_f64_u - (unreachable) - ) - (i32.trunc_f64_u - (unreachable) - ) - ) - (f32.const 1) - ) - ) - ) - (func $call-and-unary (param i32) (result i32) - (drop - (i64.eqz - (call $call-and-unary - (unreachable) - ) - ) - ) - (drop - (i64.eqz - (i32.eqz - (unreachable) - ) - ) - ) - (drop - (i64.eqz - (call_indirect (type $FUNCSIG$ii) - (unreachable) - (unreachable) - ) - ) - ) - ) - (func $tee (param $x i32) - (local $y f32) - (drop - (i64.eqz - (local.tee $x - (unreachable) - ) - ) - ) - (drop - (local.tee $y - (i64.eqz - (unreachable) - ) - ) - ) - ) - (func $tee2 - (local $0 f32) - (if - (i32.const 259) - (local.set $0 - (unreachable) - ) - ) - ) - (func $select - (drop - (i64.eqz - (select - (unreachable) - (i32.const 1) - (i32.const 2) - ) - ) - ) - ) - (func $untaken-break-should-have-value (result i32) - (block $x (result i32) - (block - (br_if $x - (i32.const 0) - (unreachable) - ) - ) - ) - ) - (func $unreachable-in-block-but-code-before (param $0 i32) (result i32) - (if - (local.get $0) - (return - (i32.const 127) - ) - ) - (block $label$0 (result i32) - (br_if $label$0 - (i32.const 0) - (return - (i32.const -32) - ) - ) - ) - ) - (func $br_table_unreachable_to_also_unreachable (result i32) - (block $a (result i32) - (block $b (result i32) - (br_table $a $b ;; seems to send a value, but is not taken - (unreachable) - (unreachable) - ) - ) - ) - ) - (func $untaken-br_if (result i32) - (block $label$8 (result i32) - (block $label$9 - (drop - (if - (i32.const 0) - (br_if $label$8 - (unreachable) - (i32.const 0) - ) - (unreachable) - ) - ) - ) - ) - ) -) - diff --git a/test/polymorphic_stack.wast.from-wast b/test/polymorphic_stack.wast.from-wast deleted file mode 100644 index d0ac2834528..00000000000 --- a/test/polymorphic_stack.wast.from-wast +++ /dev/null @@ -1,135 +0,0 @@ -(module - (type $0 (func (result i32))) - (type $FUNCSIG$ii (func (param i32) (result i32))) - (type $2 (func)) - (type $3 (func (param i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (func $break-and-binary (type $0) (result i32) - (block $x (result i32) - (f32.add - (br_if $x - (i32.trunc_f64_u - (unreachable) - ) - (i32.trunc_f64_u - (unreachable) - ) - ) - (f32.const 1) - ) - ) - ) - (func $call-and-unary (type $FUNCSIG$ii) (param $0 i32) (result i32) - (drop - (i64.eqz - (call $call-and-unary - (unreachable) - ) - ) - ) - (drop - (i64.eqz - (i32.eqz - (unreachable) - ) - ) - ) - (drop - (i64.eqz - (call_indirect $timport$0 (type $FUNCSIG$ii) - (unreachable) - (unreachable) - ) - ) - ) - ) - (func $tee (type $3) (param $x i32) - (local $y f32) - (drop - (i64.eqz - (local.tee $x - (unreachable) - ) - ) - ) - (drop - (local.tee $y - (i64.eqz - (unreachable) - ) - ) - ) - ) - (func $tee2 (type $2) - (local $0 f32) - (if - (i32.const 259) - (local.tee $0 - (unreachable) - ) - ) - ) - (func $select (type $2) - (drop - (i64.eqz - (select - (unreachable) - (i32.const 1) - (i32.const 2) - ) - ) - ) - ) - (func $untaken-break-should-have-value (type $0) (result i32) - (block $x (result i32) - (block - (br_if $x - (i32.const 0) - (unreachable) - ) - ) - ) - ) - (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) - (if - (local.get $0) - (return - (i32.const 127) - ) - ) - (block $label$0 (result i32) - (br_if $label$0 - (i32.const 0) - (return - (i32.const -32) - ) - ) - ) - ) - (func $br_table_unreachable_to_also_unreachable (type $0) (result i32) - (block $a (result i32) - (block $b (result i32) - (br_table $a $b - (unreachable) - (unreachable) - ) - ) - ) - ) - (func $untaken-br_if (type $0) (result i32) - (block $label$8 (result i32) - (block $label$9 - (drop - (if - (i32.const 0) - (br_if $label$8 - (unreachable) - (i32.const 0) - ) - (unreachable) - ) - ) - ) - ) - ) -) diff --git a/test/polymorphic_stack.wast.fromBinary b/test/polymorphic_stack.wast.fromBinary deleted file mode 100644 index 652ecb7d986..00000000000 --- a/test/polymorphic_stack.wast.fromBinary +++ /dev/null @@ -1,76 +0,0 @@ -(module - (type $0 (func (result i32))) - (type $FUNCSIG$ii (func (param i32) (result i32))) - (type $2 (func)) - (type $3 (func (param i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (func $break-and-binary (type $0) (result i32) - (block $label$1 (result i32) - (unreachable) - ) - ) - (func $call-and-unary (type $FUNCSIG$ii) (param $0 i32) (result i32) - (unreachable) - ) - (func $tee (type $3) (param $x i32) - (local $y f32) - (unreachable) - ) - (func $tee2 (type $2) - (local $0 f32) - (if - (i32.const 259) - (unreachable) - ) - ) - (func $select (type $2) - (unreachable) - ) - (func $untaken-break-should-have-value (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 - (drop - (i32.const 0) - ) - (unreachable) - ) - (unreachable) - ) - ) - (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) - (if - (local.get $0) - (return - (i32.const 127) - ) - ) - (block $label$2 (result i32) - (drop - (i32.const 0) - ) - (return - (i32.const -32) - ) - ) - ) - (func $br_table_unreachable_to_also_unreachable (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 (result i32) - (unreachable) - ) - ) - ) - (func $untaken-br_if (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 - (if - (i32.const 0) - (unreachable) - (unreachable) - ) - ) - (unreachable) - ) - ) -) - diff --git a/test/polymorphic_stack.wast.fromBinary.noDebugInfo b/test/polymorphic_stack.wast.fromBinary.noDebugInfo deleted file mode 100644 index 0069e42547c..00000000000 --- a/test/polymorphic_stack.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,76 +0,0 @@ -(module - (type $0 (func (result i32))) - (type $1 (func (param i32) (result i32))) - (type $2 (func)) - (type $3 (func (param i32))) - (import "env" "table" (table $timport$0 9 9 funcref)) - (func $0 (type $0) (result i32) - (block $label$1 (result i32) - (unreachable) - ) - ) - (func $1 (type $1) (param $0 i32) (result i32) - (unreachable) - ) - (func $2 (type $3) (param $0 i32) - (local $1 f32) - (unreachable) - ) - (func $3 (type $2) - (local $0 f32) - (if - (i32.const 259) - (unreachable) - ) - ) - (func $4 (type $2) - (unreachable) - ) - (func $5 (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 - (drop - (i32.const 0) - ) - (unreachable) - ) - (unreachable) - ) - ) - (func $6 (type $1) (param $0 i32) (result i32) - (if - (local.get $0) - (return - (i32.const 127) - ) - ) - (block $label$2 (result i32) - (drop - (i32.const 0) - ) - (return - (i32.const -32) - ) - ) - ) - (func $7 (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 (result i32) - (unreachable) - ) - ) - ) - (func $8 (type $0) (result i32) - (block $label$1 (result i32) - (block $label$2 - (if - (i32.const 0) - (unreachable) - (unreachable) - ) - ) - (unreachable) - ) - ) -) - diff --git a/test/reference-types.wast b/test/reference-types.wast deleted file mode 100644 index 8706ac0c1fa..00000000000 --- a/test/reference-types.wast +++ /dev/null @@ -1,464 +0,0 @@ -(module - (type $sig_eqref (func (param eqref))) - (type $sig_funcref (func (param funcref))) - (type $sig_anyref (func (param anyref))) - - (func $take_eqref (param eqref)) - (func $take_funcref (param funcref)) - (func $take_anyref (param anyref)) - (func $foo) - - (table funcref (elem $take_eqref $take_funcref $take_anyref)) - (elem declare func $ref-taken-but-not-in-table) - - (import "env" "import_func" (func $import_func (param eqref) (result funcref))) - (import "env" "import_global" (global $import_global eqref)) - (export "export_func" (func $import_func (param eqref) (result funcref))) - (export "export_global" (global $import_global)) - - ;; Test global initializer expressions - (global $global_eqref (mut eqref) (ref.null eq)) - (global $global_funcref (mut funcref) (ref.null func)) - (global $global_funcref_func (mut funcref) (ref.func $foo)) - (global $global_anyref (mut anyref) (ref.null any)) - - ;; Test subtype relationship in global initializer expressions - (global $global_anyref2 (mut anyref) (ref.null eq)) - - (tag $e-i32 (param i32)) - - (func $test - (local $local_eqref eqref) - (local $local_funcref funcref) - (local $local_anyref anyref) - - ;; Test types for local.get/set - (local.set $local_eqref (local.get $local_eqref)) - (local.set $local_eqref (global.get $global_eqref)) - (local.set $local_eqref (ref.null eq)) - (local.set $local_funcref (local.get $local_funcref)) - (local.set $local_funcref (global.get $global_funcref)) - (local.set $local_funcref (ref.null func)) - (local.set $local_funcref (ref.func $foo)) - (local.set $local_anyref (local.get $local_anyref)) - (local.set $local_anyref (global.get $global_anyref)) - (local.set $local_anyref (ref.null any)) - - ;; Test subtype relationship for local.set - (local.set $local_anyref (local.get $local_eqref)) - (local.set $local_anyref (global.get $global_eqref)) - (local.set $local_anyref (ref.null eq)) - - ;; Test types for global.get/set - (global.set $global_eqref (global.get $global_eqref)) - (global.set $global_eqref (local.get $local_eqref)) - (global.set $global_eqref (ref.null eq)) - (global.set $global_funcref (global.get $global_funcref)) - (global.set $global_funcref (local.get $local_funcref)) - (global.set $global_funcref (ref.null func)) - (global.set $global_funcref (ref.func $foo)) - (global.set $global_anyref (global.get $global_anyref)) - (global.set $global_anyref (local.get $local_anyref)) - (global.set $global_anyref (ref.null any)) - - ;; Test subtype relationship for global.set - (global.set $global_anyref (global.get $global_eqref)) - (global.set $global_anyref (local.get $local_eqref)) - (global.set $global_anyref (ref.null eq)) - - ;; Test function call params - (call $take_eqref (local.get $local_eqref)) - (call $take_eqref (global.get $global_eqref)) - (call $take_eqref (ref.null eq)) - (call $take_funcref (local.get $local_funcref)) - (call $take_funcref (global.get $global_funcref)) - (call $take_funcref (ref.null func)) - (call $take_funcref (ref.func $foo)) - (call $take_anyref (local.get $local_anyref)) - (call $take_anyref (global.get $global_anyref)) - (call $take_anyref (ref.null any)) - - ;; Test subtype relationship for function call params - (call $take_anyref (local.get $local_eqref)) - (call $take_anyref (global.get $global_eqref)) - (call $take_anyref (ref.null eq)) - - ;; Test call_indirect params - (call_indirect (type $sig_eqref) (local.get $local_eqref) (i32.const 0)) - (call_indirect (type $sig_eqref) (global.get $global_eqref) (i32.const 0)) - (call_indirect (type $sig_eqref) (ref.null eq) (i32.const 0)) - (call_indirect (type $sig_funcref) (local.get $local_funcref) (i32.const 1)) - (call_indirect (type $sig_funcref) (global.get $global_funcref) (i32.const 1)) - (call_indirect (type $sig_funcref) (ref.null func) (i32.const 1)) - (call_indirect (type $sig_funcref) (ref.func $foo) (i32.const 1)) - (call_indirect (type $sig_anyref) (local.get $local_anyref) (i32.const 3)) - (call_indirect (type $sig_anyref) (global.get $global_anyref) (i32.const 3)) - (call_indirect (type $sig_anyref) (ref.null any) (i32.const 3)) - - ;; Test subtype relationship for call_indirect params - (call_indirect (type $sig_anyref) (local.get $local_eqref) (i32.const 3)) - (call_indirect (type $sig_anyref) (global.get $global_eqref) (i32.const 3)) - (call_indirect (type $sig_anyref) (ref.null eq) (i32.const 3)) - - ;; Test block return type - (drop - (block (result eqref) - (br_if 0 (local.get $local_eqref) (i32.const 1)) - ) - ) - (drop - (block (result eqref) - (br_if 0 (global.get $global_eqref) (i32.const 1)) - ) - ) - (drop - (block (result eqref) - (br_if 0 (ref.null eq) (i32.const 1)) - ) - ) - (drop - (block (result funcref) - (br_if 0 (local.get $local_funcref) (i32.const 1)) - ) - ) - (drop - (block (result funcref) - (br_if 0 (global.get $global_funcref) (i32.const 1)) - ) - ) - (drop - (block (result funcref) - (br_if 0 (ref.null func) (i32.const 1)) - ) - ) - (drop - (block (result funcref) - (br_if 0 (ref.func $foo) (i32.const 1)) - ) - ) - (drop - (block (result anyref) - (br_if 0 (local.get $local_anyref) (i32.const 1)) - ) - ) - (drop - (block (result anyref) - (br_if 0 (global.get $global_anyref) (i32.const 1)) - ) - ) - (drop - (block (result anyref) - (br_if 0 (ref.null any) (i32.const 1)) - ) - ) - - ;; Test subtype relationship for block return type - (drop - (block (result anyref) - (br_if 0 (local.get $local_eqref) (i32.const 1)) - ) - ) - (drop - (block (result anyref) - (br_if 0 (ref.null eq) (i32.const 1)) - ) - ) - - ;; Test loop return type - (drop - (loop (result eqref) - (local.get $local_eqref) - ) - ) - (drop - (loop (result eqref) - (global.get $global_eqref) - ) - ) - (drop - (loop (result eqref) - (ref.null eq) - ) - ) - (drop - (loop (result funcref) - (local.get $local_funcref) - ) - ) - (drop - (loop (result funcref) - (global.get $global_funcref) - ) - ) - (drop - (loop (result funcref) - (ref.null func) - ) - ) - (drop - (loop (result funcref) - (ref.func $foo) - ) - ) - (drop - (loop (result anyref) - (local.get $local_anyref) - ) - ) - (drop - (loop (result anyref) - (global.get $global_anyref) - ) - ) - (drop - (loop (result anyref) - (ref.null any) - ) - ) - - ;; Test subtype relationship for loop return type - (drop - (loop (result anyref) - (local.get $local_eqref) - ) - ) - (drop - (loop (result anyref) - (global.get $global_eqref) - ) - ) - (drop - (loop (result anyref) - (ref.null eq) - ) - ) - - ;; Test if return type - (drop - (if (result eqref) - (i32.const 1) - (local.get $local_eqref) - (ref.null eq) - ) - ) - (drop - (if (result funcref) - (i32.const 1) - (local.get $local_funcref) - (ref.null func) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_anyref) - (ref.null any) - ) - ) - - ;; Test subtype relationship for if return type - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_eqref) - (local.get $local_eqref) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.null eq) - (ref.null i31) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.i31 - (i32.const 0) - ) - (ref.null eq) - ) - ) - - ;; Test try return type - (drop - (try (result eqref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop (pop i32)) - (ref.null eq) - ) - ) - ) - (drop - (try (result funcref) - (do - (ref.func $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (ref.null func) - ) - ) - ) - - ;; Test subtype relationship for try return type - (drop - (try (result anyref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop (pop i32)) - (ref.null any) - ) - ) - ) - (drop - (try (result anyref) - (do - (ref.null eq) - ) - (catch $e-i32 - (drop (pop i32)) - (local.get $local_eqref) - ) - ) - ) - - ;; Test typed select - (drop - (select (result eqref) - (local.get $local_eqref) - (ref.null eq) - (i32.const 1) - ) - ) - (drop - (select (result funcref) - (local.get $local_funcref) - (ref.null func) - (i32.const 1) - ) - ) - (drop - (select (result i32) - (i32.const 0) - (i32.const 2) - (i32.const 1) - ) - ) - - ;; Test subtype relationship for typed select - (drop - (select (result anyref) - (local.get $local_eqref) - (ref.i31 - (i32.const 0) - ) - (i32.const 1) - ) - ) - - ;; ref.is_null takes any reference types - (drop (ref.is_null (local.get $local_eqref))) - (drop (ref.is_null (global.get $global_eqref))) - (drop (ref.is_null (ref.null eq))) - (drop (ref.is_null (local.get $local_funcref))) - (drop (ref.is_null (global.get $global_funcref))) - (drop (ref.is_null (ref.null func))) - (drop (ref.is_null (ref.func $foo))) - (drop (ref.is_null (local.get $local_anyref))) - (drop (ref.is_null (global.get $global_anyref))) - (drop (ref.is_null (ref.null any))) - ) - - ;; Test function return type - (func $return_eqref_local (result eqref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_eqref_global (result eqref) - (global.get $global_eqref) - ) - (func $return_eqref_null (result eqref) - (ref.null eq) - ) - (func $return_funcref_local (result funcref) - (local $local_funcref funcref) - (local.get $local_funcref) - ) - (func $return_funcref_global (result funcref) - (global.get $global_funcref) - ) - (func $return_funcref_null (result funcref) - (ref.null func) - ) - (func $return_funcref_func (result funcref) - (ref.func $foo) - ) - (func $return_anyref_local (result anyref) - (local $local_anyref anyref) - (local.get $local_anyref) - ) - (func $return_anyref_global (result anyref) - (global.get $global_anyref) - ) - (func $return_anyref_null (result anyref) - (ref.null any) - ) - - ;; Test subtype relationship in function return type - (func $return_anyref2 (result anyref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_anyref3 (result anyref) - (global.get $global_eqref) - ) - (func $return_anyref4 (result anyref) - (ref.null eq) - ) - - ;; Test returns - (func $returns_eqref (result eqref) - (local $local_eqref eqref) - (return (local.get $local_eqref)) - (return (global.get $global_eqref)) - (return (ref.null eq)) - ) - (func $returns_funcref (result funcref) - (local $local_funcref funcref) - (return (local.get $local_funcref)) - (return (global.get $global_funcref)) - (return (ref.func $foo)) - (return (ref.null func)) - ) - (func $returns_anyref (result anyref) - (local $local_anyref anyref) - (return (local.get $local_anyref)) - (return (global.get $global_anyref)) - (return (ref.null any)) - ) - - ;; Test subtype relationship in returns - (func $returns_anyref2 (result anyref) - (local $local_eqref eqref) - (local $local_funcref funcref) - (return (local.get $local_eqref)) - (return (global.get $global_eqref)) - (return (ref.null eq)) - ) - - (func $ref-user - (drop - ;; an "elem declare func" must be emitted for this ref.func which is not - ;; in the table - (ref.func $ref-taken-but-not-in-table) - ) - ) - (func $ref-taken-but-not-in-table) -) diff --git a/test/reference-types.wast.from-wast b/test/reference-types.wast.from-wast deleted file mode 100644 index 6a05ce40c5d..00000000000 --- a/test/reference-types.wast.from-wast +++ /dev/null @@ -1,650 +0,0 @@ -(module - (type $0 (func (result anyref))) - (type $sig_anyref (func (param anyref))) - (type $sig_funcref (func (param funcref))) - (type $3 (func (result funcref))) - (type $sig_eqref (func (param eqref))) - (type $5 (func)) - (type $6 (func (result eqref))) - (type $7 (func (param i32))) - (type $8 (func (param eqref) (result funcref))) - (import "env" "import_global" (global $import_global eqref)) - (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref))) - (global $global_eqref (mut eqref) (ref.null none)) - (global $global_funcref (mut funcref) (ref.null nofunc)) - (global $global_funcref_func (mut funcref) (ref.func $foo)) - (global $global_anyref (mut anyref) (ref.null none)) - (global $global_anyref2 (mut anyref) (ref.null none)) - (table $0 3 3 funcref) - (elem $0 (i32.const 0) $take_eqref $take_funcref $take_anyref) - (elem declare func $foo $ref-taken-but-not-in-table) - (tag $e-i32 (param i32)) - (export "export_func" (func $import_func)) - (export "export_global" (global $import_global)) - (func $take_eqref (type $sig_eqref) (param $0 eqref) - (nop) - ) - (func $take_funcref (type $sig_funcref) (param $0 funcref) - (nop) - ) - (func $take_anyref (type $sig_anyref) (param $0 anyref) - (nop) - ) - (func $foo (type $5) - (nop) - ) - (func $test (type $5) - (local $local_eqref eqref) - (local $local_funcref funcref) - (local $local_anyref anyref) - (local.set $local_eqref - (local.get $local_eqref) - ) - (local.set $local_eqref - (global.get $global_eqref) - ) - (local.set $local_eqref - (ref.null none) - ) - (local.set $local_funcref - (local.get $local_funcref) - ) - (local.set $local_funcref - (global.get $global_funcref) - ) - (local.set $local_funcref - (ref.null nofunc) - ) - (local.set $local_funcref - (ref.func $foo) - ) - (local.set $local_anyref - (local.get $local_anyref) - ) - (local.set $local_anyref - (global.get $global_anyref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_anyref - (local.get $local_eqref) - ) - (local.set $local_anyref - (global.get $global_eqref) - ) - (local.set $local_anyref - (ref.null none) - ) - (global.set $global_eqref - (global.get $global_eqref) - ) - (global.set $global_eqref - (local.get $local_eqref) - ) - (global.set $global_eqref - (ref.null none) - ) - (global.set $global_funcref - (global.get $global_funcref) - ) - (global.set $global_funcref - (local.get $local_funcref) - ) - (global.set $global_funcref - (ref.null nofunc) - ) - (global.set $global_funcref - (ref.func $foo) - ) - (global.set $global_anyref - (global.get $global_anyref) - ) - (global.set $global_anyref - (local.get $local_anyref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_anyref - (global.get $global_eqref) - ) - (global.set $global_anyref - (local.get $local_eqref) - ) - (global.set $global_anyref - (ref.null none) - ) - (call $take_eqref - (local.get $local_eqref) - ) - (call $take_eqref - (global.get $global_eqref) - ) - (call $take_eqref - (ref.null none) - ) - (call $take_funcref - (local.get $local_funcref) - ) - (call $take_funcref - (global.get $global_funcref) - ) - (call $take_funcref - (ref.null nofunc) - ) - (call $take_funcref - (ref.func $foo) - ) - (call $take_anyref - (local.get $local_anyref) - ) - (call $take_anyref - (global.get $global_anyref) - ) - (call $take_anyref - (ref.null none) - ) - (call $take_anyref - (local.get $local_eqref) - ) - (call $take_anyref - (global.get $global_eqref) - ) - (call $take_anyref - (ref.null none) - ) - (call_indirect $0 (type $sig_eqref) - (local.get $local_eqref) - (i32.const 0) - ) - (call_indirect $0 (type $sig_eqref) - (global.get $global_eqref) - (i32.const 0) - ) - (call_indirect $0 (type $sig_eqref) - (ref.null none) - (i32.const 0) - ) - (call_indirect $0 (type $sig_funcref) - (local.get $local_funcref) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (global.get $global_funcref) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (ref.null nofunc) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (ref.func $foo) - (i32.const 1) - ) - (call_indirect $0 (type $sig_anyref) - (local.get $local_anyref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (global.get $global_anyref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (ref.null none) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (local.get $local_eqref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (global.get $global_eqref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (ref.null none) - (i32.const 3) - ) - (drop - (block $block (result eqref) - (br_if $block - (local.get $local_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $block0 (result eqref) - (br_if $block0 - (global.get $global_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $block1 (result eqref) - (br_if $block1 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $block2 (result funcref) - (br_if $block2 - (local.get $local_funcref) - (i32.const 1) - ) - ) - ) - (drop - (block $block3 (result funcref) - (br_if $block3 - (global.get $global_funcref) - (i32.const 1) - ) - ) - ) - (drop - (block $block4 (result funcref) - (br_if $block4 - (ref.null nofunc) - (i32.const 1) - ) - ) - ) - (drop - (block $block5 (result funcref) - (br_if $block5 - (ref.func $foo) - (i32.const 1) - ) - ) - ) - (drop - (block $block6 (result anyref) - (br_if $block6 - (local.get $local_anyref) - (i32.const 1) - ) - ) - ) - (drop - (block $block7 (result anyref) - (br_if $block7 - (global.get $global_anyref) - (i32.const 1) - ) - ) - ) - (drop - (block $block8 (result anyref) - (br_if $block8 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $block9 (result anyref) - (br_if $block9 - (local.get $local_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $block10 (result anyref) - (br_if $block10 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (loop $loop-in (result eqref) - (local.get $local_eqref) - ) - ) - (drop - (loop $loop-in11 (result eqref) - (global.get $global_eqref) - ) - ) - (drop - (loop $loop-in12 (result eqref) - (ref.null none) - ) - ) - (drop - (loop $loop-in13 (result funcref) - (local.get $local_funcref) - ) - ) - (drop - (loop $loop-in14 (result funcref) - (global.get $global_funcref) - ) - ) - (drop - (loop $loop-in15 (result funcref) - (ref.null nofunc) - ) - ) - (drop - (loop $loop-in16 (result funcref) - (ref.func $foo) - ) - ) - (drop - (loop $loop-in17 (result anyref) - (local.get $local_anyref) - ) - ) - (drop - (loop $loop-in18 (result anyref) - (global.get $global_anyref) - ) - ) - (drop - (loop $loop-in19 (result anyref) - (ref.null none) - ) - ) - (drop - (loop $loop-in20 (result anyref) - (local.get $local_eqref) - ) - ) - (drop - (loop $loop-in21 (result anyref) - (global.get $global_eqref) - ) - ) - (drop - (loop $loop-in22 (result anyref) - (ref.null none) - ) - ) - (drop - (if (result eqref) - (i32.const 1) - (local.get $local_eqref) - (ref.null none) - ) - ) - (drop - (if (result funcref) - (i32.const 1) - (local.get $local_funcref) - (ref.null nofunc) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_anyref) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_eqref) - (local.get $local_eqref) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.null none) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.i31 - (i32.const 0) - ) - (ref.null none) - ) - ) - (drop - (try $try (result eqref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $try28 (result funcref) - (do - (ref.func $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null nofunc) - ) - ) - ) - (drop - (try $try29 (result anyref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $try30 (result anyref) - (do - (ref.null none) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (local.get $local_eqref) - ) - ) - ) - (drop - (select (result eqref) - (local.get $local_eqref) - (ref.null none) - (i32.const 1) - ) - ) - (drop - (select (result funcref) - (local.get $local_funcref) - (ref.null nofunc) - (i32.const 1) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 2) - (i32.const 1) - ) - ) - (drop - (select (result anyref) - (local.get $local_eqref) - (ref.i31 - (i32.const 0) - ) - (i32.const 1) - ) - ) - (drop - (ref.is_null - (local.get $local_eqref) - ) - ) - (drop - (ref.is_null - (global.get $global_eqref) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - (drop - (ref.is_null - (local.get $local_funcref) - ) - ) - (drop - (ref.is_null - (global.get $global_funcref) - ) - ) - (drop - (ref.is_null - (ref.null nofunc) - ) - ) - (drop - (ref.is_null - (ref.func $foo) - ) - ) - (drop - (ref.is_null - (local.get $local_anyref) - ) - ) - (drop - (ref.is_null - (global.get $global_anyref) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - ) - (func $return_eqref_local (type $6) (result eqref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_eqref_global (type $6) (result eqref) - (global.get $global_eqref) - ) - (func $return_eqref_null (type $6) (result eqref) - (ref.null none) - ) - (func $return_funcref_local (type $3) (result funcref) - (local $local_funcref funcref) - (local.get $local_funcref) - ) - (func $return_funcref_global (type $3) (result funcref) - (global.get $global_funcref) - ) - (func $return_funcref_null (type $3) (result funcref) - (ref.null nofunc) - ) - (func $return_funcref_func (type $3) (result funcref) - (ref.func $foo) - ) - (func $return_anyref_local (type $0) (result anyref) - (local $local_anyref anyref) - (local.get $local_anyref) - ) - (func $return_anyref_global (type $0) (result anyref) - (global.get $global_anyref) - ) - (func $return_anyref_null (type $0) (result anyref) - (ref.null none) - ) - (func $return_anyref2 (type $0) (result anyref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_anyref3 (type $0) (result anyref) - (global.get $global_eqref) - ) - (func $return_anyref4 (type $0) (result anyref) - (ref.null none) - ) - (func $returns_eqref (type $6) (result eqref) - (local $local_eqref eqref) - (return - (local.get $local_eqref) - ) - (return - (global.get $global_eqref) - ) - (return - (ref.null none) - ) - ) - (func $returns_funcref (type $3) (result funcref) - (local $local_funcref funcref) - (return - (local.get $local_funcref) - ) - (return - (global.get $global_funcref) - ) - (return - (ref.func $foo) - ) - (return - (ref.null nofunc) - ) - ) - (func $returns_anyref (type $0) (result anyref) - (local $local_anyref anyref) - (return - (local.get $local_anyref) - ) - (return - (global.get $global_anyref) - ) - (return - (ref.null none) - ) - ) - (func $returns_anyref2 (type $0) (result anyref) - (local $local_eqref eqref) - (local $local_funcref funcref) - (return - (local.get $local_eqref) - ) - (return - (global.get $global_eqref) - ) - (return - (ref.null none) - ) - ) - (func $ref-user (type $5) - (drop - (ref.func $ref-taken-but-not-in-table) - ) - ) - (func $ref-taken-but-not-in-table (type $5) - (nop) - ) -) diff --git a/test/reference-types.wast.fromBinary b/test/reference-types.wast.fromBinary deleted file mode 100644 index 0ce71eb3851..00000000000 --- a/test/reference-types.wast.fromBinary +++ /dev/null @@ -1,624 +0,0 @@ -(module - (type $0 (func (result anyref))) - (type $sig_anyref (func (param anyref))) - (type $sig_funcref (func (param funcref))) - (type $3 (func (result funcref))) - (type $sig_eqref (func (param eqref))) - (type $5 (func)) - (type $6 (func (result eqref))) - (type $7 (func (param i32))) - (type $8 (func (param eqref) (result funcref))) - (import "env" "import_global" (global $import_global eqref)) - (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref))) - (global $global_eqref (mut eqref) (ref.null none)) - (global $global_funcref (mut funcref) (ref.null nofunc)) - (global $global_funcref_func (mut funcref) (ref.func $foo)) - (global $global_anyref (mut anyref) (ref.null none)) - (global $global_anyref2 (mut anyref) (ref.null none)) - (table $0 3 3 funcref) - (elem $0 (i32.const 0) $take_eqref $take_funcref $take_anyref) - (elem declare func $foo $ref-taken-but-not-in-table) - (tag $e-i32 (param i32)) - (export "export_func" (func $import_func)) - (export "export_global" (global $import_global)) - (func $take_eqref (type $sig_eqref) (param $0 eqref) - (nop) - ) - (func $take_funcref (type $sig_funcref) (param $0 funcref) - (nop) - ) - (func $take_anyref (type $sig_anyref) (param $0 anyref) - (nop) - ) - (func $foo (type $5) - (nop) - ) - (func $test (type $5) - (local $local_eqref eqref) - (local $local_funcref funcref) - (local $local_anyref anyref) - (local.set $local_eqref - (local.get $local_eqref) - ) - (local.set $local_eqref - (global.get $global_eqref) - ) - (local.set $local_eqref - (ref.null none) - ) - (local.set $local_funcref - (local.get $local_funcref) - ) - (local.set $local_funcref - (global.get $global_funcref) - ) - (local.set $local_funcref - (ref.null nofunc) - ) - (local.set $local_funcref - (ref.func $foo) - ) - (local.set $local_anyref - (local.get $local_anyref) - ) - (local.set $local_anyref - (global.get $global_anyref) - ) - (local.set $local_anyref - (ref.null none) - ) - (local.set $local_anyref - (local.get $local_eqref) - ) - (local.set $local_anyref - (global.get $global_eqref) - ) - (local.set $local_anyref - (ref.null none) - ) - (global.set $global_eqref - (global.get $global_eqref) - ) - (global.set $global_eqref - (local.get $local_eqref) - ) - (global.set $global_eqref - (ref.null none) - ) - (global.set $global_funcref - (global.get $global_funcref) - ) - (global.set $global_funcref - (local.get $local_funcref) - ) - (global.set $global_funcref - (ref.null nofunc) - ) - (global.set $global_funcref - (ref.func $foo) - ) - (global.set $global_anyref - (global.get $global_anyref) - ) - (global.set $global_anyref - (local.get $local_anyref) - ) - (global.set $global_anyref - (ref.null none) - ) - (global.set $global_anyref - (global.get $global_eqref) - ) - (global.set $global_anyref - (local.get $local_eqref) - ) - (global.set $global_anyref - (ref.null none) - ) - (call $take_eqref - (local.get $local_eqref) - ) - (call $take_eqref - (global.get $global_eqref) - ) - (call $take_eqref - (ref.null none) - ) - (call $take_funcref - (local.get $local_funcref) - ) - (call $take_funcref - (global.get $global_funcref) - ) - (call $take_funcref - (ref.null nofunc) - ) - (call $take_funcref - (ref.func $foo) - ) - (call $take_anyref - (local.get $local_anyref) - ) - (call $take_anyref - (global.get $global_anyref) - ) - (call $take_anyref - (ref.null none) - ) - (call $take_anyref - (local.get $local_eqref) - ) - (call $take_anyref - (global.get $global_eqref) - ) - (call $take_anyref - (ref.null none) - ) - (call_indirect $0 (type $sig_eqref) - (local.get $local_eqref) - (i32.const 0) - ) - (call_indirect $0 (type $sig_eqref) - (global.get $global_eqref) - (i32.const 0) - ) - (call_indirect $0 (type $sig_eqref) - (ref.null none) - (i32.const 0) - ) - (call_indirect $0 (type $sig_funcref) - (local.get $local_funcref) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (global.get $global_funcref) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (ref.null nofunc) - (i32.const 1) - ) - (call_indirect $0 (type $sig_funcref) - (ref.func $foo) - (i32.const 1) - ) - (call_indirect $0 (type $sig_anyref) - (local.get $local_anyref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (global.get $global_anyref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (ref.null none) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (local.get $local_eqref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (global.get $global_eqref) - (i32.const 3) - ) - (call_indirect $0 (type $sig_anyref) - (ref.null none) - (i32.const 3) - ) - (drop - (block $label$1 (result eqref) - (br_if $label$1 - (local.get $local_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$2 (result eqref) - (br_if $label$2 - (global.get $global_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$3 (result eqref) - (br_if $label$3 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $label$4 (result funcref) - (br_if $label$4 - (local.get $local_funcref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$5 (result funcref) - (br_if $label$5 - (global.get $global_funcref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$6 (result funcref) - (br_if $label$6 - (ref.null nofunc) - (i32.const 1) - ) - ) - ) - (drop - (block $label$7 (result funcref) - (br_if $label$7 - (ref.func $foo) - (i32.const 1) - ) - ) - ) - (drop - (block $label$8 (result anyref) - (br_if $label$8 - (local.get $local_anyref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$9 (result anyref) - (br_if $label$9 - (global.get $global_anyref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$10 (result anyref) - (br_if $label$10 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $label$11 (result anyref) - (br_if $label$11 - (local.get $local_eqref) - (i32.const 1) - ) - ) - ) - (drop - (block $label$12 (result anyref) - (br_if $label$12 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (loop $label$13 (result eqref) - (local.get $local_eqref) - ) - ) - (drop - (loop $label$14 (result eqref) - (global.get $global_eqref) - ) - ) - (drop - (loop $label$15 (result eqref) - (ref.null none) - ) - ) - (drop - (loop $label$16 (result funcref) - (local.get $local_funcref) - ) - ) - (drop - (loop $label$17 (result funcref) - (global.get $global_funcref) - ) - ) - (drop - (loop $label$18 (result funcref) - (ref.null nofunc) - ) - ) - (drop - (loop $label$19 (result funcref) - (ref.func $foo) - ) - ) - (drop - (loop $label$20 (result anyref) - (local.get $local_anyref) - ) - ) - (drop - (loop $label$21 (result anyref) - (global.get $global_anyref) - ) - ) - (drop - (loop $label$22 (result anyref) - (ref.null none) - ) - ) - (drop - (loop $label$23 (result anyref) - (local.get $local_eqref) - ) - ) - (drop - (loop $label$24 (result anyref) - (global.get $global_eqref) - ) - ) - (drop - (loop $label$25 (result anyref) - (ref.null none) - ) - ) - (drop - (if (result eqref) - (i32.const 1) - (local.get $local_eqref) - (ref.null none) - ) - ) - (drop - (if (result funcref) - (i32.const 1) - (local.get $local_funcref) - (ref.null nofunc) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_anyref) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $local_eqref) - (local.get $local_eqref) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.null none) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.i31 - (i32.const 0) - ) - (ref.null none) - ) - ) - (drop - (try $label$40 (result eqref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $label$43 (result funcref) - (do - (ref.func $foo) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null nofunc) - ) - ) - ) - (drop - (try $label$46 (result anyref) - (do - (local.get $local_eqref) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $label$49 (result anyref) - (do - (ref.null none) - ) - (catch $e-i32 - (drop - (pop i32) - ) - (local.get $local_eqref) - ) - ) - ) - (drop - (select (result eqref) - (local.get $local_eqref) - (ref.null none) - (i32.const 1) - ) - ) - (drop - (select (result funcref) - (local.get $local_funcref) - (ref.null nofunc) - (i32.const 1) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 2) - (i32.const 1) - ) - ) - (drop - (select (result anyref) - (local.get $local_eqref) - (ref.i31 - (i32.const 0) - ) - (i32.const 1) - ) - ) - (drop - (ref.is_null - (local.get $local_eqref) - ) - ) - (drop - (ref.is_null - (global.get $global_eqref) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - (drop - (ref.is_null - (local.get $local_funcref) - ) - ) - (drop - (ref.is_null - (global.get $global_funcref) - ) - ) - (drop - (ref.is_null - (ref.null nofunc) - ) - ) - (drop - (ref.is_null - (ref.func $foo) - ) - ) - (drop - (ref.is_null - (local.get $local_anyref) - ) - ) - (drop - (ref.is_null - (global.get $global_anyref) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - ) - (func $return_eqref_local (type $6) (result eqref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_eqref_global (type $6) (result eqref) - (global.get $global_eqref) - ) - (func $return_eqref_null (type $6) (result eqref) - (ref.null none) - ) - (func $return_funcref_local (type $3) (result funcref) - (local $local_funcref funcref) - (local.get $local_funcref) - ) - (func $return_funcref_global (type $3) (result funcref) - (global.get $global_funcref) - ) - (func $return_funcref_null (type $3) (result funcref) - (ref.null nofunc) - ) - (func $return_funcref_func (type $3) (result funcref) - (ref.func $foo) - ) - (func $return_anyref_local (type $0) (result anyref) - (local $local_anyref anyref) - (local.get $local_anyref) - ) - (func $return_anyref_global (type $0) (result anyref) - (global.get $global_anyref) - ) - (func $return_anyref_null (type $0) (result anyref) - (ref.null none) - ) - (func $return_anyref2 (type $0) (result anyref) - (local $local_eqref eqref) - (local.get $local_eqref) - ) - (func $return_anyref3 (type $0) (result anyref) - (global.get $global_eqref) - ) - (func $return_anyref4 (type $0) (result anyref) - (ref.null none) - ) - (func $returns_eqref (type $6) (result eqref) - (local $local_eqref eqref) - (return - (local.get $local_eqref) - ) - ) - (func $returns_funcref (type $3) (result funcref) - (local $local_funcref funcref) - (return - (local.get $local_funcref) - ) - ) - (func $returns_anyref (type $0) (result anyref) - (local $local_anyref anyref) - (return - (local.get $local_anyref) - ) - ) - (func $returns_anyref2 (type $0) (result anyref) - (local $local_eqref eqref) - (local $local_funcref funcref) - (return - (local.get $local_eqref) - ) - ) - (func $ref-user (type $5) - (drop - (ref.func $ref-taken-but-not-in-table) - ) - ) - (func $ref-taken-but-not-in-table (type $5) - (nop) - ) -) - diff --git a/test/reference-types.wast.fromBinary.noDebugInfo b/test/reference-types.wast.fromBinary.noDebugInfo deleted file mode 100644 index 983dc58fe76..00000000000 --- a/test/reference-types.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,624 +0,0 @@ -(module - (type $0 (func (result anyref))) - (type $1 (func (param anyref))) - (type $2 (func (param funcref))) - (type $3 (func (result funcref))) - (type $4 (func (param eqref))) - (type $5 (func)) - (type $6 (func (result eqref))) - (type $7 (func (param i32))) - (type $8 (func (param eqref) (result funcref))) - (import "env" "import_global" (global $gimport$0 eqref)) - (import "env" "import_func" (func $fimport$0 (type $8) (param eqref) (result funcref))) - (global $global$0 (mut eqref) (ref.null none)) - (global $global$1 (mut funcref) (ref.null nofunc)) - (global $global$2 (mut funcref) (ref.func $3)) - (global $global$3 (mut anyref) (ref.null none)) - (global $global$4 (mut anyref) (ref.null none)) - (table $0 3 3 funcref) - (elem $0 (i32.const 0) $0 $1 $2) - (elem declare func $23 $3) - (tag $tag$0 (param i32)) - (export "export_func" (func $fimport$0)) - (export "export_global" (global $gimport$0)) - (func $0 (type $4) (param $0 eqref) - (nop) - ) - (func $1 (type $2) (param $0 funcref) - (nop) - ) - (func $2 (type $1) (param $0 anyref) - (nop) - ) - (func $3 (type $5) - (nop) - ) - (func $4 (type $5) - (local $0 eqref) - (local $1 funcref) - (local $2 anyref) - (local.set $0 - (local.get $0) - ) - (local.set $0 - (global.get $global$0) - ) - (local.set $0 - (ref.null none) - ) - (local.set $1 - (local.get $1) - ) - (local.set $1 - (global.get $global$1) - ) - (local.set $1 - (ref.null nofunc) - ) - (local.set $1 - (ref.func $3) - ) - (local.set $2 - (local.get $2) - ) - (local.set $2 - (global.get $global$3) - ) - (local.set $2 - (ref.null none) - ) - (local.set $2 - (local.get $0) - ) - (local.set $2 - (global.get $global$0) - ) - (local.set $2 - (ref.null none) - ) - (global.set $global$0 - (global.get $global$0) - ) - (global.set $global$0 - (local.get $0) - ) - (global.set $global$0 - (ref.null none) - ) - (global.set $global$1 - (global.get $global$1) - ) - (global.set $global$1 - (local.get $1) - ) - (global.set $global$1 - (ref.null nofunc) - ) - (global.set $global$1 - (ref.func $3) - ) - (global.set $global$3 - (global.get $global$3) - ) - (global.set $global$3 - (local.get $2) - ) - (global.set $global$3 - (ref.null none) - ) - (global.set $global$3 - (global.get $global$0) - ) - (global.set $global$3 - (local.get $0) - ) - (global.set $global$3 - (ref.null none) - ) - (call $0 - (local.get $0) - ) - (call $0 - (global.get $global$0) - ) - (call $0 - (ref.null none) - ) - (call $1 - (local.get $1) - ) - (call $1 - (global.get $global$1) - ) - (call $1 - (ref.null nofunc) - ) - (call $1 - (ref.func $3) - ) - (call $2 - (local.get $2) - ) - (call $2 - (global.get $global$3) - ) - (call $2 - (ref.null none) - ) - (call $2 - (local.get $0) - ) - (call $2 - (global.get $global$0) - ) - (call $2 - (ref.null none) - ) - (call_indirect $0 (type $4) - (local.get $0) - (i32.const 0) - ) - (call_indirect $0 (type $4) - (global.get $global$0) - (i32.const 0) - ) - (call_indirect $0 (type $4) - (ref.null none) - (i32.const 0) - ) - (call_indirect $0 (type $2) - (local.get $1) - (i32.const 1) - ) - (call_indirect $0 (type $2) - (global.get $global$1) - (i32.const 1) - ) - (call_indirect $0 (type $2) - (ref.null nofunc) - (i32.const 1) - ) - (call_indirect $0 (type $2) - (ref.func $3) - (i32.const 1) - ) - (call_indirect $0 (type $1) - (local.get $2) - (i32.const 3) - ) - (call_indirect $0 (type $1) - (global.get $global$3) - (i32.const 3) - ) - (call_indirect $0 (type $1) - (ref.null none) - (i32.const 3) - ) - (call_indirect $0 (type $1) - (local.get $0) - (i32.const 3) - ) - (call_indirect $0 (type $1) - (global.get $global$0) - (i32.const 3) - ) - (call_indirect $0 (type $1) - (ref.null none) - (i32.const 3) - ) - (drop - (block $label$1 (result eqref) - (br_if $label$1 - (local.get $0) - (i32.const 1) - ) - ) - ) - (drop - (block $label$2 (result eqref) - (br_if $label$2 - (global.get $global$0) - (i32.const 1) - ) - ) - ) - (drop - (block $label$3 (result eqref) - (br_if $label$3 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $label$4 (result funcref) - (br_if $label$4 - (local.get $1) - (i32.const 1) - ) - ) - ) - (drop - (block $label$5 (result funcref) - (br_if $label$5 - (global.get $global$1) - (i32.const 1) - ) - ) - ) - (drop - (block $label$6 (result funcref) - (br_if $label$6 - (ref.null nofunc) - (i32.const 1) - ) - ) - ) - (drop - (block $label$7 (result funcref) - (br_if $label$7 - (ref.func $3) - (i32.const 1) - ) - ) - ) - (drop - (block $label$8 (result anyref) - (br_if $label$8 - (local.get $2) - (i32.const 1) - ) - ) - ) - (drop - (block $label$9 (result anyref) - (br_if $label$9 - (global.get $global$3) - (i32.const 1) - ) - ) - ) - (drop - (block $label$10 (result anyref) - (br_if $label$10 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (block $label$11 (result anyref) - (br_if $label$11 - (local.get $0) - (i32.const 1) - ) - ) - ) - (drop - (block $label$12 (result anyref) - (br_if $label$12 - (ref.null none) - (i32.const 1) - ) - ) - ) - (drop - (loop $label$13 (result eqref) - (local.get $0) - ) - ) - (drop - (loop $label$14 (result eqref) - (global.get $global$0) - ) - ) - (drop - (loop $label$15 (result eqref) - (ref.null none) - ) - ) - (drop - (loop $label$16 (result funcref) - (local.get $1) - ) - ) - (drop - (loop $label$17 (result funcref) - (global.get $global$1) - ) - ) - (drop - (loop $label$18 (result funcref) - (ref.null nofunc) - ) - ) - (drop - (loop $label$19 (result funcref) - (ref.func $3) - ) - ) - (drop - (loop $label$20 (result anyref) - (local.get $2) - ) - ) - (drop - (loop $label$21 (result anyref) - (global.get $global$3) - ) - ) - (drop - (loop $label$22 (result anyref) - (ref.null none) - ) - ) - (drop - (loop $label$23 (result anyref) - (local.get $0) - ) - ) - (drop - (loop $label$24 (result anyref) - (global.get $global$0) - ) - ) - (drop - (loop $label$25 (result anyref) - (ref.null none) - ) - ) - (drop - (if (result eqref) - (i32.const 1) - (local.get $0) - (ref.null none) - ) - ) - (drop - (if (result funcref) - (i32.const 1) - (local.get $1) - (ref.null nofunc) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $2) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (local.get $0) - (local.get $0) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.null none) - (ref.null none) - ) - ) - (drop - (if (result anyref) - (i32.const 1) - (ref.i31 - (i32.const 0) - ) - (ref.null none) - ) - ) - (drop - (try $label$40 (result eqref) - (do - (local.get $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $label$43 (result funcref) - (do - (ref.func $3) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (ref.null nofunc) - ) - ) - ) - (drop - (try $label$46 (result anyref) - (do - (local.get $0) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (ref.null none) - ) - ) - ) - (drop - (try $label$49 (result anyref) - (do - (ref.null none) - ) - (catch $tag$0 - (drop - (pop i32) - ) - (local.get $0) - ) - ) - ) - (drop - (select (result eqref) - (local.get $0) - (ref.null none) - (i32.const 1) - ) - ) - (drop - (select (result funcref) - (local.get $1) - (ref.null nofunc) - (i32.const 1) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 2) - (i32.const 1) - ) - ) - (drop - (select (result anyref) - (local.get $0) - (ref.i31 - (i32.const 0) - ) - (i32.const 1) - ) - ) - (drop - (ref.is_null - (local.get $0) - ) - ) - (drop - (ref.is_null - (global.get $global$0) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - (drop - (ref.is_null - (local.get $1) - ) - ) - (drop - (ref.is_null - (global.get $global$1) - ) - ) - (drop - (ref.is_null - (ref.null nofunc) - ) - ) - (drop - (ref.is_null - (ref.func $3) - ) - ) - (drop - (ref.is_null - (local.get $2) - ) - ) - (drop - (ref.is_null - (global.get $global$3) - ) - ) - (drop - (ref.is_null - (ref.null none) - ) - ) - ) - (func $5 (type $6) (result eqref) - (local $0 eqref) - (local.get $0) - ) - (func $6 (type $6) (result eqref) - (global.get $global$0) - ) - (func $7 (type $6) (result eqref) - (ref.null none) - ) - (func $8 (type $3) (result funcref) - (local $0 funcref) - (local.get $0) - ) - (func $9 (type $3) (result funcref) - (global.get $global$1) - ) - (func $10 (type $3) (result funcref) - (ref.null nofunc) - ) - (func $11 (type $3) (result funcref) - (ref.func $3) - ) - (func $12 (type $0) (result anyref) - (local $0 anyref) - (local.get $0) - ) - (func $13 (type $0) (result anyref) - (global.get $global$3) - ) - (func $14 (type $0) (result anyref) - (ref.null none) - ) - (func $15 (type $0) (result anyref) - (local $0 eqref) - (local.get $0) - ) - (func $16 (type $0) (result anyref) - (global.get $global$0) - ) - (func $17 (type $0) (result anyref) - (ref.null none) - ) - (func $18 (type $6) (result eqref) - (local $0 eqref) - (return - (local.get $0) - ) - ) - (func $19 (type $3) (result funcref) - (local $0 funcref) - (return - (local.get $0) - ) - ) - (func $20 (type $0) (result anyref) - (local $0 anyref) - (return - (local.get $0) - ) - ) - (func $21 (type $0) (result anyref) - (local $0 eqref) - (local $1 funcref) - (return - (local.get $0) - ) - ) - (func $22 (type $5) - (drop - (ref.func $23) - ) - ) - (func $23 (type $5) - (nop) - ) -) - diff --git a/test/reg_switch.wast b/test/reg_switch.wast deleted file mode 100644 index 3bae4683d4d..00000000000 --- a/test/reg_switch.wast +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $0 (func)) - (memory $0 0) - (func $0 (type $0) - (if - (i32.const 0) - (block $A - (br_table $A - (i32.const 0) - ) - ) - ) - ) -) diff --git a/test/reg_switch.wast.from-wast b/test/reg_switch.wast.from-wast deleted file mode 100644 index a766908048b..00000000000 --- a/test/reg_switch.wast.from-wast +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $0 (func)) - (memory $0 0) - (func $0 (type $0) - (if - (i32.const 0) - (block $A - (br_table $A - (i32.const 0) - ) - ) - ) - ) -) diff --git a/test/reg_switch.wast.fromBinary b/test/reg_switch.wast.fromBinary deleted file mode 100644 index 00b78d79cb1..00000000000 --- a/test/reg_switch.wast.fromBinary +++ /dev/null @@ -1,15 +0,0 @@ -(module - (type $0 (func)) - (memory $0 0) - (func $0 (type $0) - (if - (i32.const 0) - (block $label$2 - (br_table $label$2 - (i32.const 0) - ) - ) - ) - ) -) - diff --git a/test/reg_switch.wast.fromBinary.noDebugInfo b/test/reg_switch.wast.fromBinary.noDebugInfo deleted file mode 100644 index 00b78d79cb1..00000000000 --- a/test/reg_switch.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,15 +0,0 @@ -(module - (type $0 (func)) - (memory $0 0) - (func $0 (type $0) - (if - (i32.const 0) - (block $label$2 - (br_table $label$2 - (i32.const 0) - ) - ) - ) - ) -) - diff --git a/test/segment-overlap.wast b/test/segment-overlap.wast deleted file mode 100644 index dce86fd882f..00000000000 --- a/test/segment-overlap.wast +++ /dev/null @@ -1,6 +0,0 @@ -(module - (memory $0 10) - (data (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") ;; overlaps with the next - (data (i32.const 104) "\00\00\00\00") -) - diff --git a/test/segment-overlap.wast.from-wast b/test/segment-overlap.wast.from-wast deleted file mode 100644 index 52f23d83442..00000000000 --- a/test/segment-overlap.wast.from-wast +++ /dev/null @@ -1,5 +0,0 @@ -(module - (memory $0 10) - (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") - (data $1 (i32.const 104) "\00\00\00\00") -) diff --git a/test/segment-overlap.wast.fromBinary b/test/segment-overlap.wast.fromBinary deleted file mode 100644 index 6ff742a5f4d..00000000000 --- a/test/segment-overlap.wast.fromBinary +++ /dev/null @@ -1,6 +0,0 @@ -(module - (memory $0 10) - (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") - (data $1 (i32.const 104) "\00\00\00\00") -) - diff --git a/test/segment-overlap.wast.fromBinary.noDebugInfo b/test/segment-overlap.wast.fromBinary.noDebugInfo deleted file mode 100644 index 6ff742a5f4d..00000000000 --- a/test/segment-overlap.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,6 +0,0 @@ -(module - (memory $0 10) - (data $0 (i32.const 100) "\ff\ff\ff\ff\ff\ff\ff\ff") - (data $1 (i32.const 104) "\00\00\00\00") -) - diff --git a/test/signext.wast b/test/signext.wast deleted file mode 100644 index 74bd488e73a..00000000000 --- a/test/signext.wast +++ /dev/null @@ -1,12 +0,0 @@ -(module - (type $0 (func)) - (func $signext (type $0) - (local $0 i32) - (local $1 i64) - (drop (i32.extend8_s (local.get $0))) - (drop (i32.extend16_s (local.get $0))) - (drop (i64.extend8_s (local.get $1))) - (drop (i64.extend16_s (local.get $1))) - (drop (i64.extend32_s (local.get $1))) - ) -) diff --git a/test/signext.wast.from-wast b/test/signext.wast.from-wast deleted file mode 100644 index 128bf5b1139..00000000000 --- a/test/signext.wast.from-wast +++ /dev/null @@ -1,32 +0,0 @@ -(module - (type $0 (func)) - (func $signext (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.extend8_s - (local.get $0) - ) - ) - (drop - (i32.extend16_s - (local.get $0) - ) - ) - (drop - (i64.extend8_s - (local.get $1) - ) - ) - (drop - (i64.extend16_s - (local.get $1) - ) - ) - (drop - (i64.extend32_s - (local.get $1) - ) - ) - ) -) diff --git a/test/signext.wast.fromBinary b/test/signext.wast.fromBinary deleted file mode 100644 index 55b8b92ebe3..00000000000 --- a/test/signext.wast.fromBinary +++ /dev/null @@ -1,33 +0,0 @@ -(module - (type $0 (func)) - (func $signext (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.extend8_s - (local.get $0) - ) - ) - (drop - (i32.extend16_s - (local.get $0) - ) - ) - (drop - (i64.extend8_s - (local.get $1) - ) - ) - (drop - (i64.extend16_s - (local.get $1) - ) - ) - (drop - (i64.extend32_s - (local.get $1) - ) - ) - ) -) - diff --git a/test/signext.wast.fromBinary.noDebugInfo b/test/signext.wast.fromBinary.noDebugInfo deleted file mode 100644 index e7b5303ddee..00000000000 --- a/test/signext.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,33 +0,0 @@ -(module - (type $0 (func)) - (func $0 (type $0) - (local $0 i32) - (local $1 i64) - (drop - (i32.extend8_s - (local.get $0) - ) - ) - (drop - (i32.extend16_s - (local.get $0) - ) - ) - (drop - (i64.extend8_s - (local.get $1) - ) - ) - (drop - (i64.extend16_s - (local.get $1) - ) - ) - (drop - (i64.extend32_s - (local.get $1) - ) - ) - ) -) - diff --git a/test/simd.wast b/test/simd.wast deleted file mode 100644 index a89efb384e7..00000000000 --- a/test/simd.wast +++ /dev/null @@ -1,1372 +0,0 @@ -(module - (memory 1 1) - (func $v128.load (param $0 i32) (result v128) - (v128.load offset=0 align=16 - (local.get $0) - ) - ) - (func $v128.load8x8_s (param $0 i32) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load8x8_u (param $0 i32) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load16x4_s (param $0 i32) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (param $0 i32) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (param $0 i32) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (param $0 i32) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load8_splat (param $0 i32) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (param $0 i32) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (param $0 i32) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (param $0 i32) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.store (param $0 i32) (param $1 v128) - (v128.store offset=0 align=16 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.const.i8x16 (result v128) - (v128.const i8x16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) - ) - (func $v128.const.i16x8 (result v128) - (v128.const i16x8 1 2 3 4 5 6 7 8) - ) - (func $v128.const.i32x4 (result v128) - (v128.const i32x4 1 2 3 4) - ) - (func $v128.const.i64x2 (result v128) - (v128.const i64x2 1 2) - ) - (func $v128.const.f32x4 (result v128) - (v128.const f32x4 1.0 2 3 4) - ) - (func $v128.const.f64x2 (result v128) - (v128.const f64x2 1.0 2) - ) - (func $i8x16.shuffle (param $0 v128) (param $1 v128) (result v128) - (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.swizzle (param $0 v128) (param $1 v128) (result v128) - (i8x16.swizzle - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.splat (param $0 i32) (result v128) - (i8x16.splat - (local.get $0) - ) - ) - (func $i16x8.splat (param $0 i32) (result v128) - (i16x8.splat - (local.get $0) - ) - ) - (func $f32x4.splat (param $0 f32) (result v128) - (f32x4.splat - (local.get $0) - ) - ) - (func $f64x2.splat (param $0 f64) (result v128) - (f64x2.splat - (local.get $0) - ) - ) - (func $i8x16.extract_lane_s (param $0 v128) (result i32) - (i8x16.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i8x16.extract_lane_u (param $0 v128) (result i32) - (i8x16.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i8x16.replace_lane (param $0 v128) (param $1 i32) (result v128) - (i8x16.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extract_lane_s (param $0 v128) (result i32) - (i16x8.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i16x8.extract_lane_u (param $0 v128) (result i32) - (i16x8.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i16x8.replace_lane (param $0 v128) (param $1 i32) (result v128) - (i16x8.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extract_lane (param $0 v128) (result i32) - (i32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $i32x4.replace_lane (param $0 v128) (param $1 i32) (result v128) - (i32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extract_lane (param $0 v128) (result i64) - (i64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $i64x2.replace_lane (param $0 v128) (param $1 i64) (result v128) - (i64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.extract_lane (param $0 v128) (result f32) - (f32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $f32x4.replace_lane (param $0 v128) (param $1 f32) (result v128) - (f32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.extract_lane (param $0 v128) (result f64) - (f64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $f64x2.replace_lane (param $0 v128) (param $1 f64) (result v128) - (f64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.eq (param $0 v128) (param $1 v128) (result v128) - (i8x16.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ne (param $0 v128) (param $1 v128) (result v128) - (i8x16.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.eq (param $0 v128) (param $1 v128) (result v128) - (i16x8.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ne (param $0 v128) (param $1 v128) (result v128) - (i16x8.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.eq (param $0 v128) (param $1 v128) (result v128) - (i32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ne (param $0 v128) (param $1 v128) (result v128) - (i32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.eq (param $0 v128) (param $1 v128) (result v128) - (f32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ne (param $0 v128) (param $1 v128) (result v128) - (f32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.lt (param $0 v128) (param $1 v128) (result v128) - (f32x4.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.gt (param $0 v128) (param $1 v128) (result v128) - (f32x4.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.le (param $0 v128) (param $1 v128) (result v128) - (f32x4.le - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ge (param $0 v128) (param $1 v128) (result v128) - (f32x4.ge - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.eq (param $0 v128) (param $1 v128) (result v128) - (f64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ne (param $0 v128) (param $1 v128) (result v128) - (f64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.lt (param $0 v128) (param $1 v128) (result v128) - (f64x2.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.gt (param $0 v128) (param $1 v128) (result v128) - (f64x2.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.le (param $0 v128) (param $1 v128) (result v128) - (f64x2.le - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ge (param $0 v128) (param $1 v128) (result v128) - (f64x2.ge - (local.get $0) - (local.get $1) - ) - ) - (func $v128.not (param $0 v128) (result v128) - (v128.not - (local.get $0) - ) - ) - (func $v128.and (param $0 v128) (param $1 v128) (result v128) - (v128.and - (local.get $0) - (local.get $1) - ) - ) - (func $v128.andnot (param $0 v128) (param $1 v128) (result v128) - (v128.andnot - (local.get $0) - (local.get $1) - ) - ) - (func $v128.or (param $0 v128) (param $1 v128) (result v128) - (v128.or - (local.get $0) - (local.get $1) - ) - ) - (func $v128.xor (param $0 v128) (param $1 v128) (result v128) - (v128.xor - (local.get $0) - (local.get $1) - ) - ) - (func $v128.bitselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (v128.bitselect - (local.get $0) - (local.get $1) - (local.get $2) - ) - ) - (func $v128.any_true (param $0 v128) (result i32) - (v128.any_true - (local.get $0) - ) - ) - (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (param $0 i32) (param $1 v128) - (v128.store8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (param $0 i32) (param $1 v128) - (v128.store16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (param $0 i32) (param $1 v128) - (v128.store32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (param $0 i32) (param $1 v128) - (v128.store64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (param $0 i32) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (param $0 i32) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) - (func $f32x4.demote_f64x2_zero (param $0 v128) (result v128) - (f32x4.demote_f64x2_zero - (local.get $0) - ) - ) - (func $f64x2.promote_low_f32x4 (param $0 v128) (result v128) - (f64x2.promote_low_f32x4 - (local.get $0) - ) - ) - (func $i8x16.abs (param $0 v128) (result v128) - (i8x16.abs - (local.get $0) - ) - ) - (func $i8x16.neg (param $0 v128) (result v128) - (i8x16.neg - (local.get $0) - ) - ) - (func $i8x16.popcnt (param $0 v128) (result v128) - (i8x16.popcnt - (local.get $0) - ) - ) - (func $i8x16.all_true (param $0 v128) (result i32) - (i8x16.all_true - (local.get $0) - ) - ) - (func $i8x16.bitmask (param $0 v128) (result i32) - (i8x16.bitmask - (local.get $0) - ) - ) - (func $i8x16.narrow_i16x8_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.narrow_i16x8_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ceil (param $0 v128) (result v128) - (f32x4.ceil - (local.get $0) - ) - ) - (func $f32x4.floor (param $0 v128) (result v128) - (f32x4.floor - (local.get $0) - ) - ) - (func $f32x4.trunc (param $0 v128) (result v128) - (f32x4.trunc - (local.get $0) - ) - ) - (func $f32x4.nearest (param $0 v128) (result v128) - (f32x4.nearest - (local.get $0) - ) - ) - (func $i8x16.shl (param $0 v128) (param $1 i32) (result v128) - (i8x16.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_s (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_u (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add (param $0 v128) (param $1 v128) (result v128) - (i8x16.add - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ceil (param $0 v128) (result v128) - (f64x2.ceil - (local.get $0) - ) - ) - (func $f64x2.floor (param $0 v128) (result v128) - (f64x2.floor - (local.get $0) - ) - ) - (func $i8x16.min_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.min_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_s (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.trunc (param $0 v128) (result v128) - (f64x2.trunc - (local.get $0) - ) - ) - (func $i8x16.avgr_u (param $0 v128) (param $1 v128) (result v128) - (i8x16.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_s (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_u (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_u - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_s (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_u (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_u - (local.get $0) - ) - ) - (func $i16x8.abs (param $0 v128) (result v128) - (i16x8.abs - (local.get $0) - ) - ) - (func $i16x8.neg (param $0 v128) (result v128) - (i16x8.neg - (local.get $0) - ) - ) - (func $i16x8.q15mulr_sat_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.q15mulr_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.all_true (param $0 v128) (result i32) - (i16x8.all_true - (local.get $0) - ) - ) - (func $i16x8.bitmask (param $0 v128) (result i32) - (i16x8.bitmask - (local.get $0) - ) - ) - (func $i16x8.narrow_i32x4_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.narrow_i32x4_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extend_low_i8x16_s (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_s (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_low_i8x16_u (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_u - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_u (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_u - (local.get $0) - ) - ) -(func $i16x8.shl (param $0 v128) (param $1 i32) (result v128) - (i16x8.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_s (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_u (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add (param $0 v128) (param $1 v128) (result v128) - (i16x8.add - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.nearest (param $0 v128) (result v128) - (f64x2.nearest - (local.get $0) - ) - ) - (func $i16x8.mul (param $0 v128) (param $1 v128) (result v128) - (i16x8.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.avgr_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_s (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_u (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.abs (param $0 v128) (result v128) - (i32x4.abs - (local.get $0) - ) - ) - (func $i32x4.neg (param $0 v128) (result v128) - (i32x4.neg - (local.get $0) - ) - ) - (func $i32x4.all_true (param $0 v128) (result i32) - (i32x4.all_true - (local.get $0) - ) - ) - (func $i32x4.bitmask (param $0 v128) (result i32) - (i32x4.bitmask - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_s (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_s (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_u (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_u (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.shl (param $0 v128) (param $1 i32) (result v128) - (i32x4.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_s (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_u (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.add (param $0 v128) (param $1 v128) (result v128) - (i32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.sub (param $0 v128) (param $1 v128) (result v128) - (i32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.mul (param $0 v128) (param $1 v128) (result v128) - (i32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.dot_i16x8_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.dot_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_s (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_u (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.abs (param $0 v128) (result v128) - (i64x2.abs - (local.get $0) - ) - ) - (func $i64x2.neg (param $0 v128) (result v128) - (i64x2.neg - (local.get $0) - ) - ) - (func $i64x2.all_true (param $0 v128) (result i32) - (i64x2.all_true - (local.get $0) - ) - ) - (func $i64x2.bitmask (param $0 v128) (result i32) - (i64x2.bitmask - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_s (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_s (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_u (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_u (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.shl (param $0 v128) (param $1 i32) (result v128) - (i64x2.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_s (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_u (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.add (param $0 v128) (param $1 v128) (result v128) - (i64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.sub (param $0 v128) (param $1 v128) (result v128) - (i64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.mul (param $0 v128) (param $1 v128) (result v128) - (i64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.eq (param $0 v128) (param $1 v128) (result v128) - (i64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ne (param $0 v128) (param $1 v128) (result v128) - (i64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.lt_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.gt_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.le_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ge_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_s (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_u (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_u (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.abs (param $0 v128) (result v128) - (f32x4.abs - (local.get $0) - ) - ) - (func $f32x4.neg (param $0 v128) (result v128) - (f32x4.neg - (local.get $0) - ) - ) - (func $f32x4.sqrt (param $0 v128) (result v128) - (f32x4.sqrt - (local.get $0) - ) - ) - (func $f32x4.add (param $0 v128) (param $1 v128) (result v128) - (f32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.sub (param $0 v128) (param $1 v128) (result v128) - (f32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.mul (param $0 v128) (param $1 v128) (result v128) - (f32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.div (param $0 v128) (param $1 v128) (result v128) - (f32x4.div - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.min (param $0 v128) (param $1 v128) (result v128) - (f32x4.min - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.max (param $0 v128) (param $1 v128) (result v128) - (f32x4.max - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmin (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmax (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.abs (param $0 v128) (result v128) - (f64x2.abs - (local.get $0) - ) - ) - (func $f64x2.neg (param $0 v128) (result v128) - (f64x2.neg - (local.get $0) - ) - ) - (func $f64x2.sqrt (param $0 v128) (result v128) - (f64x2.sqrt - (local.get $0) - ) - ) - (func $f64x2.add (param $0 v128) (param $1 v128) (result v128) - (f64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.sub (param $0 v128) (param $1 v128) (result v128) - (f64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.mul (param $0 v128) (param $1 v128) (result v128) - (f64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.div (param $0 v128) (param $1 v128) (result v128) - (f64x2.div - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.min (param $0 v128) (param $1 v128) (result v128) - (f64x2.min - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.max (param $0 v128) (param $1 v128) (result v128) - (f64x2.max - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmin (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmax (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.trunc_sat_f32x4_s (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_s - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f32x4_u (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_u - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_s (param $0 v128) (result v128) - (f32x4.convert_i32x4_s - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_u (param $0 v128) (result v128) - (f32x4.convert_i32x4_u - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_s_zero (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_s_zero - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_u_zero (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_u_zero - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_s (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_s - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_u (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_u - (local.get $0) - ) - ) -) diff --git a/test/simd.wast.from-wast b/test/simd.wast.from-wast deleted file mode 100644 index b25fc0d45b1..00000000000 --- a/test/simd.wast.from-wast +++ /dev/null @@ -1,1389 +0,0 @@ -(module - (type $0 (func (param v128 v128) (result v128))) - (type $1 (func (param v128) (result v128))) - (type $2 (func (param i32) (result v128))) - (type $3 (func (param v128 i32) (result v128))) - (type $4 (func (param v128) (result i32))) - (type $5 (func (param i32 v128))) - (type $6 (func (param i32 v128) (result v128))) - (type $7 (func (result v128))) - (type $8 (func (param f32) (result v128))) - (type $9 (func (param f64) (result v128))) - (type $10 (func (param v128) (result i64))) - (type $11 (func (param v128 i64) (result v128))) - (type $12 (func (param v128) (result f32))) - (type $13 (func (param v128 f32) (result v128))) - (type $14 (func (param v128) (result f64))) - (type $15 (func (param v128 f64) (result v128))) - (type $16 (func (param v128 v128 v128) (result v128))) - (memory $0 1 1) - (func $v128.load (type $2) (param $0 i32) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $2) (param $0 i32) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $2) (param $0 i32) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $2) (param $0 i32) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $2) (param $0 i32) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $2) (param $0 i32) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $2) (param $0 i32) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load8_splat (type $2) (param $0 i32) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (type $2) (param $0 i32) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (type $2) (param $0 i32) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (type $2) (param $0 i32) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.store (type $5) (param $0 i32) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $v128.const.i8x16 (type $7) (result v128) - (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) - ) - (func $v128.const.i16x8 (type $7) (result v128) - (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) - ) - (func $v128.const.i32x4 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) - ) - (func $v128.const.i64x2 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) - ) - (func $v128.const.f32x4 (type $7) (result v128) - (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) - ) - (func $v128.const.f64x2 (type $7) (result v128) - (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) - ) - (func $i8x16.shuffle (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.swizzle (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.swizzle - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.splat (type $2) (param $0 i32) (result v128) - (i8x16.splat - (local.get $0) - ) - ) - (func $i16x8.splat (type $2) (param $0 i32) (result v128) - (i16x8.splat - (local.get $0) - ) - ) - (func $f32x4.splat (type $8) (param $0 f32) (result v128) - (f32x4.splat - (local.get $0) - ) - ) - (func $f64x2.splat (type $9) (param $0 f64) (result v128) - (f64x2.splat - (local.get $0) - ) - ) - (func $i8x16.extract_lane_s (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i8x16.extract_lane_u (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i8x16.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extract_lane_s (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i16x8.extract_lane_u (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i16x8.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extract_lane (type $4) (param $0 v128) (result i32) - (i32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $i32x4.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extract_lane (type $10) (param $0 v128) (result i64) - (i64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $i64x2.replace_lane (type $11) (param $0 v128) (param $1 i64) (result v128) - (i64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.extract_lane (type $12) (param $0 v128) (result f32) - (f32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $f32x4.replace_lane (type $13) (param $0 v128) (param $1 f32) (result v128) - (f32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.extract_lane (type $14) (param $0 v128) (result f64) - (f64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $f64x2.replace_lane (type $15) (param $0 v128) (param $1 f64) (result v128) - (f64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.lt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.gt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.le (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.le - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ge (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ge - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.lt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.gt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.le (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.le - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ge (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ge - (local.get $0) - (local.get $1) - ) - ) - (func $v128.not (type $1) (param $0 v128) (result v128) - (v128.not - (local.get $0) - ) - ) - (func $v128.and (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.and - (local.get $0) - (local.get $1) - ) - ) - (func $v128.andnot (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.andnot - (local.get $0) - (local.get $1) - ) - ) - (func $v128.or (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.or - (local.get $0) - (local.get $1) - ) - ) - (func $v128.xor (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.xor - (local.get $0) - (local.get $1) - ) - ) - (func $v128.bitselect (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (v128.bitselect - (local.get $0) - (local.get $1) - (local.get $2) - ) - ) - (func $v128.any_true (type $4) (param $0 v128) (result i32) - (v128.any_true - (local.get $0) - ) - ) - (func $v128.load8_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (type $2) (param $0 i32) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (type $2) (param $0 i32) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) - (func $f32x4.demote_f64x2_zero (type $1) (param $0 v128) (result v128) - (f32x4.demote_f64x2_zero - (local.get $0) - ) - ) - (func $f64x2.promote_low_f32x4 (type $1) (param $0 v128) (result v128) - (f64x2.promote_low_f32x4 - (local.get $0) - ) - ) - (func $i8x16.abs (type $1) (param $0 v128) (result v128) - (i8x16.abs - (local.get $0) - ) - ) - (func $i8x16.neg (type $1) (param $0 v128) (result v128) - (i8x16.neg - (local.get $0) - ) - ) - (func $i8x16.popcnt (type $1) (param $0 v128) (result v128) - (i8x16.popcnt - (local.get $0) - ) - ) - (func $i8x16.all_true (type $4) (param $0 v128) (result i32) - (i8x16.all_true - (local.get $0) - ) - ) - (func $i8x16.bitmask (type $4) (param $0 v128) (result i32) - (i8x16.bitmask - (local.get $0) - ) - ) - (func $i8x16.narrow_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.narrow_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ceil (type $1) (param $0 v128) (result v128) - (f32x4.ceil - (local.get $0) - ) - ) - (func $f32x4.floor (type $1) (param $0 v128) (result v128) - (f32x4.floor - (local.get $0) - ) - ) - (func $f32x4.trunc (type $1) (param $0 v128) (result v128) - (f32x4.trunc - (local.get $0) - ) - ) - (func $f32x4.nearest (type $1) (param $0 v128) (result v128) - (f32x4.nearest - (local.get $0) - ) - ) - (func $i8x16.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ceil (type $1) (param $0 v128) (result v128) - (f64x2.ceil - (local.get $0) - ) - ) - (func $f64x2.floor (type $1) (param $0 v128) (result v128) - (f64x2.floor - (local.get $0) - ) - ) - (func $i8x16.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.trunc (type $1) (param $0 v128) (result v128) - (f64x2.trunc - (local.get $0) - ) - ) - (func $i8x16.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_u - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_u - (local.get $0) - ) - ) - (func $i16x8.abs (type $1) (param $0 v128) (result v128) - (i16x8.abs - (local.get $0) - ) - ) - (func $i16x8.neg (type $1) (param $0 v128) (result v128) - (i16x8.neg - (local.get $0) - ) - ) - (func $i16x8.q15mulr_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.q15mulr_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.all_true (type $4) (param $0 v128) (result i32) - (i16x8.all_true - (local.get $0) - ) - ) - (func $i16x8.bitmask (type $4) (param $0 v128) (result i32) - (i16x8.bitmask - (local.get $0) - ) - ) - (func $i16x8.narrow_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.narrow_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extend_low_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_low_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_u - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_u - (local.get $0) - ) - ) - (func $i16x8.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.nearest (type $1) (param $0 v128) (result v128) - (f64x2.nearest - (local.get $0) - ) - ) - (func $i16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.abs (type $1) (param $0 v128) (result v128) - (i32x4.abs - (local.get $0) - ) - ) - (func $i32x4.neg (type $1) (param $0 v128) (result v128) - (i32x4.neg - (local.get $0) - ) - ) - (func $i32x4.all_true (type $4) (param $0 v128) (result i32) - (i32x4.all_true - (local.get $0) - ) - ) - (func $i32x4.bitmask (type $4) (param $0 v128) (result i32) - (i32x4.bitmask - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.dot_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.dot_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.abs (type $1) (param $0 v128) (result v128) - (i64x2.abs - (local.get $0) - ) - ) - (func $i64x2.neg (type $1) (param $0 v128) (result v128) - (i64x2.neg - (local.get $0) - ) - ) - (func $i64x2.all_true (type $4) (param $0 v128) (result i32) - (i64x2.all_true - (local.get $0) - ) - ) - (func $i64x2.bitmask (type $4) (param $0 v128) (result i32) - (i64x2.bitmask - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_s (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_s (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_u (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_u (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.abs (type $1) (param $0 v128) (result v128) - (f32x4.abs - (local.get $0) - ) - ) - (func $f32x4.neg (type $1) (param $0 v128) (result v128) - (f32x4.neg - (local.get $0) - ) - ) - (func $f32x4.sqrt (type $1) (param $0 v128) (result v128) - (f32x4.sqrt - (local.get $0) - ) - ) - (func $f32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.div (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.div - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.min (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.min - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.max (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.max - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.abs (type $1) (param $0 v128) (result v128) - (f64x2.abs - (local.get $0) - ) - ) - (func $f64x2.neg (type $1) (param $0 v128) (result v128) - (f64x2.neg - (local.get $0) - ) - ) - (func $f64x2.sqrt (type $1) (param $0 v128) (result v128) - (f64x2.sqrt - (local.get $0) - ) - ) - (func $f64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.div (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.div - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.min (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.min - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.max (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.max - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.trunc_sat_f32x4_s (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_s - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f32x4_u (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_u - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_s (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_s - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_u (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_u - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_s_zero (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_s_zero - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_u_zero (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_u_zero - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_s (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_s - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_u (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_u - (local.get $0) - ) - ) -) diff --git a/test/simd.wast.fromBinary b/test/simd.wast.fromBinary deleted file mode 100644 index 892d56754ce..00000000000 --- a/test/simd.wast.fromBinary +++ /dev/null @@ -1,1390 +0,0 @@ -(module - (type $0 (func (param v128 v128) (result v128))) - (type $1 (func (param v128) (result v128))) - (type $2 (func (param i32) (result v128))) - (type $3 (func (param v128 i32) (result v128))) - (type $4 (func (param v128) (result i32))) - (type $5 (func (param i32 v128))) - (type $6 (func (param i32 v128) (result v128))) - (type $7 (func (result v128))) - (type $8 (func (param f32) (result v128))) - (type $9 (func (param f64) (result v128))) - (type $10 (func (param v128) (result i64))) - (type $11 (func (param v128 i64) (result v128))) - (type $12 (func (param v128) (result f32))) - (type $13 (func (param v128 f32) (result v128))) - (type $14 (func (param v128) (result f64))) - (type $15 (func (param v128 f64) (result v128))) - (type $16 (func (param v128 v128 v128) (result v128))) - (memory $0 1 1) - (func $v128.load (type $2) (param $0 i32) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $2) (param $0 i32) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $2) (param $0 i32) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $2) (param $0 i32) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $2) (param $0 i32) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $2) (param $0 i32) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $2) (param $0 i32) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load8_splat (type $2) (param $0 i32) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (type $2) (param $0 i32) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (type $2) (param $0 i32) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (type $2) (param $0 i32) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.store (type $5) (param $0 i32) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $v128.const.i8x16 (type $7) (result v128) - (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) - ) - (func $v128.const.i16x8 (type $7) (result v128) - (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) - ) - (func $v128.const.i32x4 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) - ) - (func $v128.const.i64x2 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) - ) - (func $v128.const.f32x4 (type $7) (result v128) - (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) - ) - (func $v128.const.f64x2 (type $7) (result v128) - (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) - ) - (func $i8x16.shuffle (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.swizzle (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.swizzle - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.splat (type $2) (param $0 i32) (result v128) - (i8x16.splat - (local.get $0) - ) - ) - (func $i16x8.splat (type $2) (param $0 i32) (result v128) - (i16x8.splat - (local.get $0) - ) - ) - (func $f32x4.splat (type $8) (param $0 f32) (result v128) - (f32x4.splat - (local.get $0) - ) - ) - (func $f64x2.splat (type $9) (param $0 f64) (result v128) - (f64x2.splat - (local.get $0) - ) - ) - (func $i8x16.extract_lane_s (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i8x16.extract_lane_u (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i8x16.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extract_lane_s (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_s 0 - (local.get $0) - ) - ) - (func $i16x8.extract_lane_u (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_u 0 - (local.get $0) - ) - ) - (func $i16x8.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extract_lane (type $4) (param $0 v128) (result i32) - (i32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $i32x4.replace_lane (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extract_lane (type $10) (param $0 v128) (result i64) - (i64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $i64x2.replace_lane (type $11) (param $0 v128) (param $1 i64) (result v128) - (i64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.extract_lane (type $12) (param $0 v128) (result f32) - (f32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $f32x4.replace_lane (type $13) (param $0 v128) (param $1 f32) (result v128) - (f32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.extract_lane (type $14) (param $0 v128) (result f64) - (f64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $f64x2.replace_lane (type $15) (param $0 v128) (param $1 f64) (result v128) - (f64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.lt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.gt_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.le_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.ge_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.lt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.gt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.le (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.le - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ge (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ge - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.lt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.lt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.gt (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.gt - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.le (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.le - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ge (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ge - (local.get $0) - (local.get $1) - ) - ) - (func $v128.not (type $1) (param $0 v128) (result v128) - (v128.not - (local.get $0) - ) - ) - (func $v128.and (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.and - (local.get $0) - (local.get $1) - ) - ) - (func $v128.andnot (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.andnot - (local.get $0) - (local.get $1) - ) - ) - (func $v128.or (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.or - (local.get $0) - (local.get $1) - ) - ) - (func $v128.xor (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.xor - (local.get $0) - (local.get $1) - ) - ) - (func $v128.bitselect (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (v128.bitselect - (local.get $0) - (local.get $1) - (local.get $2) - ) - ) - (func $v128.any_true (type $4) (param $0 v128) (result i32) - (v128.any_true - (local.get $0) - ) - ) - (func $v128.load8_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load16_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_offset (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load64_lane_align_offset (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store8_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store16_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store32_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_offset (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.store64_lane_align_offset (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load32_zero (type $2) (param $0 i32) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (type $2) (param $0 i32) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) - (func $f32x4.demote_f64x2_zero (type $1) (param $0 v128) (result v128) - (f32x4.demote_f64x2_zero - (local.get $0) - ) - ) - (func $f64x2.promote_low_f32x4 (type $1) (param $0 v128) (result v128) - (f64x2.promote_low_f32x4 - (local.get $0) - ) - ) - (func $i8x16.abs (type $1) (param $0 v128) (result v128) - (i8x16.abs - (local.get $0) - ) - ) - (func $i8x16.neg (type $1) (param $0 v128) (result v128) - (i8x16.neg - (local.get $0) - ) - ) - (func $i8x16.popcnt (type $1) (param $0 v128) (result v128) - (i8x16.popcnt - (local.get $0) - ) - ) - (func $i8x16.all_true (type $4) (param $0 v128) (result i32) - (i8x16.all_true - (local.get $0) - ) - ) - (func $i8x16.bitmask (type $4) (param $0 v128) (result i32) - (i8x16.bitmask - (local.get $0) - ) - ) - (func $i8x16.narrow_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.narrow_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.ceil (type $1) (param $0 v128) (result v128) - (f32x4.ceil - (local.get $0) - ) - ) - (func $f32x4.floor (type $1) (param $0 v128) (result v128) - (f32x4.floor - (local.get $0) - ) - ) - (func $f32x4.trunc (type $1) (param $0 v128) (result v128) - (f32x4.trunc - (local.get $0) - ) - ) - (func $f32x4.nearest (type $1) (param $0 v128) (result v128) - (f32x4.nearest - (local.get $0) - ) - ) - (func $i8x16.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.ceil (type $1) (param $0 v128) (result v128) - (f64x2.ceil - (local.get $0) - ) - ) - (func $f64x2.floor (type $1) (param $0 v128) (result v128) - (f64x2.floor - (local.get $0) - ) - ) - (func $i8x16.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i8x16.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.trunc (type $1) (param $0 v128) (result v128) - (f64x2.trunc - (local.get $0) - ) - ) - (func $i8x16.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extadd_pairwise_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_u - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extadd_pairwise_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_u - (local.get $0) - ) - ) - (func $i16x8.abs (type $1) (param $0 v128) (result v128) - (i16x8.abs - (local.get $0) - ) - ) - (func $i16x8.neg (type $1) (param $0 v128) (result v128) - (i16x8.neg - (local.get $0) - ) - ) - (func $i16x8.q15mulr_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.q15mulr_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.all_true (type $4) (param $0 v128) (result i32) - (i16x8.all_true - (local.get $0) - ) - ) - (func $i16x8.bitmask (type $4) (param $0 v128) (result i32) - (i16x8.bitmask - (local.get $0) - ) - ) - (func $i16x8.narrow_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.narrow_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extend_low_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_s (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_s - (local.get $0) - ) - ) - (func $i16x8.extend_low_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_u - (local.get $0) - ) - ) - (func $i16x8.extend_high_i8x16_u (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_u - (local.get $0) - ) - ) - (func $i16x8.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.add_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.sub_sat_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.nearest (type $1) (param $0 v128) (result v128) - (f64x2.nearest - (local.get $0) - ) - ) - (func $i16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.avgr_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_low_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i16x8.extmul_high_i8x16_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.abs (type $1) (param $0 v128) (result v128) - (i32x4.abs - (local.get $0) - ) - ) - (func $i32x4.neg (type $1) (param $0 v128) (result v128) - (i32x4.neg - (local.get $0) - ) - ) - (func $i32x4.all_true (type $4) (param $0 v128) (result i32) - (i32x4.all_true - (local.get $0) - ) - ) - (func $i32x4.bitmask (type $4) (param $0 v128) (result i32) - (i32x4.bitmask - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_s (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_s - (local.get $0) - ) - ) - (func $i32x4.extend_low_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.extend_high_i16x8_u (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_u - (local.get $0) - ) - ) - (func $i32x4.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.min_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.max_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.dot_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.dot_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_low_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.extmul_high_i16x8_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.abs (type $1) (param $0 v128) (result v128) - (i64x2.abs - (local.get $0) - ) - ) - (func $i64x2.neg (type $1) (param $0 v128) (result v128) - (i64x2.neg - (local.get $0) - ) - ) - (func $i64x2.all_true (type $4) (param $0 v128) (result i32) - (i64x2.all_true - (local.get $0) - ) - ) - (func $i64x2.bitmask (type $4) (param $0 v128) (result i32) - (i64x2.bitmask - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_s (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_s (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_s - (local.get $0) - ) - ) - (func $i64x2.extend_low_i32x4_u (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.extend_high_i32x4_u (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_u - (local.get $0) - ) - ) - (func $i64x2.shl (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shl - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_s (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.shr_u (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.eq (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ne (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.lt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.gt_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.le_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.ge_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_s (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_low_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $i64x2.extmul_high_i32x4_u (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.abs (type $1) (param $0 v128) (result v128) - (f32x4.abs - (local.get $0) - ) - ) - (func $f32x4.neg (type $1) (param $0 v128) (result v128) - (f32x4.neg - (local.get $0) - ) - ) - (func $f32x4.sqrt (type $1) (param $0 v128) (result v128) - (f32x4.sqrt - (local.get $0) - ) - ) - (func $f32x4.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.div (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.div - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.min (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.min - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.max (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.max - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f32x4.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.abs (type $1) (param $0 v128) (result v128) - (f64x2.abs - (local.get $0) - ) - ) - (func $f64x2.neg (type $1) (param $0 v128) (result v128) - (f64x2.neg - (local.get $0) - ) - ) - (func $f64x2.sqrt (type $1) (param $0 v128) (result v128) - (f64x2.sqrt - (local.get $0) - ) - ) - (func $f64x2.add (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.sub (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.mul (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.div (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.div - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.min (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.min - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.max (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.max - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $f64x2.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $i32x4.trunc_sat_f32x4_s (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_s - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f32x4_u (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_u - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_s (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_s - (local.get $0) - ) - ) - (func $f32x4.convert_i32x4_u (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_u - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_s_zero (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_s_zero - (local.get $0) - ) - ) - (func $i32x4.trunc_sat_f64x2_u_zero (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_u_zero - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_s (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_s - (local.get $0) - ) - ) - (func $f64x2.convert_low_i32x4_u (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_u - (local.get $0) - ) - ) -) - diff --git a/test/simd.wast.fromBinary.noDebugInfo b/test/simd.wast.fromBinary.noDebugInfo deleted file mode 100644 index 18e2671f305..00000000000 --- a/test/simd.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,1390 +0,0 @@ -(module - (type $0 (func (param v128 v128) (result v128))) - (type $1 (func (param v128) (result v128))) - (type $2 (func (param i32) (result v128))) - (type $3 (func (param v128 i32) (result v128))) - (type $4 (func (param v128) (result i32))) - (type $5 (func (param i32 v128))) - (type $6 (func (param i32 v128) (result v128))) - (type $7 (func (result v128))) - (type $8 (func (param f32) (result v128))) - (type $9 (func (param f64) (result v128))) - (type $10 (func (param v128) (result i64))) - (type $11 (func (param v128 i64) (result v128))) - (type $12 (func (param v128) (result f32))) - (type $13 (func (param v128 f32) (result v128))) - (type $14 (func (param v128) (result f64))) - (type $15 (func (param v128 f64) (result v128))) - (type $16 (func (param v128 v128 v128) (result v128))) - (memory $0 1 1) - (func $0 (type $2) (param $0 i32) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $1 (type $2) (param $0 i32) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $2 (type $2) (param $0 i32) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $3 (type $2) (param $0 i32) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $4 (type $2) (param $0 i32) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $5 (type $2) (param $0 i32) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $6 (type $2) (param $0 i32) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $7 (type $2) (param $0 i32) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $8 (type $2) (param $0 i32) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $9 (type $2) (param $0 i32) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $10 (type $2) (param $0 i32) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $11 (type $5) (param $0 i32) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $12 (type $7) (result v128) - (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) - ) - (func $13 (type $7) (result v128) - (v128.const i32x4 0x00020001 0x00040003 0x00060005 0x00080007) - ) - (func $14 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) - ) - (func $15 (type $7) (result v128) - (v128.const i32x4 0x00000001 0x00000000 0x00000002 0x00000000) - ) - (func $16 (type $7) (result v128) - (v128.const i32x4 0x3f800000 0x40000000 0x40400000 0x40800000) - ) - (func $17 (type $7) (result v128) - (v128.const i32x4 0x00000000 0x3ff00000 0x00000000 0x40000000) - ) - (func $18 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.shuffle 0 17 2 19 4 21 6 23 8 25 10 27 12 29 14 31 - (local.get $0) - (local.get $1) - ) - ) - (func $19 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.swizzle - (local.get $0) - (local.get $1) - ) - ) - (func $20 (type $2) (param $0 i32) (result v128) - (i8x16.splat - (local.get $0) - ) - ) - (func $21 (type $2) (param $0 i32) (result v128) - (i16x8.splat - (local.get $0) - ) - ) - (func $22 (type $8) (param $0 f32) (result v128) - (f32x4.splat - (local.get $0) - ) - ) - (func $23 (type $9) (param $0 f64) (result v128) - (f64x2.splat - (local.get $0) - ) - ) - (func $24 (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_s 0 - (local.get $0) - ) - ) - (func $25 (type $4) (param $0 v128) (result i32) - (i8x16.extract_lane_u 0 - (local.get $0) - ) - ) - (func $26 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $27 (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_s 0 - (local.get $0) - ) - ) - (func $28 (type $4) (param $0 v128) (result i32) - (i16x8.extract_lane_u 0 - (local.get $0) - ) - ) - (func $29 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $30 (type $4) (param $0 v128) (result i32) - (i32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $31 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $32 (type $10) (param $0 v128) (result i64) - (i64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $33 (type $11) (param $0 v128) (param $1 i64) (result v128) - (i64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $34 (type $12) (param $0 v128) (result f32) - (f32x4.extract_lane 0 - (local.get $0) - ) - ) - (func $35 (type $13) (param $0 v128) (param $1 f32) (result v128) - (f32x4.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $36 (type $14) (param $0 v128) (result f64) - (f64x2.extract_lane 0 - (local.get $0) - ) - ) - (func $37 (type $15) (param $0 v128) (param $1 f64) (result v128) - (f64x2.replace_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $38 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.eq - (local.get $0) - (local.get $1) - ) - ) - (func $39 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ne - (local.get $0) - (local.get $1) - ) - ) - (func $40 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $41 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $42 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $43 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $44 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $45 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $46 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $47 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $48 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.eq - (local.get $0) - (local.get $1) - ) - ) - (func $49 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ne - (local.get $0) - (local.get $1) - ) - ) - (func $50 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $51 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $52 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $53 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $54 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $55 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $56 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $57 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $58 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $59 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $60 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $61 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.lt_u - (local.get $0) - (local.get $1) - ) - ) - (func $62 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $63 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.gt_u - (local.get $0) - (local.get $1) - ) - ) - (func $64 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $65 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.le_u - (local.get $0) - (local.get $1) - ) - ) - (func $66 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $67 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.ge_u - (local.get $0) - (local.get $1) - ) - ) - (func $68 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.eq - (local.get $0) - (local.get $1) - ) - ) - (func $69 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ne - (local.get $0) - (local.get $1) - ) - ) - (func $70 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.lt - (local.get $0) - (local.get $1) - ) - ) - (func $71 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.gt - (local.get $0) - (local.get $1) - ) - ) - (func $72 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.le - (local.get $0) - (local.get $1) - ) - ) - (func $73 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.ge - (local.get $0) - (local.get $1) - ) - ) - (func $74 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $75 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $76 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.lt - (local.get $0) - (local.get $1) - ) - ) - (func $77 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.gt - (local.get $0) - (local.get $1) - ) - ) - (func $78 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.le - (local.get $0) - (local.get $1) - ) - ) - (func $79 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.ge - (local.get $0) - (local.get $1) - ) - ) - (func $80 (type $1) (param $0 v128) (result v128) - (v128.not - (local.get $0) - ) - ) - (func $81 (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.and - (local.get $0) - (local.get $1) - ) - ) - (func $82 (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.andnot - (local.get $0) - (local.get $1) - ) - ) - (func $83 (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.or - (local.get $0) - (local.get $1) - ) - ) - (func $84 (type $0) (param $0 v128) (param $1 v128) (result v128) - (v128.xor - (local.get $0) - (local.get $1) - ) - ) - (func $85 (type $16) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (v128.bitselect - (local.get $0) - (local.get $1) - (local.get $2) - ) - ) - (func $86 (type $4) (param $0 v128) (result i32) - (v128.any_true - (local.get $0) - ) - ) - (func $87 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $88 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $89 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $90 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $91 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $92 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $93 (type $6) (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $94 (type $5) (param $0 i32) (param $1 v128) - (v128.store8_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $95 (type $5) (param $0 i32) (param $1 v128) - (v128.store16_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $96 (type $5) (param $0 i32) (param $1 v128) - (v128.store32_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $97 (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane 0 - (local.get $0) - (local.get $1) - ) - ) - (func $98 (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $99 (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 0 - (local.get $0) - (local.get $1) - ) - ) - (func $100 (type $5) (param $0 i32) (param $1 v128) - (v128.store64_lane offset=32 align=1 0 - (local.get $0) - (local.get $1) - ) - ) - (func $101 (type $2) (param $0 i32) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $102 (type $2) (param $0 i32) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) - (func $103 (type $1) (param $0 v128) (result v128) - (f32x4.demote_f64x2_zero - (local.get $0) - ) - ) - (func $104 (type $1) (param $0 v128) (result v128) - (f64x2.promote_low_f32x4 - (local.get $0) - ) - ) - (func $105 (type $1) (param $0 v128) (result v128) - (i8x16.abs - (local.get $0) - ) - ) - (func $106 (type $1) (param $0 v128) (result v128) - (i8x16.neg - (local.get $0) - ) - ) - (func $107 (type $1) (param $0 v128) (result v128) - (i8x16.popcnt - (local.get $0) - ) - ) - (func $108 (type $4) (param $0 v128) (result i32) - (i8x16.all_true - (local.get $0) - ) - ) - (func $109 (type $4) (param $0 v128) (result i32) - (i8x16.bitmask - (local.get $0) - ) - ) - (func $110 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $111 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.narrow_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $112 (type $1) (param $0 v128) (result v128) - (f32x4.ceil - (local.get $0) - ) - ) - (func $113 (type $1) (param $0 v128) (result v128) - (f32x4.floor - (local.get $0) - ) - ) - (func $114 (type $1) (param $0 v128) (result v128) - (f32x4.trunc - (local.get $0) - ) - ) - (func $115 (type $1) (param $0 v128) (result v128) - (f32x4.nearest - (local.get $0) - ) - ) - (func $116 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shl - (local.get $0) - (local.get $1) - ) - ) - (func $117 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $118 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i8x16.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $119 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add - (local.get $0) - (local.get $1) - ) - ) - (func $120 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $121 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $122 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub - (local.get $0) - (local.get $1) - ) - ) - (func $123 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $124 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $125 (type $1) (param $0 v128) (result v128) - (f64x2.ceil - (local.get $0) - ) - ) - (func $126 (type $1) (param $0 v128) (result v128) - (f64x2.floor - (local.get $0) - ) - ) - (func $127 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $128 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $129 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $130 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $131 (type $1) (param $0 v128) (result v128) - (f64x2.trunc - (local.get $0) - ) - ) - (func $132 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i8x16.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $133 (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_s - (local.get $0) - ) - ) - (func $134 (type $1) (param $0 v128) (result v128) - (i16x8.extadd_pairwise_i8x16_u - (local.get $0) - ) - ) - (func $135 (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_s - (local.get $0) - ) - ) - (func $136 (type $1) (param $0 v128) (result v128) - (i32x4.extadd_pairwise_i16x8_u - (local.get $0) - ) - ) - (func $137 (type $1) (param $0 v128) (result v128) - (i16x8.abs - (local.get $0) - ) - ) - (func $138 (type $1) (param $0 v128) (result v128) - (i16x8.neg - (local.get $0) - ) - ) - (func $139 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.q15mulr_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $140 (type $4) (param $0 v128) (result i32) - (i16x8.all_true - (local.get $0) - ) - ) - (func $141 (type $4) (param $0 v128) (result i32) - (i16x8.bitmask - (local.get $0) - ) - ) - (func $142 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $143 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.narrow_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $144 (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_s - (local.get $0) - ) - ) - (func $145 (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_s - (local.get $0) - ) - ) - (func $146 (type $1) (param $0 v128) (result v128) - (i16x8.extend_low_i8x16_u - (local.get $0) - ) - ) - (func $147 (type $1) (param $0 v128) (result v128) - (i16x8.extend_high_i8x16_u - (local.get $0) - ) - ) - (func $148 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shl - (local.get $0) - (local.get $1) - ) - ) - (func $149 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $150 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i16x8.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $151 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add - (local.get $0) - (local.get $1) - ) - ) - (func $152 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $153 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.add_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $154 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub - (local.get $0) - (local.get $1) - ) - ) - (func $155 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_s - (local.get $0) - (local.get $1) - ) - ) - (func $156 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.sub_sat_u - (local.get $0) - (local.get $1) - ) - ) - (func $157 (type $1) (param $0 v128) (result v128) - (f64x2.nearest - (local.get $0) - ) - ) - (func $158 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.mul - (local.get $0) - (local.get $1) - ) - ) - (func $159 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $160 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $161 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $162 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $163 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.avgr_u - (local.get $0) - (local.get $1) - ) - ) - (func $164 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $165 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_s - (local.get $0) - (local.get $1) - ) - ) - (func $166 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_low_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $167 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i16x8.extmul_high_i8x16_u - (local.get $0) - (local.get $1) - ) - ) - (func $168 (type $1) (param $0 v128) (result v128) - (i32x4.abs - (local.get $0) - ) - ) - (func $169 (type $1) (param $0 v128) (result v128) - (i32x4.neg - (local.get $0) - ) - ) - (func $170 (type $4) (param $0 v128) (result i32) - (i32x4.all_true - (local.get $0) - ) - ) - (func $171 (type $4) (param $0 v128) (result i32) - (i32x4.bitmask - (local.get $0) - ) - ) - (func $172 (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_s - (local.get $0) - ) - ) - (func $173 (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_s - (local.get $0) - ) - ) - (func $174 (type $1) (param $0 v128) (result v128) - (i32x4.extend_low_i16x8_u - (local.get $0) - ) - ) - (func $175 (type $1) (param $0 v128) (result v128) - (i32x4.extend_high_i16x8_u - (local.get $0) - ) - ) - (func $176 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shl - (local.get $0) - (local.get $1) - ) - ) - (func $177 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $178 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i32x4.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $179 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $180 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $181 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $182 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_s - (local.get $0) - (local.get $1) - ) - ) - (func $183 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.min_u - (local.get $0) - (local.get $1) - ) - ) - (func $184 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_s - (local.get $0) - (local.get $1) - ) - ) - (func $185 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.max_u - (local.get $0) - (local.get $1) - ) - ) - (func $186 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.dot_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $187 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $188 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_s - (local.get $0) - (local.get $1) - ) - ) - (func $189 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_low_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $190 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i32x4.extmul_high_i16x8_u - (local.get $0) - (local.get $1) - ) - ) - (func $191 (type $1) (param $0 v128) (result v128) - (i64x2.abs - (local.get $0) - ) - ) - (func $192 (type $1) (param $0 v128) (result v128) - (i64x2.neg - (local.get $0) - ) - ) - (func $193 (type $4) (param $0 v128) (result i32) - (i64x2.all_true - (local.get $0) - ) - ) - (func $194 (type $4) (param $0 v128) (result i32) - (i64x2.bitmask - (local.get $0) - ) - ) - (func $195 (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_s - (local.get $0) - ) - ) - (func $196 (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_s - (local.get $0) - ) - ) - (func $197 (type $1) (param $0 v128) (result v128) - (i64x2.extend_low_i32x4_u - (local.get $0) - ) - ) - (func $198 (type $1) (param $0 v128) (result v128) - (i64x2.extend_high_i32x4_u - (local.get $0) - ) - ) - (func $199 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shl - (local.get $0) - (local.get $1) - ) - ) - (func $200 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_s - (local.get $0) - (local.get $1) - ) - ) - (func $201 (type $3) (param $0 v128) (param $1 i32) (result v128) - (i64x2.shr_u - (local.get $0) - (local.get $1) - ) - ) - (func $202 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $203 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $204 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $205 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.eq - (local.get $0) - (local.get $1) - ) - ) - (func $206 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ne - (local.get $0) - (local.get $1) - ) - ) - (func $207 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.lt_s - (local.get $0) - (local.get $1) - ) - ) - (func $208 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.gt_s - (local.get $0) - (local.get $1) - ) - ) - (func $209 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.le_s - (local.get $0) - (local.get $1) - ) - ) - (func $210 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.ge_s - (local.get $0) - (local.get $1) - ) - ) - (func $211 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $212 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_s - (local.get $0) - (local.get $1) - ) - ) - (func $213 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_low_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $214 (type $0) (param $0 v128) (param $1 v128) (result v128) - (i64x2.extmul_high_i32x4_u - (local.get $0) - (local.get $1) - ) - ) - (func $215 (type $1) (param $0 v128) (result v128) - (f32x4.abs - (local.get $0) - ) - ) - (func $216 (type $1) (param $0 v128) (result v128) - (f32x4.neg - (local.get $0) - ) - ) - (func $217 (type $1) (param $0 v128) (result v128) - (f32x4.sqrt - (local.get $0) - ) - ) - (func $218 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.add - (local.get $0) - (local.get $1) - ) - ) - (func $219 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.sub - (local.get $0) - (local.get $1) - ) - ) - (func $220 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.mul - (local.get $0) - (local.get $1) - ) - ) - (func $221 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.div - (local.get $0) - (local.get $1) - ) - ) - (func $222 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.min - (local.get $0) - (local.get $1) - ) - ) - (func $223 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.max - (local.get $0) - (local.get $1) - ) - ) - (func $224 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $225 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f32x4.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $226 (type $1) (param $0 v128) (result v128) - (f64x2.abs - (local.get $0) - ) - ) - (func $227 (type $1) (param $0 v128) (result v128) - (f64x2.neg - (local.get $0) - ) - ) - (func $228 (type $1) (param $0 v128) (result v128) - (f64x2.sqrt - (local.get $0) - ) - ) - (func $229 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.add - (local.get $0) - (local.get $1) - ) - ) - (func $230 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.sub - (local.get $0) - (local.get $1) - ) - ) - (func $231 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.mul - (local.get $0) - (local.get $1) - ) - ) - (func $232 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.div - (local.get $0) - (local.get $1) - ) - ) - (func $233 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.min - (local.get $0) - (local.get $1) - ) - ) - (func $234 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.max - (local.get $0) - (local.get $1) - ) - ) - (func $235 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmin - (local.get $0) - (local.get $1) - ) - ) - (func $236 (type $0) (param $0 v128) (param $1 v128) (result v128) - (f64x2.pmax - (local.get $0) - (local.get $1) - ) - ) - (func $237 (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_s - (local.get $0) - ) - ) - (func $238 (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f32x4_u - (local.get $0) - ) - ) - (func $239 (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_s - (local.get $0) - ) - ) - (func $240 (type $1) (param $0 v128) (result v128) - (f32x4.convert_i32x4_u - (local.get $0) - ) - ) - (func $241 (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_s_zero - (local.get $0) - ) - ) - (func $242 (type $1) (param $0 v128) (result v128) - (i32x4.trunc_sat_f64x2_u_zero - (local.get $0) - ) - ) - (func $243 (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_s - (local.get $0) - ) - ) - (func $244 (type $1) (param $0 v128) (result v128) - (f64x2.convert_low_i32x4_u - (local.get $0) - ) - ) -) - diff --git a/test/simd64.wast b/test/simd64.wast deleted file mode 100644 index f5cf85055bf..00000000000 --- a/test/simd64.wast +++ /dev/null @@ -1,74 +0,0 @@ -(module - (memory i64 1 1) - (func $v128.load (param $0 i64) (result v128) - (v128.load offset=0 align=16 - (local.get $0) - ) - ) - (func $v128.store (param $0 i64) (param $1 v128) - (v128.store offset=0 align=16 - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_splat (param $0 i64) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (param $0 i64) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (param $0 i64) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (param $0 i64) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.load8x8_u (param $0 i64) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load8x8_s (param $0 i64) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load16x4_s (param $0 i64) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (param $0 i64) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (param $0 i64) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (param $0 i64) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load32_zero (param $0 i64) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (param $0 i64) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) -) diff --git a/test/simd64.wast.from-wast b/test/simd64.wast.from-wast deleted file mode 100644 index 163225ab0e5..00000000000 --- a/test/simd64.wast.from-wast +++ /dev/null @@ -1,76 +0,0 @@ -(module - (type $0 (func (param i64) (result v128))) - (type $1 (func (param i64 v128))) - (memory $0 i64 1 1) - (func $v128.load (type $0) (param $0 i64) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $v128.store (type $1) (param $0 i64) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_splat (type $0) (param $0 i64) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (type $0) (param $0 i64) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (type $0) (param $0 i64) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (type $0) (param $0 i64) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $0) (param $0 i64) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $0) (param $0 i64) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $0) (param $0 i64) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $0) (param $0 i64) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $0) (param $0 i64) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $0) (param $0 i64) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load32_zero (type $0) (param $0 i64) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (type $0) (param $0 i64) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) -) diff --git a/test/simd64.wast.fromBinary b/test/simd64.wast.fromBinary deleted file mode 100644 index 27fa123b0ee..00000000000 --- a/test/simd64.wast.fromBinary +++ /dev/null @@ -1,77 +0,0 @@ -(module - (type $0 (func (param i64) (result v128))) - (type $1 (func (param i64 v128))) - (memory $0 i64 1 1) - (func $v128.load (type $0) (param $0 i64) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $v128.store (type $1) (param $0 i64) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $v128.load8_splat (type $0) (param $0 i64) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $v128.load16_splat (type $0) (param $0 i64) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $v128.load32_splat (type $0) (param $0 i64) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $v128.load64_splat (type $0) (param $0 i64) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $v128.load8x8_u (type $0) (param $0 i64) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $v128.load8x8_s (type $0) (param $0 i64) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $v128.load16x4_s (type $0) (param $0 i64) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $v128.load16x4_u (type $0) (param $0 i64) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $v128.load32x2_s (type $0) (param $0 i64) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $v128.load32x2_u (type $0) (param $0 i64) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $v128.load32_zero (type $0) (param $0 i64) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $v128.load64_zero (type $0) (param $0 i64) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) -) - diff --git a/test/simd64.wast.fromBinary.noDebugInfo b/test/simd64.wast.fromBinary.noDebugInfo deleted file mode 100644 index c77e914aac3..00000000000 --- a/test/simd64.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,77 +0,0 @@ -(module - (type $0 (func (param i64) (result v128))) - (type $1 (func (param i64 v128))) - (memory $0 i64 1 1) - (func $0 (type $0) (param $0 i64) (result v128) - (v128.load - (local.get $0) - ) - ) - (func $1 (type $1) (param $0 i64) (param $1 v128) - (v128.store - (local.get $0) - (local.get $1) - ) - ) - (func $2 (type $0) (param $0 i64) (result v128) - (v128.load8_splat - (local.get $0) - ) - ) - (func $3 (type $0) (param $0 i64) (result v128) - (v128.load16_splat - (local.get $0) - ) - ) - (func $4 (type $0) (param $0 i64) (result v128) - (v128.load32_splat - (local.get $0) - ) - ) - (func $5 (type $0) (param $0 i64) (result v128) - (v128.load64_splat - (local.get $0) - ) - ) - (func $6 (type $0) (param $0 i64) (result v128) - (v128.load8x8_u - (local.get $0) - ) - ) - (func $7 (type $0) (param $0 i64) (result v128) - (v128.load8x8_s - (local.get $0) - ) - ) - (func $8 (type $0) (param $0 i64) (result v128) - (v128.load16x4_s - (local.get $0) - ) - ) - (func $9 (type $0) (param $0 i64) (result v128) - (v128.load16x4_u - (local.get $0) - ) - ) - (func $10 (type $0) (param $0 i64) (result v128) - (v128.load32x2_s - (local.get $0) - ) - ) - (func $11 (type $0) (param $0 i64) (result v128) - (v128.load32x2_u - (local.get $0) - ) - ) - (func $12 (type $0) (param $0 i64) (result v128) - (v128.load32_zero - (local.get $0) - ) - ) - (func $13 (type $0) (param $0 i64) (result v128) - (v128.load64_zero - (local.get $0) - ) - ) -) - diff --git a/test/subtypes.wast b/test/subtypes.wast deleted file mode 100644 index 08059e7231e..00000000000 --- a/test/subtypes.wast +++ /dev/null @@ -1,59 +0,0 @@ -;; Test that we can roundtrip struct and array types -(module - ;; Arrays - (type $vector-i32 (array i32)) - - (type $vector-any (sub (array (ref any)))) - (type $vector-i31 (sub $vector-any (array (ref i31)))) - - ;; Structs - (type $struct-any (sub (struct - (field (ref any)) - ))) - (type $struct-i31 (sub $struct-any (struct - (field (ref i31)) - ))) - (type $struct-i31_any (sub $struct-i31(struct - (field (ref i31)) - (field (ref any)) - ))) - - ;; Recursive structs - (type $struct-rec-one (sub (struct - (field (ref $struct-rec-one)) - ))) - (type $struct-rec-two (sub $struct-rec-one (struct - (field (ref $struct-rec-two)) - (field (ref $struct-rec-two)) - ))) - - (func $foo (param $no-null (ref $vector-i32)) - (param $yes-null (ref null $vector-i32)) - ;; ok to set a non-nullable reference to a nullable target - (local.set $yes-null (local.get $no-null)) - ) - - (func $bar (param $v-i31 (ref $vector-i31)) - (param $v-any (ref $vector-any)) - ;; ok to set a vector of (immutable) i31s to a vector of anyies - (local.set $v-any (local.get $v-i31)) - ) - - (func $baz (param $s-i31 (ref $struct-i31)) - (param $s-any (ref $struct-any)) - ;; ok to set a struct of an (immutable) i31 to a one of an any - (local.set $s-any (local.get $s-i31)) - ) - - (func $boo (param $s-i31 (ref $struct-i31)) - (param $s-i31_any (ref $struct-i31_any)) - ;; also ok to have extra fields - (local.set $s-i31 (local.get $s-i31_any)) - ) - - (func $coinductive (param $rec-one (ref $struct-rec-one)) - (param $rec-two (ref $struct-rec-two)) - ;; Do not infinitely recurse when determining this subtype relation! - (local.set $rec-one (local.get $rec-two)) - ) -) diff --git a/test/subtypes.wast.from-wast b/test/subtypes.wast.from-wast deleted file mode 100644 index 1304c0c3146..00000000000 --- a/test/subtypes.wast.from-wast +++ /dev/null @@ -1,40 +0,0 @@ -(module - (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) - (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) - (type $vector-i32 (array i32)) - (type $struct-any (sub (struct (field (ref any))))) - (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) - (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) - (type $vector-any (sub (array (ref any)))) - (type $vector-i31 (sub $vector-any (array (ref i31)))) - (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) - (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) - (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) - (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) - (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) - (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) - (local.set $yes-null - (local.get $no-null) - ) - ) - (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) - (local.set $v-any - (local.get $v-i31) - ) - ) - (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) - (local.set $s-any - (local.get $s-i31) - ) - ) - (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) - (local.set $s-i31 - (local.get $s-i31_any) - ) - ) - (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) - (local.set $rec-one - (local.get $rec-two) - ) - ) -) diff --git a/test/subtypes.wast.fromBinary b/test/subtypes.wast.fromBinary deleted file mode 100644 index 6a3ef7345f8..00000000000 --- a/test/subtypes.wast.fromBinary +++ /dev/null @@ -1,41 +0,0 @@ -(module - (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) - (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) - (type $vector-i32 (array i32)) - (type $struct-any (sub (struct (field (ref any))))) - (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) - (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) - (type $vector-any (sub (array (ref any)))) - (type $vector-i31 (sub $vector-any (array (ref i31)))) - (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) - (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) - (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) - (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) - (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) - (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) - (local.set $yes-null - (local.get $no-null) - ) - ) - (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) - (local.set $v-any - (local.get $v-i31) - ) - ) - (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) - (local.set $s-any - (local.get $s-i31) - ) - ) - (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) - (local.set $s-i31 - (local.get $s-i31_any) - ) - ) - (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) - (local.set $rec-one - (local.get $rec-two) - ) - ) -) - diff --git a/test/subtypes.wast.fromBinary.noDebugInfo b/test/subtypes.wast.fromBinary.noDebugInfo deleted file mode 100644 index 29e5755552f..00000000000 --- a/test/subtypes.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,41 +0,0 @@ -(module - (type $0 (sub (struct (field (ref $0))))) - (type $1 (sub $0 (struct (field (ref $1)) (field (ref $1))))) - (type $2 (array i32)) - (type $3 (sub (struct (field (ref any))))) - (type $4 (sub $3 (struct (field (ref i31))))) - (type $5 (func (param (ref $2) (ref null $2)))) - (type $6 (sub (array (ref any)))) - (type $7 (sub $6 (array (ref i31)))) - (type $8 (func (param (ref $7) (ref $6)))) - (type $9 (func (param (ref $4) (ref $3)))) - (type $10 (sub $4 (struct (field (ref i31)) (field (ref any))))) - (type $11 (func (param (ref $4) (ref $10)))) - (type $12 (func (param (ref $0) (ref $1)))) - (func $0 (type $5) (param $0 (ref $2)) (param $1 (ref null $2)) - (local.set $1 - (local.get $0) - ) - ) - (func $1 (type $8) (param $0 (ref $7)) (param $1 (ref $6)) - (local.set $1 - (local.get $0) - ) - ) - (func $2 (type $9) (param $0 (ref $4)) (param $1 (ref $3)) - (local.set $1 - (local.get $0) - ) - ) - (func $3 (type $11) (param $0 (ref $4)) (param $1 (ref $10)) - (local.set $0 - (local.get $1) - ) - ) - (func $4 (type $12) (param $0 (ref $0)) (param $1 (ref $1)) - (local.set $0 - (local.get $1) - ) - ) -) - diff --git a/test/table-import.wast b/test/table-import.wast deleted file mode 100644 index bbce9e2fd03..00000000000 --- a/test/table-import.wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func)) - (import "env" "table" (table 1 1 funcref)) - (elem (i32.const 0) $foo) - (memory $0 0) - (func $foo (type $0) - (nop) - ) -) diff --git a/test/table-import.wast.from-wast b/test/table-import.wast.from-wast deleted file mode 100644 index ab805d22dac..00000000000 --- a/test/table-import.wast.from-wast +++ /dev/null @@ -1,9 +0,0 @@ -(module - (type $0 (func)) - (import "env" "table" (table $timport$0 1 1 funcref)) - (memory $0 0) - (elem $0 (i32.const 0) $foo) - (func $foo (type $0) - (nop) - ) -) diff --git a/test/table-import.wast.fromBinary b/test/table-import.wast.fromBinary deleted file mode 100644 index 52043bc10fe..00000000000 --- a/test/table-import.wast.fromBinary +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func)) - (import "env" "table" (table $timport$0 1 1 funcref)) - (memory $0 0) - (elem $0 (i32.const 0) $foo) - (func $foo (type $0) - (nop) - ) -) - diff --git a/test/table-import.wast.fromBinary.noDebugInfo b/test/table-import.wast.fromBinary.noDebugInfo deleted file mode 100644 index 6c92becc8a1..00000000000 --- a/test/table-import.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $0 (func)) - (import "env" "table" (table $timport$0 1 1 funcref)) - (memory $0 0) - (elem $0 (i32.const 0) $0) - (func $0 (type $0) - (nop) - ) -) - diff --git a/test/tags.wast b/test/tags.wast deleted file mode 100644 index 6dc383a8659..00000000000 --- a/test/tags.wast +++ /dev/null @@ -1,16 +0,0 @@ -;; Test tags - -(module - (tag (param i32)) - (tag $e (param i32 f32)) - (tag $empty) - - (tag $e-params0 (param i32 f32)) - (tag $e-params1 (param i32) (param f32)) - - (tag $e-export (export "ex0") (param i32)) - (tag $e-import (import "env" "im0") (param i32)) - - (import "env" "im1" (tag (param i32 f32))) - (export "ex1" (tag $e)) -) diff --git a/test/tags.wast.from-wast b/test/tags.wast.from-wast deleted file mode 100644 index 8b1645a0b9e..00000000000 --- a/test/tags.wast.from-wast +++ /dev/null @@ -1,15 +0,0 @@ -(module - (type $0 (func (param i32 f32))) - (type $1 (func (param i32))) - (type $2 (func)) - (import "env" "im0" (tag $e-import (param i32))) - (import "env" "im1" (tag $eimport$1 (param i32 f32))) - (tag $2 (param i32)) - (tag $e (param i32 f32)) - (tag $empty) - (tag $e-params0 (param i32 f32)) - (tag $e-params1 (param i32 f32)) - (tag $e-export (param i32)) - (export "ex0" (tag $e-export)) - (export "ex1" (tag $e)) -) diff --git a/test/tags.wast.fromBinary b/test/tags.wast.fromBinary deleted file mode 100644 index 99b478addc6..00000000000 --- a/test/tags.wast.fromBinary +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $0 (func (param i32 f32))) - (type $1 (func (param i32))) - (type $2 (func)) - (import "env" "im0" (tag $e-import (param i32))) - (import "env" "im1" (tag $eimport$1 (param i32 f32))) - (tag $tag$0 (param i32)) - (tag $e (param i32 f32)) - (tag $empty) - (tag $e-params0 (param i32 f32)) - (tag $e-params1 (param i32 f32)) - (tag $e-export (param i32)) - (export "ex0" (tag $e-export)) - (export "ex1" (tag $e)) -) - diff --git a/test/tags.wast.fromBinary.noDebugInfo b/test/tags.wast.fromBinary.noDebugInfo deleted file mode 100644 index 6cd126efb8a..00000000000 --- a/test/tags.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $0 (func (param i32 f32))) - (type $1 (func (param i32))) - (type $2 (func)) - (import "env" "im0" (tag $eimport$0 (param i32))) - (import "env" "im1" (tag $eimport$1 (param i32 f32))) - (tag $tag$0 (param i32)) - (tag $tag$1 (param i32 f32)) - (tag $tag$2) - (tag $tag$3 (param i32 f32)) - (tag $tag$4 (param i32 f32)) - (tag $tag$5 (param i32)) - (export "ex0" (tag $tag$5)) - (export "ex1" (tag $tag$1)) -) - diff --git a/test/tail-call.wast.from-wast b/test/tail-call.wast.from-wast deleted file mode 100644 index 3c0e0c15075..00000000000 --- a/test/tail-call.wast.from-wast +++ /dev/null @@ -1,13 +0,0 @@ -(module - (type $void (func)) - (table $0 1 1 funcref) - (elem (i32.const 0) $foo) - (func $foo - (return_call $bar) - ) - (func $bar - (return_call_indirect $0 (type $void) - (i32.const 0) - ) - ) -) diff --git a/test/tail-call.wast.fromBinary b/test/tail-call.wast.fromBinary deleted file mode 100644 index 81a5c4f9f97..00000000000 --- a/test/tail-call.wast.fromBinary +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $void (func)) - (table $0 1 1 funcref) - (elem (i32.const 0) $foo) - (func $foo - (return_call $bar) - ) - (func $bar - (return_call_indirect $0 (type $void) - (i32.const 0) - ) - ) -) - diff --git a/test/tail-call.wast.fromBinary.noDebugInfo b/test/tail-call.wast.fromBinary.noDebugInfo deleted file mode 100644 index 91962633070..00000000000 --- a/test/tail-call.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,14 +0,0 @@ -(module - (type $none_=>_none (func)) - (table $0 1 1 funcref) - (elem (i32.const 0) $0) - (func $0 - (return_call $1) - ) - (func $1 - (return_call_indirect $0 (type $none_=>_none) - (i32.const 0) - ) - ) -) - diff --git a/test/unit.wast.from-wast b/test/unit.wast.from-wast deleted file mode 100644 index bba5203e07a..00000000000 --- a/test/unit.wast.from-wast +++ /dev/null @@ -1,619 +0,0 @@ -(module - (type $none_=>_i32 (func (result i32))) - (type $none_=>_none (func)) - (type $f32_=>_none (func (param f32))) - (type $none_=>_f64 (func (result f64))) - (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) - (type $i32_i64_=>_none (func (param i32 i64))) - (type $i32_=>_i32 (func (param i32) (result i32))) - (type $f64_=>_i32 (func (param f64) (result i32))) - (type $none_=>_i64 (func (result i64))) - (type $f64_=>_f64 (func (param f64) (result f64))) - (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) - (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) - (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) - (memory $0 4096 4096) - (data (i32.const 1026) "\14\00") - (table $0 10 funcref) - (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) - (export "big_negative" (func $big_negative)) - (func $big_negative (; 3 ;) - (local $temp f64) - (block $block0 - (local.set $temp - (f64.const -2147483648) - ) - (local.set $temp - (f64.const -2147483648) - ) - (local.set $temp - (f64.const -21474836480) - ) - (local.set $temp - (f64.const 0.039625) - ) - (local.set $temp - (f64.const -0.039625) - ) - ) - ) - (func $importedDoubles (; 4 ;) (result f64) - (local $temp f64) - (block $topmost (result f64) - (local.set $temp - (f64.add - (f64.add - (f64.add - (f64.load - (i32.const 8) - ) - (f64.load - (i32.const 16) - ) - ) - (f64.neg - (f64.load - (i32.const 16) - ) - ) - ) - (f64.neg - (f64.load - (i32.const 8) - ) - ) - ) - ) - (if - (i32.gt_s - (i32.load - (i32.const 24) - ) - (i32.const 0) - ) - (br $topmost - (f64.const -3.4) - ) - ) - (if - (f64.gt - (f64.load - (i32.const 32) - ) - (f64.const 0) - ) - (br $topmost - (f64.const 5.6) - ) - ) - (f64.const 1.2) - ) - ) - (func $doubleCompares (; 5 ;) (param $x f64) (param $y f64) (result f64) - (local $t f64) - (local $Int f64) - (local $Double i32) - (block $topmost (result f64) - (if - (f64.gt - (local.get $x) - (f64.const 0) - ) - (br $topmost - (f64.const 1.2) - ) - ) - (if - (f64.gt - (local.get $Int) - (f64.const 0) - ) - (br $topmost - (f64.const -3.4) - ) - ) - (if - (i32.gt_s - (local.get $Double) - (i32.const 0) - ) - (br $topmost - (f64.const 5.6) - ) - ) - (if - (f64.lt - (local.get $x) - (local.get $y) - ) - (br $topmost - (local.get $x) - ) - ) - (local.get $y) - ) - ) - (func $intOps (; 6 ;) (result i32) - (local $x i32) - (i32.eq - (local.get $x) - (i32.const 0) - ) - ) - (func $hexLiterals (; 7 ;) - (drop - (i32.add - (i32.add - (i32.const 0) - (i32.const 313249263) - ) - (i32.const -19088752) - ) - ) - ) - (func $conversions (; 8 ;) - (local $i i32) - (local $d f64) - (block $block0 - (local.set $i - (call $f64-to-int - (local.get $d) - ) - ) - (local.set $d - (f64.convert_i32_s - (local.get $i) - ) - ) - (local.set $d - (f64.convert_i32_u - (i32.shr_u - (local.get $i) - (i32.const 0) - ) - ) - ) - ) - ) - (func $seq (; 9 ;) - (local $J f64) - (local.set $J - (f64.sub - (block $block0 (result f64) - (drop - (f64.const 0.1) - ) - (f64.const 5.1) - ) - (block $block1 (result f64) - (drop - (f64.const 3.2) - ) - (f64.const 4.2) - ) - ) - ) - ) - (func $switcher (; 10 ;) (param $x i32) (result i32) - (block $topmost (result i32) - (block $switch$0 - (block $switch-default$3 - (block $switch-case$2 - (block $switch-case$1 - (br_table $switch-case$1 $switch-case$2 $switch-default$3 - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - ) - (br $topmost - (i32.const 1) - ) - ) - (br $topmost - (i32.const 2) - ) - ) - (nop) - ) - (block $switch$4 - (block $switch-default$7 - (block $switch-case$6 - (block $switch-case$5 - (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 - (i32.sub - (local.get $x) - (i32.const 5) - ) - ) - ) - (br $topmost - (i32.const 121) - ) - ) - (br $topmost - (i32.const 51) - ) - ) - (nop) - ) - (block $label$break$Lout - (block $switch-default$16 - (block $switch-case$15 - (block $switch-case$12 - (block $switch-case$9 - (block $switch-case$8 - (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 - (i32.sub - (local.get $x) - (i32.const 2) - ) - ) - ) - (br $label$break$Lout) - ) - (br $label$break$Lout) - ) - (block $while-out$10 - (loop $while-in$11 - (block $block1 - (br $while-out$10) - (br $while-in$11) - ) - ) - (br $label$break$Lout) - ) - ) - (block $while-out$13 - (loop $while-in$14 - (block $block3 - (br $label$break$Lout) - (br $while-in$14) - ) - ) - (br $label$break$Lout) - ) - ) - (nop) - ) - (i32.const 0) - ) - ) - (func $blocker (; 11 ;) - (block $label$break$L - (br $label$break$L) - ) - ) - (func $frem (; 12 ;) (result f64) - (call $f64-rem - (f64.const 5.5) - (f64.const 1.2) - ) - ) - (func $big_uint_div_u (; 13 ;) (result i32) - (local $x i32) - (block $topmost (result i32) - (local.set $x - (i32.and - (i32.div_u - (i32.const -1) - (i32.const 2) - ) - (i32.const -1) - ) - ) - (local.get $x) - ) - ) - (func $fr (; 14 ;) (param $x f32) - (local $y f32) - (local $z f64) - (block $block0 - (drop - (f32.demote_f64 - (local.get $z) - ) - ) - (drop - (local.get $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - ) - ) - (func $negZero (; 15 ;) (result f64) - (f64.const -0) - ) - (func $abs (; 16 ;) - (local $x i32) - (local $y f64) - (local $z f32) - (local $asm2wasm_i32_temp i32) - (block $block0 - (local.set $x - (block $block1 (result i32) - (local.set $asm2wasm_i32_temp - (i32.const 0) - ) - (select - (i32.sub - (i32.const 0) - (local.get $asm2wasm_i32_temp) - ) - (local.get $asm2wasm_i32_temp) - (i32.lt_s - (local.get $asm2wasm_i32_temp) - (i32.const 0) - ) - ) - ) - ) - (local.set $y - (f64.abs - (f64.const 0) - ) - ) - (local.set $z - (f32.abs - (f32.const 0) - ) - ) - ) - ) - (func $neg (; 17 ;) - (local $x f32) - (block $block0 - (local.set $x - (f32.neg - (local.get $x) - ) - ) - (call_indirect (type $f32_=>_none) - (local.get $x) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - ) - (func $cneg (; 18 ;) (param $x f32) - (call_indirect (type $f32_=>_none) - (local.get $x) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $___syscall_ret (; 19 ;) - (local $$0 i32) - (drop - (i32.gt_u - (i32.shr_u - (local.get $$0) - (i32.const 0) - ) - (i32.const -4096) - ) - ) - ) - (func $z (; 20 ;) - (nop) - ) - (func $w (; 21 ;) - (nop) - ) - (func $block_and_after (; 22 ;) (result i32) - (block $waka - (drop - (i32.const 1) - ) - (br $waka) - ) - (i32.const 0) - ) - (func $loop-roundtrip (; 23 ;) (param $0 f64) (result f64) - (loop $loop-in1 (result f64) - (drop - (local.get $0) - ) - (local.get $0) - ) - ) - (func $big-i64 (; 24 ;) (result i64) - (i64.const -9218868437227405313) - ) - (func $i64-store32 (; 25 ;) (param $0 i32) (param $1 i64) - (i64.store32 - (local.get $0) - (local.get $1) - ) - ) - (func $return-unreachable (; 26 ;) (result i32) - (return - (i32.const 1) - ) - ) - (func $unreachable-block (; 27 ;) (result i32) - (f64.abs - (block $block - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - ) - ) - (func $unreachable-block-toplevel (; 28 ;) (result i32) - (block $block - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - ) - (func $unreachable-block0 (; 29 ;) (result i32) - (f64.abs - (block $block - (return - (i32.const 2) - ) - ) - ) - ) - (func $unreachable-block0-toplevel (; 30 ;) (result i32) - (block $block - (return - (i32.const 2) - ) - ) - ) - (func $unreachable-block-with-br (; 31 ;) (result i32) - (block $block - (drop - (i32.const 1) - ) - (br $block) - ) - (i32.const 1) - ) - (func $unreachable-if (; 32 ;) (result i32) - (f64.abs - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - ) - (func $unreachable-if-toplevel (; 33 ;) (result i32) - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop (; 34 ;) (result i32) - (f64.abs - (loop $loop-in - (nop) - (return - (i32.const 1) - ) - ) - ) - ) - (func $unreachable-loop0 (; 35 ;) (result i32) - (f64.abs - (loop $loop-in - (return - (i32.const 1) - ) - ) - ) - ) - (func $unreachable-loop-toplevel (; 36 ;) (result i32) - (loop $loop-in - (nop) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop0-toplevel (; 37 ;) (result i32) - (loop $loop-in - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-ifs (; 38 ;) - (if - (unreachable) - (nop) - ) - (if - (unreachable) - (unreachable) - ) - (if - (unreachable) - (nop) - (nop) - ) - (if - (unreachable) - (unreachable) - (nop) - ) - (if - (unreachable) - (nop) - (unreachable) - ) - (if - (unreachable) - (unreachable) - (unreachable) - ) - (if - (i32.const 1) - (unreachable) - (nop) - ) - (if - (i32.const 1) - (nop) - (unreachable) - ) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $unreachable-if-arm (; 39 ;) - (if - (i32.const 1) - (block $block - (nop) - ) - (block $block12 - (unreachable) - (drop - (i32.const 1) - ) - ) - ) - ) -) diff --git a/test/unit.wast.fromBinary b/test/unit.wast.fromBinary deleted file mode 100644 index 9564e9ecaba..00000000000 --- a/test/unit.wast.fromBinary +++ /dev/null @@ -1,537 +0,0 @@ -(module - (type $none_=>_i32 (func (result i32))) - (type $none_=>_none (func)) - (type $f32_=>_none (func (param f32))) - (type $none_=>_f64 (func (result f64))) - (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) - (type $i32_i64_=>_none (func (param i32 i64))) - (type $i32_=>_i32 (func (param i32) (result i32))) - (type $f64_=>_i32 (func (param f64) (result i32))) - (type $none_=>_i64 (func (result i64))) - (type $f64_=>_f64 (func (param f64) (result f64))) - (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) - (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) - (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) - (memory $0 4096 4096) - (data (i32.const 1026) "\14\00") - (table $0 10 funcref) - (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) - (export "big_negative" (func $big_negative)) - (func $big_negative (; 3 ;) - (local $0 f64) - (local.set $0 - (f64.const -2147483648) - ) - (local.set $0 - (f64.const -2147483648) - ) - (local.set $0 - (f64.const -21474836480) - ) - (local.set $0 - (f64.const 0.039625) - ) - (local.set $0 - (f64.const -0.039625) - ) - ) - (func $importedDoubles (; 4 ;) (result f64) - (local $0 f64) - (block $label$1 (result f64) - (local.set $0 - (f64.add - (f64.add - (f64.add - (f64.load - (i32.const 8) - ) - (f64.load - (i32.const 16) - ) - ) - (f64.neg - (f64.load - (i32.const 16) - ) - ) - ) - (f64.neg - (f64.load - (i32.const 8) - ) - ) - ) - ) - (if - (i32.gt_s - (i32.load - (i32.const 24) - ) - (i32.const 0) - ) - (br $label$1 - (f64.const -3.4) - ) - ) - (if - (f64.gt - (f64.load - (i32.const 32) - ) - (f64.const 0) - ) - (br $label$1 - (f64.const 5.6) - ) - ) - (f64.const 1.2) - ) - ) - (func $doubleCompares (; 5 ;) (param $0 f64) (param $1 f64) (result f64) - (local $2 i32) - (local $3 f64) - (local $4 f64) - (block $label$1 (result f64) - (if - (f64.gt - (local.get $0) - (f64.const 0) - ) - (br $label$1 - (f64.const 1.2) - ) - ) - (if - (f64.gt - (local.get $4) - (f64.const 0) - ) - (br $label$1 - (f64.const -3.4) - ) - ) - (if - (i32.gt_s - (local.get $2) - (i32.const 0) - ) - (br $label$1 - (f64.const 5.6) - ) - ) - (if - (f64.lt - (local.get $0) - (local.get $1) - ) - (br $label$1 - (local.get $0) - ) - ) - (local.get $1) - ) - ) - (func $intOps (; 6 ;) (result i32) - (local $0 i32) - (i32.eq - (local.get $0) - (i32.const 0) - ) - ) - (func $hexLiterals (; 7 ;) - (drop - (i32.add - (i32.add - (i32.const 0) - (i32.const 313249263) - ) - (i32.const -19088752) - ) - ) - ) - (func $conversions (; 8 ;) - (local $0 i32) - (local $1 f64) - (local.set $0 - (call $f64-to-int - (local.get $1) - ) - ) - (local.set $1 - (f64.convert_i32_s - (local.get $0) - ) - ) - (local.set $1 - (f64.convert_i32_u - (i32.shr_u - (local.get $0) - (i32.const 0) - ) - ) - ) - ) - (func $seq (; 9 ;) - (local $0 f64) - (local.set $0 - (f64.sub - (block $label$1 (result f64) - (drop - (f64.const 0.1) - ) - (f64.const 5.1) - ) - (block $label$2 (result f64) - (drop - (f64.const 3.2) - ) - (f64.const 4.2) - ) - ) - ) - ) - (func $switcher (; 10 ;) (param $0 i32) (result i32) - (block $label$1 (result i32) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_table $label$5 $label$4 $label$3 - (i32.sub - (local.get $0) - (i32.const 1) - ) - ) - ) - (br $label$1 - (i32.const 1) - ) - ) - (br $label$1 - (i32.const 2) - ) - ) - (nop) - ) - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_table $label$8 $label$7 $label$7 $label$7 $label$7 $label$7 $label$7 $label$9 $label$7 - (i32.sub - (local.get $0) - (i32.const 5) - ) - ) - ) - (br $label$1 - (i32.const 121) - ) - ) - (br $label$1 - (i32.const 51) - ) - ) - (nop) - ) - (block $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_table $label$12 $label$11 $label$11 $label$13 $label$11 $label$11 $label$11 $label$11 $label$14 $label$11 $label$15 $label$11 - (i32.sub - (local.get $0) - (i32.const 2) - ) - ) - ) - (br $label$10) - ) - (br $label$10) - ) - (block $label$16 - (loop $label$17 - (br $label$16) - ) - ) - ) - (block $label$18 - (loop $label$19 - (br $label$10) - ) - ) - ) - (nop) - ) - (i32.const 0) - ) - ) - (func $blocker (; 11 ;) - (block $label$1 - (br $label$1) - ) - ) - (func $frem (; 12 ;) (result f64) - (call $f64-rem - (f64.const 5.5) - (f64.const 1.2) - ) - ) - (func $big_uint_div_u (; 13 ;) (result i32) - (local $0 i32) - (local.set $0 - (i32.and - (i32.div_u - (i32.const -1) - (i32.const 2) - ) - (i32.const -1) - ) - ) - (local.get $0) - ) - (func $fr (; 14 ;) (param $0 f32) - (local $1 f32) - (local $2 f64) - (drop - (f32.demote_f64 - (local.get $2) - ) - ) - (drop - (local.get $1) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - ) - (func $negZero (; 15 ;) (result f64) - (f64.const -0) - ) - (func $abs (; 16 ;) - (local $0 i32) - (local $1 i32) - (local $2 f32) - (local $3 f64) - (local.set $0 - (block $label$1 (result i32) - (local.set $1 - (i32.const 0) - ) - (select - (i32.sub - (i32.const 0) - (local.get $1) - ) - (local.get $1) - (i32.lt_s - (local.get $1) - (i32.const 0) - ) - ) - ) - ) - (local.set $3 - (f64.abs - (f64.const 0) - ) - ) - (local.set $2 - (f32.abs - (f32.const 0) - ) - ) - ) - (func $neg (; 17 ;) - (local $0 f32) - (local.set $0 - (f32.neg - (local.get $0) - ) - ) - (call_indirect (type $f32_=>_none) - (local.get $0) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $cneg (; 18 ;) (param $0 f32) - (call_indirect (type $f32_=>_none) - (local.get $0) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $___syscall_ret (; 19 ;) - (local $0 i32) - (drop - (i32.gt_u - (i32.shr_u - (local.get $0) - (i32.const 0) - ) - (i32.const -4096) - ) - ) - ) - (func $z (; 20 ;) - (nop) - ) - (func $w (; 21 ;) - (nop) - ) - (func $block_and_after (; 22 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (br $label$1) - ) - (i32.const 0) - ) - (func $loop-roundtrip (; 23 ;) (param $0 f64) (result f64) - (loop $label$1 (result f64) - (drop - (local.get $0) - ) - (local.get $0) - ) - ) - (func $big-i64 (; 24 ;) (result i64) - (i64.const -9218868437227405313) - ) - (func $i64-store32 (; 25 ;) (param $0 i32) (param $1 i64) - (i64.store32 - (local.get $0) - (local.get $1) - ) - ) - (func $return-unreachable (; 26 ;) (result i32) - (return - (i32.const 1) - ) - ) - (func $unreachable-block (; 27 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - ) - (func $unreachable-block-toplevel (; 28 ;) (result i32) - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - (func $unreachable-block0 (; 29 ;) (result i32) - (block $label$1 - (return - (i32.const 2) - ) - ) - ) - (func $unreachable-block0-toplevel (; 30 ;) (result i32) - (return - (i32.const 2) - ) - ) - (func $unreachable-block-with-br (; 31 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (br $label$1) - ) - (i32.const 1) - ) - (func $unreachable-if (; 32 ;) (result i32) - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-if-toplevel (; 33 ;) (result i32) - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop (; 34 ;) (result i32) - (loop $label$1 - (nop) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop0 (; 35 ;) (result i32) - (loop $label$1 - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop-toplevel (; 36 ;) (result i32) - (loop $label$1 - (nop) - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-loop0-toplevel (; 37 ;) (result i32) - (loop $label$1 - (return - (i32.const 1) - ) - ) - ) - (func $unreachable-ifs (; 38 ;) - (unreachable) - ) - (func $unreachable-if-arm (; 39 ;) - (if - (i32.const 1) - (nop) - (unreachable) - ) - ) -) - diff --git a/test/unit.wast.fromBinary.noDebugInfo b/test/unit.wast.fromBinary.noDebugInfo deleted file mode 100644 index 8ad733079d2..00000000000 --- a/test/unit.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,537 +0,0 @@ -(module - (type $none_=>_i32 (func (result i32))) - (type $none_=>_none (func)) - (type $f32_=>_none (func (param f32))) - (type $none_=>_f64 (func (result f64))) - (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) - (type $i32_i64_=>_none (func (param i32 i64))) - (type $i32_=>_i32 (func (param i32) (result i32))) - (type $f64_=>_i32 (func (param f64) (result i32))) - (type $none_=>_i64 (func (result i64))) - (type $f64_=>_f64 (func (param f64) (result f64))) - (import "env" "_emscripten_asm_const_vi" (func $fimport$0)) - (import "asm2wasm" "f64-to-int" (func $fimport$1 (param f64) (result i32))) - (import "asm2wasm" "f64-rem" (func $fimport$2 (param f64 f64) (result f64))) - (memory $0 4096 4096) - (data (i32.const 1026) "\14\00") - (table $0 10 funcref) - (elem (i32.const 0) $17 $0 $17 $17 $18 $18 $1 $18 $17 $15) - (export "big_negative" (func $0)) - (func $0 (; 3 ;) - (local $0 f64) - (local.set $0 - (f64.const -2147483648) - ) - (local.set $0 - (f64.const -2147483648) - ) - (local.set $0 - (f64.const -21474836480) - ) - (local.set $0 - (f64.const 0.039625) - ) - (local.set $0 - (f64.const -0.039625) - ) - ) - (func $1 (; 4 ;) (result f64) - (local $0 f64) - (block $label$1 (result f64) - (local.set $0 - (f64.add - (f64.add - (f64.add - (f64.load - (i32.const 8) - ) - (f64.load - (i32.const 16) - ) - ) - (f64.neg - (f64.load - (i32.const 16) - ) - ) - ) - (f64.neg - (f64.load - (i32.const 8) - ) - ) - ) - ) - (if - (i32.gt_s - (i32.load - (i32.const 24) - ) - (i32.const 0) - ) - (br $label$1 - (f64.const -3.4) - ) - ) - (if - (f64.gt - (f64.load - (i32.const 32) - ) - (f64.const 0) - ) - (br $label$1 - (f64.const 5.6) - ) - ) - (f64.const 1.2) - ) - ) - (func $2 (; 5 ;) (param $0 f64) (param $1 f64) (result f64) - (local $2 i32) - (local $3 f64) - (local $4 f64) - (block $label$1 (result f64) - (if - (f64.gt - (local.get $0) - (f64.const 0) - ) - (br $label$1 - (f64.const 1.2) - ) - ) - (if - (f64.gt - (local.get $4) - (f64.const 0) - ) - (br $label$1 - (f64.const -3.4) - ) - ) - (if - (i32.gt_s - (local.get $2) - (i32.const 0) - ) - (br $label$1 - (f64.const 5.6) - ) - ) - (if - (f64.lt - (local.get $0) - (local.get $1) - ) - (br $label$1 - (local.get $0) - ) - ) - (local.get $1) - ) - ) - (func $3 (; 6 ;) (result i32) - (local $0 i32) - (i32.eq - (local.get $0) - (i32.const 0) - ) - ) - (func $4 (; 7 ;) - (drop - (i32.add - (i32.add - (i32.const 0) - (i32.const 313249263) - ) - (i32.const -19088752) - ) - ) - ) - (func $5 (; 8 ;) - (local $0 i32) - (local $1 f64) - (local.set $0 - (call $fimport$1 - (local.get $1) - ) - ) - (local.set $1 - (f64.convert_i32_s - (local.get $0) - ) - ) - (local.set $1 - (f64.convert_i32_u - (i32.shr_u - (local.get $0) - (i32.const 0) - ) - ) - ) - ) - (func $6 (; 9 ;) - (local $0 f64) - (local.set $0 - (f64.sub - (block $label$1 (result f64) - (drop - (f64.const 0.1) - ) - (f64.const 5.1) - ) - (block $label$2 (result f64) - (drop - (f64.const 3.2) - ) - (f64.const 4.2) - ) - ) - ) - ) - (func $7 (; 10 ;) (param $0 i32) (result i32) - (block $label$1 (result i32) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_table $label$5 $label$4 $label$3 - (i32.sub - (local.get $0) - (i32.const 1) - ) - ) - ) - (br $label$1 - (i32.const 1) - ) - ) - (br $label$1 - (i32.const 2) - ) - ) - (nop) - ) - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_table $label$8 $label$7 $label$7 $label$7 $label$7 $label$7 $label$7 $label$9 $label$7 - (i32.sub - (local.get $0) - (i32.const 5) - ) - ) - ) - (br $label$1 - (i32.const 121) - ) - ) - (br $label$1 - (i32.const 51) - ) - ) - (nop) - ) - (block $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_table $label$12 $label$11 $label$11 $label$13 $label$11 $label$11 $label$11 $label$11 $label$14 $label$11 $label$15 $label$11 - (i32.sub - (local.get $0) - (i32.const 2) - ) - ) - ) - (br $label$10) - ) - (br $label$10) - ) - (block $label$16 - (loop $label$17 - (br $label$16) - ) - ) - ) - (block $label$18 - (loop $label$19 - (br $label$10) - ) - ) - ) - (nop) - ) - (i32.const 0) - ) - ) - (func $8 (; 11 ;) - (block $label$1 - (br $label$1) - ) - ) - (func $9 (; 12 ;) (result f64) - (call $fimport$2 - (f64.const 5.5) - (f64.const 1.2) - ) - ) - (func $10 (; 13 ;) (result i32) - (local $0 i32) - (local.set $0 - (i32.and - (i32.div_u - (i32.const -1) - (i32.const 2) - ) - (i32.const -1) - ) - ) - (local.get $0) - ) - (func $11 (; 14 ;) (param $0 f32) - (local $1 f32) - (local $2 f64) - (drop - (f32.demote_f64 - (local.get $2) - ) - ) - (drop - (local.get $1) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - ) - (func $12 (; 15 ;) (result f64) - (f64.const -0) - ) - (func $13 (; 16 ;) - (local $0 i32) - (local $1 i32) - (local $2 f32) - (local $3 f64) - (local.set $0 - (block $label$1 (result i32) - (local.set $1 - (i32.const 0) - ) - (select - (i32.sub - (i32.const 0) - (local.get $1) - ) - (local.get $1) - (i32.lt_s - (local.get $1) - (i32.const 0) - ) - ) - ) - ) - (local.set $3 - (f64.abs - (f64.const 0) - ) - ) - (local.set $2 - (f32.abs - (f32.const 0) - ) - ) - ) - (func $14 (; 17 ;) - (local $0 f32) - (local.set $0 - (f32.neg - (local.get $0) - ) - ) - (call_indirect (type $f32_=>_none) - (local.get $0) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $15 (; 18 ;) (param $0 f32) - (call_indirect (type $f32_=>_none) - (local.get $0) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $16 (; 19 ;) - (local $0 i32) - (drop - (i32.gt_u - (i32.shr_u - (local.get $0) - (i32.const 0) - ) - (i32.const -4096) - ) - ) - ) - (func $17 (; 20 ;) - (nop) - ) - (func $18 (; 21 ;) - (nop) - ) - (func $19 (; 22 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (br $label$1) - ) - (i32.const 0) - ) - (func $20 (; 23 ;) (param $0 f64) (result f64) - (loop $label$1 (result f64) - (drop - (local.get $0) - ) - (local.get $0) - ) - ) - (func $21 (; 24 ;) (result i64) - (i64.const -9218868437227405313) - ) - (func $22 (; 25 ;) (param $0 i32) (param $1 i64) - (i64.store32 - (local.get $0) - (local.get $1) - ) - ) - (func $23 (; 26 ;) (result i32) - (return - (i32.const 1) - ) - ) - (func $24 (; 27 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - ) - (func $25 (; 28 ;) (result i32) - (drop - (i32.const 1) - ) - (return - (i32.const 2) - ) - ) - (func $26 (; 29 ;) (result i32) - (block $label$1 - (return - (i32.const 2) - ) - ) - ) - (func $27 (; 30 ;) (result i32) - (return - (i32.const 2) - ) - ) - (func $28 (; 31 ;) (result i32) - (block $label$1 - (drop - (i32.const 1) - ) - (br $label$1) - ) - (i32.const 1) - ) - (func $29 (; 32 ;) (result i32) - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - (func $30 (; 33 ;) (result i32) - (if - (i32.const 3) - (return - (i32.const 2) - ) - (return - (i32.const 1) - ) - ) - ) - (func $31 (; 34 ;) (result i32) - (loop $label$1 - (nop) - (return - (i32.const 1) - ) - ) - ) - (func $32 (; 35 ;) (result i32) - (loop $label$1 - (return - (i32.const 1) - ) - ) - ) - (func $33 (; 36 ;) (result i32) - (loop $label$1 - (nop) - (return - (i32.const 1) - ) - ) - ) - (func $34 (; 37 ;) (result i32) - (loop $label$1 - (return - (i32.const 1) - ) - ) - ) - (func $35 (; 38 ;) - (unreachable) - ) - (func $36 (; 39 ;) - (if - (i32.const 1) - (nop) - (unreachable) - ) - ) -) - diff --git a/test/unit.wat b/test/unit.wat deleted file mode 100644 index 6d15b26d1c8..00000000000 --- a/test/unit.wat +++ /dev/null @@ -1,554 +0,0 @@ -(module - (type $FUNCSIG$vf (func (param f32))) - (type $FUNCSIG$v (func)) - (type $FUNCSIG$id (func (param f64) (result i32))) - (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) - (type $4 (func (result f64))) - (type $5 (func (result i32))) - (type $6 (func (param i32) (result i32))) - (type $7 (func (param f64) (result f64))) - (type $8 (func (result i64))) - (type $9 (func (param i32 i64))) - (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) - (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) - (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) - (table 10 funcref) - (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) - (memory $0 4096 4096) - (data (i32.const 1026) "\14\00") - (export "big_negative" (func $big_negative)) - (func $big_negative (type $FUNCSIG$v) - (local $temp f64) - (block $block0 - (local.set $temp - (f64.const -2147483648) - ) - (local.set $temp - (f64.const -2147483648) - ) - (local.set $temp - (f64.const -21474836480) - ) - (local.set $temp - (f64.const 0.039625) - ) - (local.set $temp - (f64.const -0.039625) - ) - ) - ) - (func $importedDoubles (type $4) (result f64) - (local $temp f64) - (block $topmost (result f64) - (local.set $temp - (f64.add - (f64.add - (f64.add - (f64.load - (i32.const 8) - ) - (f64.load - (i32.const 16) - ) - ) - (f64.neg - (f64.load - (i32.const 16) - ) - ) - ) - (f64.neg - (f64.load - (i32.const 8) - ) - ) - ) - ) - (if - (i32.gt_s - (i32.load - (i32.const 24) - ) - (i32.const 0) - ) - (br $topmost - (f64.const -3.4) - ) - ) - (if - (f64.gt - (f64.load - (i32.const 32) - ) - (f64.const 0) - ) - (br $topmost - (f64.const 5.6) - ) - ) - (f64.const 1.2) - ) - ) - (func $doubleCompares (type $FUNCSIG$ddd) (param $x f64) (param $y f64) (result f64) - (local $t f64) - (local $Int f64) - (local $Double i32) - (block $topmost (result f64) - (if - (f64.gt - (local.get $x) - (f64.const 0) - ) - (br $topmost - (f64.const 1.2) - ) - ) - (if - (f64.gt - (local.get $Int) - (f64.const 0) - ) - (br $topmost - (f64.const -3.4) - ) - ) - (if - (i32.gt_s - (local.get $Double) - (i32.const 0) - ) - (br $topmost - (f64.const 5.6) - ) - ) - (if - (f64.lt - (local.get $x) - (local.get $y) - ) - (br $topmost - (local.get $x) - ) - ) - (local.get $y) - ) - ) - (func $intOps (type $5) (result i32) - (local $x i32) - (i32.eq - (local.get $x) - (i32.const 0) - ) - ) - (func $hexLiterals (type $FUNCSIG$v) - (drop - (i32.add - (i32.add - (i32.const 0) - (i32.const 313249263) - ) - (i32.const -19088752) - ) - ) - ) - (func $conversions (type $FUNCSIG$v) - (local $i i32) - (local $d f64) - (block $block0 - (local.set $i - (call $f64-to-int - (local.get $d) - ) - ) - (local.set $d - (f64.convert_i32_s - (local.get $i) - ) - ) - (local.set $d - (f64.convert_i32_u - (i32.shr_u - (local.get $i) - (i32.const 0) - ) - ) - ) - ) - ) - (func $seq (type $FUNCSIG$v) - (local $J f64) - (local.set $J - (f64.sub - (block $block0 (result f64) - (drop - (f64.const 0.1) - ) - (f64.const 5.1) - ) - (block $block1 (result f64) - (drop - (f64.const 3.2) - ) - (f64.const 4.2) - ) - ) - ) - ) - (func $switcher (type $6) (param $x i32) (result i32) - (block $topmost (result i32) - (block $switch$0 - (block $switch-default$3 - (block $switch-case$2 - (block $switch-case$1 - (br_table $switch-case$1 $switch-case$2 $switch-default$3 - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - ) - (br $topmost - (i32.const 1) - ) - ) - (br $topmost - (i32.const 2) - ) - ) - (nop) - ) - (block $switch$4 - (block $switch-default$7 - (block $switch-case$6 - (block $switch-case$5 - (br_table $switch-case$6 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-default$7 $switch-case$5 $switch-default$7 - (i32.sub - (local.get $x) - (i32.const 5) - ) - ) - ) - (br $topmost - (i32.const 121) - ) - ) - (br $topmost - (i32.const 51) - ) - ) - (nop) - ) - (block $label$break$Lout - (block $switch-default$16 - (block $switch-case$15 - (block $switch-case$12 - (block $switch-case$9 - (block $switch-case$8 - (br_table $switch-case$15 $switch-default$16 $switch-default$16 $switch-case$12 $switch-default$16 $switch-default$16 $switch-default$16 $switch-default$16 $switch-case$9 $switch-default$16 $switch-case$8 $switch-default$16 - (i32.sub - (local.get $x) - (i32.const 2) - ) - ) - ) - (br $label$break$Lout) - ) - (br $label$break$Lout) - ) - (block $while-out$10 - (loop $while-in$11 - (block $block1 - (br $while-out$10) - (br $while-in$11) - ) - ) - (br $label$break$Lout) - ) - ) - (block $while-out$13 - (loop $while-in$14 - (block $block3 - (br $label$break$Lout) - (br $while-in$14) - ) - ) - (br $label$break$Lout) - ) - ) - (nop) - ) - (i32.const 0) - ) - ) - (func $blocker (type $FUNCSIG$v) - (block $label$break$L - (br $label$break$L) - ) - ) - (func $frem (type $4) (result f64) - (call $f64-rem - (f64.const 5.5) - (f64.const 1.2) - ) - ) - (func $big_uint_div_u (type $5) (result i32) - (local $x i32) - (block $topmost (result i32) - (local.set $x - (i32.and - (i32.div_u - (i32.const -1) - (i32.const 2) - ) - (i32.const -1) - ) - ) - (local.get $x) - ) - ) - (func $fr (type $FUNCSIG$vf) (param $x f32) - (local $y f32) - (local $z f64) - (block $block0 - (drop - (f32.demote_f64 - (local.get $z) - ) - ) - (drop - (local.get $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - ) - ) - (func $negZero (type $4) (result f64) - (f64.const -0) - ) - (func $abs (type $FUNCSIG$v) - (local $x i32) - (local $y f64) - (local $z f32) - (local $asm2wasm_i32_temp i32) - (block $block0 - (local.set $x - (block $block1 (result i32) - (local.set $asm2wasm_i32_temp - (i32.const 0) - ) - (select - (i32.sub - (i32.const 0) - (local.get $asm2wasm_i32_temp) - ) - (local.get $asm2wasm_i32_temp) - (i32.lt_s - (local.get $asm2wasm_i32_temp) - (i32.const 0) - ) - ) - ) - ) - (local.set $y - (f64.abs - (f64.const 0) - ) - ) - (local.set $z - (f32.abs - (f32.const 0) - ) - ) - ) - ) - (func $neg (type $FUNCSIG$v) - (local $x f32) - (block $block0 - (local.set $x - (f32.neg - (local.get $x) - ) - ) - (call_indirect (type $FUNCSIG$vf) - (local.get $x) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - ) - (func $cneg (type $FUNCSIG$vf) (param $x f32) - (call_indirect (type $FUNCSIG$vf) - (local.get $x) - (i32.add - (i32.and - (i32.const 1) - (i32.const 7) - ) - (i32.const 8) - ) - ) - ) - (func $___syscall_ret (type $FUNCSIG$v) - (local $$0 i32) - (drop - (i32.gt_u - (i32.shr_u - (local.get $$0) - (i32.const 0) - ) - (i32.const -4096) - ) - ) - ) - (func $z (type $FUNCSIG$v) - (nop) - ) - (func $w (type $FUNCSIG$v) - (nop) - ) - (func $block_and_after (type $5) (result i32) - (block $waka - (drop - (i32.const 1) - ) - (br $waka) - ) - (i32.const 0) - ) - (func $loop-roundtrip (type $7) (param $0 f64) (result f64) - (loop $loop-in1 (result f64) - (drop - (local.get $0) - ) - (local.get $0) - ) - ) - (func $big-i64 (type $8) (result i64) - (i64.const -9218868437227405313) - ) - (func $i64-store32 (type $9) (param $0 i32) (param $1 i64) - (i64.store32 - (local.get $0) - (local.get $1) - ) - ) - (func $return-unreachable (result i32) - (return (i32.const 1)) - ) - (func $unreachable-block (result i32) - (f64.abs - (block ;; note no type - valid in binaryen IR, in wasm must be i32 - (drop (i32.const 1)) - (return (i32.const 2)) - ) - ) - ) - (func $unreachable-block-toplevel (result i32) - (block ;; note no type - valid in binaryen IR, in wasm must be i32 - (drop (i32.const 1)) - (return (i32.const 2)) - ) - ) - (func $unreachable-block0 (result i32) - (f64.abs - (block ;; note no type - valid in binaryen IR, in wasm must be i32 - (return (i32.const 2)) - ) - ) - ) - (func $unreachable-block0-toplevel (result i32) - (block ;; note no type - valid in binaryen IR, in wasm must be i32 - (return (i32.const 2)) - ) - ) - (func $unreachable-block-with-br (result i32) - (block $block ;; unreachable type due to last element having that type, but the block is exitable - (drop (i32.const 1)) - (br $block) - ) - (i32.const 1) - ) - (func $unreachable-if (result i32) - (f64.abs - (if ;; note no type - valid in binaryen IR, in wasm must be i32 - (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) - ) - ) - ) - (func $unreachable-if-toplevel (result i32) - (if ;; note no type - valid in binaryen IR, in wasm must be i32 - (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) - ) - ) - (func $unreachable-loop (result i32) - (f64.abs - (loop ;; note no type - valid in binaryen IR, in wasm must be i32 - (nop) - (return (i32.const 1)) - ) - ) - ) - (func $unreachable-loop0 (result i32) - (f64.abs - (loop ;; note no type - valid in binaryen IR, in wasm must be i32 - (return (i32.const 1)) - ) - ) - ) - (func $unreachable-loop-toplevel (result i32) - (loop ;; note no type - valid in binaryen IR, in wasm must be i32 - (nop) - (return (i32.const 1)) - ) - ) - (func $unreachable-loop0-toplevel (result i32) - (loop ;; note no type - valid in binaryen IR, in wasm must be i32 - (return (i32.const 1)) - ) - ) - (func $unreachable-ifs - (if (unreachable) (nop)) - (if (unreachable) (unreachable)) - (if (unreachable) (nop) (nop)) - (if (unreachable) (unreachable) (nop)) - (if (unreachable) (nop) (unreachable)) - (if (unreachable) (unreachable) (unreachable)) - ;; - (if (i32.const 1) (unreachable) (nop)) - (if (i32.const 1) (nop) (unreachable)) - (if (i32.const 1) (unreachable) (unreachable)) - ) - (func $unreachable-if-arm - (if - (i32.const 1) - (block - (nop) - ) - (block - (unreachable) - (drop - (i32.const 1) - ) - ) - ) - ) -) diff --git a/test/unreachable-code.wast b/test/unreachable-code.wast deleted file mode 100644 index f67d10e52c9..00000000000 --- a/test/unreachable-code.wast +++ /dev/null @@ -1,85 +0,0 @@ -(module - (func $a - (if (i32.const 1) - (unreachable) - ) - ) - (func $b - (if (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-block - (block - (if (i32.const 1) - (unreachable) - ) - ) - ) - (func $b-block - (block - (if (i32.const 1) - (unreachable) - (unreachable) - ) - ) - ) - (func $a-prepost - (nop) - (if (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $b-prepost - (nop) - (if (i32.const 1) - (unreachable) - (unreachable) - ) - (nop) - ) - (func $a-block-prepost - (nop) - (block - (if (i32.const 1) - (unreachable) - ) - ) - (nop) - ) - (func $b-block-prepost - (nop) - (block - (if (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (nop) - ) - (func $recurse - (block $a - (nop) - (block $b - (nop) - (br $b) - (nop) - ) - (nop) - ) - ) - (func $recurse-b - (block $a - (nop) - (block $b - (nop) - (br $a) - (nop) - ) - (nop) - ) - ) -) - diff --git a/test/unreachable-code.wast.from-wast b/test/unreachable-code.wast.from-wast deleted file mode 100644 index ed789b1f8f4..00000000000 --- a/test/unreachable-code.wast.from-wast +++ /dev/null @@ -1,89 +0,0 @@ -(module - (type $0 (func)) - (func $a (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $b (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-block (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $b-block (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $b-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - (nop) - ) - (func $a-block-prepost (type $0) - (nop) - (block - (if - (i32.const 1) - (unreachable) - ) - ) - (nop) - ) - (func $b-block-prepost (type $0) - (nop) - (block - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (nop) - ) - (func $recurse (type $0) - (block $a - (nop) - (block $b - (nop) - (br $b) - (nop) - ) - (nop) - ) - ) - (func $recurse-b (type $0) - (block $a - (nop) - (block $b - (nop) - (br $a) - (nop) - ) - (nop) - ) - ) -) diff --git a/test/unreachable-code.wast.fromBinary b/test/unreachable-code.wast.fromBinary deleted file mode 100644 index dd0a1cec6b5..00000000000 --- a/test/unreachable-code.wast.fromBinary +++ /dev/null @@ -1,79 +0,0 @@ -(module - (type $0 (func)) - (func $a (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $b (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-block (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $b-block (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $b-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $a-block-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $b-block-prepost (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $recurse (type $0) - (nop) - (block $label$1 - (nop) - (br $label$1) - ) - (nop) - ) - (func $recurse-b (type $0) - (block $label$1 - (nop) - (block $label$2 - (nop) - (br $label$1) - ) - ) - ) -) - diff --git a/test/unreachable-code.wast.fromBinary.noDebugInfo b/test/unreachable-code.wast.fromBinary.noDebugInfo deleted file mode 100644 index 01aedc451f7..00000000000 --- a/test/unreachable-code.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,79 +0,0 @@ -(module - (type $0 (func)) - (func $0 (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $1 (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $2 (type $0) - (if - (i32.const 1) - (unreachable) - ) - ) - (func $3 (type $0) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $4 (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $5 (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $6 (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - ) - (nop) - ) - (func $7 (type $0) - (nop) - (if - (i32.const 1) - (unreachable) - (unreachable) - ) - ) - (func $8 (type $0) - (nop) - (block $label$1 - (nop) - (br $label$1) - ) - (nop) - ) - (func $9 (type $0) - (block $label$1 - (nop) - (block $label$2 - (nop) - (br $label$1) - ) - ) - ) -) - diff --git a/test/unreachable-instr-type.wast b/test/unreachable-instr-type.wast deleted file mode 100644 index b7c2078ab58..00000000000 --- a/test/unreachable-instr-type.wast +++ /dev/null @@ -1,28 +0,0 @@ -(module - (memory (shared 1 1)) - (func $test - (f32.load (unreachable)) - - (f32.store - (unreachable) - (f32.const 0) - ) - - (i64.atomic.rmw.add - (unreachable) - (i64.const 0) - ) - - (i64.atomic.rmw.cmpxchg - (unreachable) - (i64.const 0) - (i64.const 1) - ) - - (memory.atomic.wait64 - (unreachable) - (i64.const 0) - (i64.const 0) - ) - ) -) diff --git a/test/unreachable-instr-type.wast.from-wast b/test/unreachable-instr-type.wast.from-wast deleted file mode 100644 index 0c255902ee6..00000000000 --- a/test/unreachable-instr-type.wast.from-wast +++ /dev/null @@ -1,27 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 1 1)) - (func $test (type $0) - (i32.load - (unreachable) - ) - (f32.store - (unreachable) - (f32.const 0) - ) - (i32.atomic.rmw.add - (unreachable) - (i64.const 0) - ) - (i32.atomic.rmw.cmpxchg - (unreachable) - (i64.const 0) - (i64.const 1) - ) - (memory.atomic.wait64 - (unreachable) - (i64.const 0) - (i64.const 0) - ) - ) -) diff --git a/test/unreachable-instr-type.wast.fromBinary b/test/unreachable-instr-type.wast.fromBinary deleted file mode 100644 index 602ae379ca2..00000000000 --- a/test/unreachable-instr-type.wast.fromBinary +++ /dev/null @@ -1,8 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 1 1)) - (func $test (type $0) - (unreachable) - ) -) - diff --git a/test/unreachable-instr-type.wast.fromBinary.noDebugInfo b/test/unreachable-instr-type.wast.fromBinary.noDebugInfo deleted file mode 100644 index f74fdce2b44..00000000000 --- a/test/unreachable-instr-type.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,8 +0,0 @@ -(module - (type $0 (func)) - (memory $0 (shared 1 1)) - (func $0 (type $0) - (unreachable) - ) -) - diff --git a/test/untaken-br_if.wast b/test/untaken-br_if.wast deleted file mode 100644 index 92ed74c959a..00000000000 --- a/test/untaken-br_if.wast +++ /dev/null @@ -1,14 +0,0 @@ -(module - (func $binaryify-untaken-br_if (result f32) - (if (result f32) - (i32.const 1) - (unreachable) - (block $label$1 (result f32) - (br_if $label$1 - (f32.const 1) - (unreachable) - ) - ) - ) - ) -) diff --git a/test/untaken-br_if.wast.from-wast b/test/untaken-br_if.wast.from-wast deleted file mode 100644 index ba4d246d355..00000000000 --- a/test/untaken-br_if.wast.from-wast +++ /dev/null @@ -1,15 +0,0 @@ -(module - (type $0 (func (result f32))) - (func $binaryify-untaken-br_if (type $0) (result f32) - (if (result f32) - (i32.const 1) - (unreachable) - (block $label$1 (result f32) - (br_if $label$1 - (f32.const 1) - (unreachable) - ) - ) - ) - ) -) diff --git a/test/untaken-br_if.wast.fromBinary b/test/untaken-br_if.wast.fromBinary deleted file mode 100644 index 73c0d586fcc..00000000000 --- a/test/untaken-br_if.wast.fromBinary +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $0 (func (result f32))) - (func $binaryify-untaken-br_if (type $0) (result f32) - (if (result f32) - (i32.const 1) - (unreachable) - (block $label$3 (result f32) - (drop - (f32.const 1) - ) - (unreachable) - ) - ) - ) -) - diff --git a/test/untaken-br_if.wast.fromBinary.noDebugInfo b/test/untaken-br_if.wast.fromBinary.noDebugInfo deleted file mode 100644 index dd7d1197c7a..00000000000 --- a/test/untaken-br_if.wast.fromBinary.noDebugInfo +++ /dev/null @@ -1,16 +0,0 @@ -(module - (type $0 (func (result f32))) - (func $0 (type $0) (result f32) - (if (result f32) - (i32.const 1) - (unreachable) - (block $label$3 (result f32) - (drop - (f32.const 1) - ) - (unreachable) - ) - ) - ) -) - From 1da1363759012c844f061a29bea94a825ab39565 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 13 Dec 2023 11:55:14 -0800 Subject: [PATCH 003/553] [EH][test] Slice test code into different functions (#6177) We ported basic tests to `test/lit/basic/` in #6160, but comparing `CHECK` lines with the test code for long functions is not easy, even though it wouldn't necessarily be worse than the the separate files we used to have in `test/`. This slices `exception-handling.wast` into functions so that the `CHECK` lines are easy to check. --- test/lit/basic/exception-handling.wast | 1407 +++++++++++++----------- 1 file changed, 774 insertions(+), 633 deletions(-) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index ed85338e820..9191beeb2fd 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -69,8 +69,7 @@ ;; --------------------------------------------------------------------------- ;; Old Phase 3 exception handling - ;; CHECK-TEXT: (func $eh-test (type $0) - ;; CHECK-TEXT-NEXT: (local $x (i32 i64)) + ;; CHECK-TEXT: (func $simple-try-catch (type $0) ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 @@ -83,7 +82,35 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try0 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $simple-try-catch (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $simple-try-catch + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-catch-multivalue-tag (type $0) + ;; CHECK-TEXT-NEXT: (local $x (i32 i64)) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -101,20 +128,104 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (block $l11 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-catch-multivalue-tag (type $0) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 (i32 i64)) + ;; CHECK-BIN-NEXT: (local $3 i32) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32-i64 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32-i64 + ;; CHECK-BIN-NEXT: (local.set $2 + ;; CHECK-BIN-NEXT: (pop i32 i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $3 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-catch-multivalue-tag (local $x (i32 i64)) + (try + (do + (throw $e-i32-i64 (i32.const 0) (i64.const 0)) + ) + (catch $e-i32-i64 + (local.set $x (pop i32 i64)) + (drop + (tuple.extract 2 0 + (local.get $x) + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-with-block-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l10 ;; CHECK-TEXT-NEXT: (try $l1 ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br $l11) + ;; CHECK-TEXT-NEXT: (br $l10) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (catch $e-i32 ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (pop i32) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $l11) + ;; CHECK-TEXT-NEXT: (br $l10) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try2 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-with-block-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-with-block-label + (try $l1 + (do + (br $l1) + ) + (catch $e-i32 + (drop (pop i32)) + (br $l1) + ) + ) + ) + + ;; CHECK-TEXT: (func $empty-try-body (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) @@ -124,7 +235,30 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try3 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $empty-try-body (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $empty-try-body + (try + (do) + (catch $e-i32 + (drop (pop i32)) + ) + ) + ) + + ;; CHECK-TEXT: (func $multiple-insts-within-try-and-catch-bodies (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (call $foo) ;; CHECK-TEXT-NEXT: (call $bar) @@ -137,7 +271,38 @@ ;; CHECK-TEXT-NEXT: (call $bar) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try4 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $multiple-insts-within-try-and-catch-bodies (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $multiple-insts-within-try-and-catch-bodies + (try + (do + (call $foo) + (call $bar) + ) + (catch $e-i32 + (drop (pop i32)) + (call $foo) + (call $bar) + ) + ) + ) + + ;; CHECK-TEXT: (func $multiple-catches (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -154,7 +319,42 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try5 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $multiple-catches (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $multiple-catches + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + ) + ) + + ;; CHECK-TEXT: (func $catch-all (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -164,7 +364,30 @@ ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try6 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catch-all (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catch-all + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch_all) + ) + ) + + ;; CHECK-TEXT: (func $catch-and-catch-all-together (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -185,9 +408,52 @@ ;; CHECK-TEXT-NEXT: (call $bar) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try7 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catch-and-catch-all-together (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catch-and-catch-all-together + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + (catch_all + (call $foo) + (call $bar) + ) + ) + ) + + ;; CHECK-TEXT: (func $nested-try-catch (type $0) + ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try8 + ;; CHECK-TEXT-NEXT: (try $try1 ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -209,7 +475,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try9 + ;; CHECK-TEXT-NEXT: (try $try2 ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -226,149 +492,11 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try10 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $eh-test (type $0) - ;; CHECK-BIN-NEXT: (local $x i32) - ;; CHECK-BIN-NEXT: (local $1 i64) - ;; CHECK-BIN-NEXT: (local $2 (i32 i64)) - ;; CHECK-BIN-NEXT: (local $3 i32) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32-i64 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i64.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32-i64 - ;; CHECK-BIN-NEXT: (local.set $2 - ;; CHECK-BIN-NEXT: (pop i32 i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.set $x - ;; CHECK-BIN-NEXT: (block (result i32) - ;; CHECK-BIN-NEXT: (local.set $3 - ;; CHECK-BIN-NEXT: (tuple.extract 2 0 - ;; CHECK-BIN-NEXT: (local.get $2) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.set $1 - ;; CHECK-BIN-NEXT: (tuple.extract 2 1 - ;; CHECK-BIN-NEXT: (local.get $2) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.get $3) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (local.get $x) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (block $label$7 - ;; CHECK-BIN-NEXT: (try $label$10 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br $label$7) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$7) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$13 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$16 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$19 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i64 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$22 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$25 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i64 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$34 + ;; CHECK-BIN: (func $nested-try-catch (type $0) + ;; CHECK-BIN-NEXT: (try $label$9 ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (try $label$29 + ;; CHECK-BIN-NEXT: (try $label$4 ;; CHECK-BIN-NEXT: (do ;; CHECK-BIN-NEXT: (throw $e-i32 ;; CHECK-BIN-NEXT: (i32.const 0) @@ -390,7 +518,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$33 + ;; CHECK-BIN-NEXT: (try $label$8 ;; CHECK-BIN-NEXT: (do ;; CHECK-BIN-NEXT: (throw $e-i32 ;; CHECK-BIN-NEXT: (i32.const 0) @@ -407,111 +535,8 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$37 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $eh-test (local $x (i32 i64)) - ;; Simple try-catch - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - ) - - ;; try-catch with multivalue tag - (try - (do - (throw $e-i32-i64 (i32.const 0) (i64.const 0)) - ) - (catch $e-i32-i64 - (local.set $x (pop i32 i64)) - (drop - (tuple.extract 2 0 - (local.get $x) - ) - ) - ) - ) - - ;; Try with a block label - (try $l1 - (do - (br $l1) - ) - (catch $e-i32 - (drop (pop i32)) - (br $l1) - ) - ) - - ;; Empty try body - (try - (do) - (catch $e-i32 - (drop (pop i32)) - ) - ) - - ;; Multiple instructions within try and catch bodies - (try - (do - (call $foo) - (call $bar) - ) - (catch $e-i32 - (drop (pop i32)) - (call $foo) - (call $bar) - ) - ) - - ;; Multiple catch clauses - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - ) - - ;; Single catch-all clause - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch_all) - ) - - ;; catch and catch-all clauses together - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - (catch_all - (call $foo) - (call $bar) - ) - ) - - ;; nested try-catch + (func $nested-try-catch (try (do (try @@ -539,8 +564,27 @@ ) ) ) + ) - ;; try without catch or delegate + ;; CHECK-TEXT: (func $catchless-delegateless-try (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catchless-delegateless-try (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catchless-delegateless-try (try (do (throw $e-i32 (i32.const 0)) @@ -548,7 +592,7 @@ ) ) - ;; CHECK-TEXT: (func $delegate-test (type $0) + ;; CHECK-TEXT: (func $inner-delegate-target-outer-catch (type $0) ;; CHECK-TEXT-NEXT: (try $l0 ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (try $try @@ -557,7 +601,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (delegate $l0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try11 + ;; CHECK-TEXT-NEXT: (try $try3 ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (call $foo) ;; CHECK-TEXT-NEXT: ) @@ -568,52 +612,8 @@ ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (block $l015 - ;; CHECK-TEXT-NEXT: (try $l012 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try13 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br_if $l015 - ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l012) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try14 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br_if $l015 - ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l012) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l016 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try17 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l016) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try18 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-empty - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $delegate-test (type $0) + ;; CHECK-BIN: (func $inner-delegate-target-outer-catch (type $0) ;; CHECK-BIN-NEXT: (try $label$9 ;; CHECK-BIN-NEXT: (do ;; CHECK-BIN-NEXT: (block $label$1 @@ -635,25 +635,74 @@ ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (block $label$10 - ;; CHECK-BIN-NEXT: (try $label$19 + ;; CHECK-BIN-NEXT: ) + (func $inner-delegate-target-outer-catch + (try $l0 + (do + (try + (do + (call $foo) + ) + (delegate $l0) ;; by label + ) + (try + (do + (call $foo) + ) + (delegate 0) ;; by depth + ) + ) + (catch_all) + ) + ) + + ;; CHECK-TEXT: (func $branch-and-delegate-target-same-try-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l05 + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l05 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try4 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l05 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $branch-and-delegate-target-same-try-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$10 ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$11 - ;; CHECK-BIN-NEXT: (try $label$14 + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (try $label$5 ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br_if $label$10 + ;; CHECK-BIN-NEXT: (br_if $label$1 ;; CHECK-BIN-NEXT: (i32.const 1) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$19) + ;; CHECK-BIN-NEXT: (delegate $label$10) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$17 + ;; CHECK-BIN-NEXT: (try $label$8 ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br_if $label$10 + ;; CHECK-BIN-NEXT: (br_if $label$1 ;; CHECK-BIN-NEXT: (i32.const 1) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$19) + ;; CHECK-BIN-NEXT: (delegate $label$10) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) @@ -662,48 +711,8 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$25 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$20 - ;; CHECK-BIN-NEXT: (try $label$23 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$25) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$28 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-empty - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $delegate-test - ;; Inner delegates target an outer catch - (try $l0 - (do - (try - (do - (call $foo) - ) - (delegate $l0) ;; by label - ) - (try - (do - (call $foo) - ) - (delegate 0) ;; by depth - ) - ) - (catch_all) - ) - + (func $branch-and-delegate-target-same-try-label ;; When there are both a branch and a delegate that target the same try ;; label. Because binaryen only allows blocks and loops to be targetted by ;; branches, we wrap the try with a block and make branches that block @@ -726,7 +735,37 @@ ) (catch_all) ) + ) + ;; CHECK-TEXT: (func $inner-delegate-target-outer-delegate (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $inner-delegate-target-outer-delegate (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $inner-delegate-target-outer-delegate ;; The inner delegate targets the outer delegate, which in turn targets the ;; caller. (try $l0 @@ -740,7 +779,29 @@ ) (delegate 0) ) + ) + ;; CHECK-TEXT: (func $empty-catch-body (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-empty + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $empty-catch-body (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-empty + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $empty-catch-body ;; 'catch' body can be empty when the tag's type is none. (try (do) @@ -748,7 +809,7 @@ ) ) - ;; CHECK-TEXT: (func $rethrow-test (type $0) + ;; CHECK-TEXT: (func $try-catch-rethrow (type $0) ;; CHECK-TEXT-NEXT: (try $l0 ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (call $foo) @@ -763,100 +824,8 @@ ;; CHECK-TEXT-NEXT: (rethrow $l0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (block $l020 - ;; CHECK-TEXT-NEXT: (try $l019 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (rethrow $l019) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (br $l020) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l021 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (rethrow $l021) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (rethrow $l021) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l022 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try23 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (block $b0 - ;; CHECK-TEXT-NEXT: (rethrow $l022) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (block $b1 - ;; CHECK-TEXT-NEXT: (rethrow $l022) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l024 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try25 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (rethrow $l024) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l026 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try27 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (rethrow $l026) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $rethrow-test (type $0) + ;; CHECK-BIN: (func $try-catch-rethrow (type $0) ;; CHECK-BIN-NEXT: (try $label$3 ;; CHECK-BIN-NEXT: (do ;; CHECK-BIN-NEXT: (call $foo) @@ -871,98 +840,8 @@ ;; CHECK-BIN-NEXT: (rethrow $label$3) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (block $label$4 - ;; CHECK-BIN-NEXT: (try $label$7 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (rethrow $label$7) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (br $label$4) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$13 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$12 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (rethrow $label$13) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (rethrow $label$13) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$20 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$19 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (block $label$18 - ;; CHECK-BIN-NEXT: (rethrow $label$20) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (rethrow $label$20) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$26 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$25 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (rethrow $label$26) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$32 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$31 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (rethrow $label$32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $rethrow-test + (func $try-catch-rethrow ;; Simple try-catch-rethrow (try $l0 (do @@ -976,7 +855,45 @@ (rethrow 0) ;; by depth ) ) + ) + ;; CHECK-TEXT: (func $branch-and-rethrow-target-same-try-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l06 + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (br $l06) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $branch-and-rethrow-target-same-try-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $branch-and-rethrow-target-same-try-label ;; When there are both a branch and a rethrow that target the same try ;; label. Because binaryen only allows blocks and loops to be targetted by ;; branches, we wrap the try with a block and make branches that block @@ -994,7 +911,55 @@ (br $l0) ) ) + ) + ;; CHECK-TEXT: (func $nested-rethrow (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-rethrow (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $nested-rethrow ;; One more level deep (try $l0 (do @@ -1015,7 +980,61 @@ ) ) ) + ) + ;; CHECK-TEXT: (func $rnested-rethrow-with-interleaving-block (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $b0 + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (block $b1 + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $rnested-rethrow-with-interleaving-block (type $0) + ;; CHECK-BIN-NEXT: (try $label$7 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$5 + ;; CHECK-BIN-NEXT: (rethrow $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $rnested-rethrow-with-interleaving-block ;; Interleaving block (try $l0 (do @@ -1040,7 +1059,73 @@ ) ) ) + ) + ;; CHECK-TEXT: (func $rethrow-within-nested-try-part (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l07 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try8 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l07) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $rethrow-within-nested-try-part (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$12 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$11 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $rethrow-within-nested-try-part ;; Within nested try, but rather in 'try' part and not 'catch' (try $l0 (do @@ -1070,7 +1155,7 @@ ) ) - ;; CHECK-TEXT: (func $pop-test (type $0) + ;; CHECK-TEXT: (func $pop-within-if-condition (type $0) ;; CHECK-TEXT-NEXT: (try $try ;; CHECK-TEXT-NEXT: (do ;; CHECK-TEXT-NEXT: (nop) @@ -1085,18 +1170,8 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try28 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-eqref - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop anyref) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $pop-test (type $0) + ;; CHECK-BIN: (func $pop-within-if-condition (type $0) ;; CHECK-BIN-NEXT: (try $label$5 ;; CHECK-BIN-NEXT: (do ;; CHECK-BIN-NEXT: (nop) @@ -1111,18 +1186,8 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$8 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-eqref - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop eqref) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $pop-test + (func $pop-within-if-condition (try (do) (catch $e-i32 @@ -1136,7 +1201,33 @@ ) ) ) + ) + ;; CHECK-TEXT: (func $pop-can-be-supertype (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-eqref + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $pop-can-be-supertype (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-eqref + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $pop-can-be-supertype (try (do) (catch $e-eqref @@ -1192,10 +1283,7 @@ ) ) - ;; When 'delegate' is next to a nested block, make sure its delegate argument - ;; is parsed correctly. - - ;; CHECK-TEXT: (func $nested-block-and-try (type $0) + ;; CHECK-TEXT: (func $nested-delegate-within-block (type $0) ;; CHECK-TEXT-NEXT: (block $l0 ;; CHECK-TEXT-NEXT: (block $l1 ;; CHECK-TEXT-NEXT: ) @@ -1208,7 +1296,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $nested-block-and-try (type $0) + ;; CHECK-BIN: (func $nested-delegate-within-block (type $0) ;; CHECK-BIN-NEXT: (block $label$1 ;; CHECK-BIN-NEXT: (block $label$2 ;; CHECK-BIN-NEXT: ) @@ -1221,7 +1309,9 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) - (func $nested-block-and-try + (func $nested-delegate-within-block + ;; When 'delegate' is next to a nested block, make sure its delegate + ;; argument is parsed correctly. (block $l0 (block $l1) (try @@ -1235,7 +1325,7 @@ ;; --------------------------------------------------------------------------- ;; New exception handling - ;; CHECK-TEXT: (func $exnref-test (type $5) (result exnref) + ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $5) (result exnref) ;; CHECK-TEXT-NEXT: (local $exn exnref) ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) ;; CHECK-TEXT-NEXT: (if (result exnref) @@ -1248,7 +1338,7 @@ ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $exnref-test (type $5) (result exnref) + ;; CHECK-BIN: (func $exnref-nullexnref-test (type $5) (result exnref) ;; CHECK-BIN-NEXT: (local $exn exnref) ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) ;; CHECK-BIN-NEXT: (if (result exnref) @@ -1261,7 +1351,7 @@ ;; CHECK-BIN-NEXT: (local.get $exn) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $exnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref) + (func $exnref-nullexnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref) (if (result exnref) (i32.const 1) (if (result nullexnref) @@ -1304,10 +1394,6 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $2 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) -;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) -;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64)) -;; CHECK-BIN-NODEBUG-NEXT: (local $3 i32) ;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 @@ -1320,7 +1406,14 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64)) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 i32) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1351,20 +1444,26 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$7 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$10 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br $label$7) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (pop i32) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$7) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$13 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1374,7 +1473,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$16 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: (call $1) @@ -1387,7 +1489,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (call $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1404,7 +1509,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$22 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1414,7 +1522,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1435,9 +1546,12 @@ ;; CHECK-BIN-NODEBUG-NEXT: (call $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$34 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (try $label$29 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1459,7 +1573,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$33 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1476,7 +1590,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$37 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -1485,7 +1602,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG: (func $12 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 @@ -1507,25 +1624,28 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$10 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$10 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$11 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$14 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$19) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$17 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$19) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1534,20 +1654,26 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$20 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$23 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$25) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (delegate 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$28 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1557,7 +1683,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG: (func $16 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) @@ -1572,8 +1698,11 @@ ;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1581,19 +1710,22 @@ ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (pop i32) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$4) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (br $label$4) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$13 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$12 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1601,20 +1733,23 @@ ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (pop i32) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$13) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$13) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$20 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$19 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1622,24 +1757,27 @@ ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (pop i32) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$18 -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$20) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$20) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$26 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$25 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$26) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all ;; CHECK-BIN-NODEBUG-NEXT: (nop) @@ -1647,14 +1785,14 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$32 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$12 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (call $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$31 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$11 ;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$32) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$12) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (catch_all ;; CHECK-BIN-NODEBUG-NEXT: (nop) @@ -1664,7 +1802,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG: (func $21 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (nop) @@ -1679,7 +1817,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1691,7 +1832,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG: (func $23 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 ;; CHECK-BIN-NODEBUG-NEXT: (do ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 @@ -1708,7 +1849,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $7 (type $0) +;; CHECK-BIN-NODEBUG: (func $24 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -1722,7 +1863,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $8 (type $5) (result exnref) +;; CHECK-BIN-NODEBUG: (func $25 (type $5) (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) ;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) From 61c3666ebd85eaadb11d06ce8048f4bea026af3d Mon Sep 17 00:00:00 2001 From: Goktug Gokdogan Date: Wed, 13 Dec 2023 13:48:19 -0800 Subject: [PATCH 004/553] J2CL: Use a more future proof naming convention for once functions (#6173) Existing convention uses _@once@_ but we also use @ for class separation. It is cleaner&more future proof to use something other convention like __. --- src/passes/J2CLOpts.cpp | 2 +- test/lit/passes/j2cl-inline.wast | 22 ++++++++++++---------- test/lit/passes/j2cl.wast | 24 ++++++++++++------------ 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/passes/J2CLOpts.cpp b/src/passes/J2CLOpts.cpp index f6821b80f23..78edecc4510 100644 --- a/src/passes/J2CLOpts.cpp +++ b/src/passes/J2CLOpts.cpp @@ -30,7 +30,7 @@ namespace wasm { namespace { -bool isOnceFunction(Function* f) { return f->name.hasSubstring("_@once@_"); } +bool isOnceFunction(Function* f) { return f->name.hasSubstring("__"); } using AssignmentCountMap = std::unordered_map; diff --git a/test/lit/passes/j2cl-inline.wast b/test/lit/passes/j2cl-inline.wast index dad35b80e7e..263be0726fc 100644 --- a/test/lit/passes/j2cl-inline.wast +++ b/test/lit/passes/j2cl-inline.wast @@ -1,16 +1,18 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --no-inline=*_@once@_* --optimize-j2cl --inlining --vacuum --optimize-level=3 -all -S -o - | filecheck %s +;; NOTE: In real world example no-inline would use __ but there is escaping problem in a multi-platform +;; way in lit so we are working around it by using no-inline with a different pattern that matches same method. +;; RUN: foreach %s %t wasm-opt --no-inline=*clinit* --optimize-j2cl --inlining --vacuum --optimize-level=3 -all -S -o - | filecheck %s ;; Only trivial once functions are inlined (module ;; A once function that has become empty - (func $clinit-trivial-1_@once@_@Foo ) + (func $clinit-trivial-1__@Foo ) ;; A once function that just calls another - (func $clinit-trivial-2_@once@_@Bar - (call $clinit-trivial-1_@once@_@Foo) + (func $clinit-trivial-2__@Bar + (call $clinit-trivial-1__@Foo) ) ;; CHECK: (type $0 (func)) @@ -19,7 +21,7 @@ (global $$class-initialized@Zoo (mut i32) (i32.const 0)) ;; Not hoisted but trivial. - ;; CHECK: (func $clinit-non-trivial_@once@_@Zoo (type $0) + ;; CHECK: (func $clinit-non-trivial__@Zoo (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $$class-initialized@Zoo) ;; CHECK-NEXT: (return) @@ -28,7 +30,7 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $clinit-non-trivial_@once@_@Zoo + (func $clinit-non-trivial__@Zoo (if (global.get $$class-initialized@Zoo) (return) ) @@ -36,11 +38,11 @@ ) ;; CHECK: (func $main (type $0) - ;; CHECK-NEXT: (call $clinit-non-trivial_@once@_@Zoo) + ;; CHECK-NEXT: (call $clinit-non-trivial__@Zoo) ;; CHECK-NEXT: ) (func $main - (call $clinit-trivial-1_@once@_@Foo) - (call $clinit-trivial-2_@once@_@Bar) - (call $clinit-non-trivial_@once@_@Zoo) + (call $clinit-trivial-1__@Foo) + (call $clinit-trivial-2__@Bar) + (call $clinit-non-trivial__@Zoo) ) ) diff --git a/test/lit/passes/j2cl.wast b/test/lit/passes/j2cl.wast index 0d37dd829ce..2294b7d3d7d 100644 --- a/test/lit/passes/j2cl.wast +++ b/test/lit/passes/j2cl.wast @@ -12,10 +12,10 @@ (global $field-i32@Foo (mut i32) (i32.const 0)) (global $field-f64@Foo (mut f64) (f64.const 0)) - ;; CHECK: (func $clinit_@once@_@Foo (type $0) + ;; CHECK: (func $clinit__@Foo (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Foo + (func $clinit__@Foo (global.set $field-i32@Foo (i32.const 1)) (global.set $field-f64@Foo (f64.const 1)) ) @@ -48,14 +48,14 @@ ;; CHECK: (global $field3@Foo anyref (global.get $field1@Foo)) (global $field3@Foo (mut anyref) (ref.null none)) - ;; CHECK: (func $clinit_@once@_@Foo (type $1) + ;; CHECK: (func $clinit__@Foo (type $1) ;; CHECK-NEXT: (global.set $field2@Foo ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (global.get $referredFieldMut@Foo) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Foo + (func $clinit__@Foo ;; Referred field is immutable, should hoist (global.set $field1@Foo (struct.new $A ( global.get $referredField@Foo) @@ -85,7 +85,7 @@ (global $field-any@Foo (mut anyref) (struct.new $A)) - ;; CHECK: (func $clinit_@once@_@Foo (type $1) + ;; CHECK: (func $clinit__@Foo (type $1) ;; CHECK-NEXT: (global.set $field-i32@Foo ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -93,7 +93,7 @@ ;; CHECK-NEXT: (struct.new_default $A) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Foo + (func $clinit__@Foo (global.set $field-i32@Foo (i32.const 1)) (global.set $field-any@Foo (struct.new $A)) ) @@ -107,10 +107,10 @@ ;; CHECK: (global $field@Foo i32 (i32.const 1)) (global $field@Foo (mut i32) (i32.const 0)) - ;; CHECK: (func $clinit_@once@_@Foo (type $0) + ;; CHECK: (func $clinit__@Foo (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Foo + (func $clinit__@Foo (global.set $field@Foo (i32.const 1)) ) ) @@ -123,12 +123,12 @@ ;; CHECK: (global $$class-initialized@Foo (mut i32) (i32.const 0)) (global $$class-initialized@Foo (mut i32) (i32.const 0)) - ;; CHECK: (func $clinit_@once@_@Foo (type $0) + ;; CHECK: (func $clinit__@Foo (type $0) ;; CHECK-NEXT: (global.set $$class-initialized@Foo ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Foo + (func $clinit__@Foo (global.set $$class-initialized@Foo (i32.const 1)) ) ) @@ -141,12 +141,12 @@ ;; CHECK: (global $field@Foo (mut i32) (i32.const 0)) (global $field@Foo (mut i32) (i32.const 0)) - ;; CHECK: (func $clinit_@once@_@Bar (type $0) + ;; CHECK: (func $clinit__@Bar (type $0) ;; CHECK-NEXT: (global.set $field@Foo ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $clinit_@once@_@Bar + (func $clinit__@Bar ;; Note that $clinit is @Bar and field is @Foo. (global.set $field@Foo (i32.const 1)) ) From 94f9b9a0c4e57bae64bc787362712874c6d5a00d Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 13 Dec 2023 13:53:31 -0800 Subject: [PATCH 005/553] [EH][test] Split EH tests into old and new spec (#6178) This moves tests for the old EH spec to `exception-handling-old.wast` and moves the new `exnref` test into `exception-handling.wast`, onto which I plan to add more tests for the new EH spec. The primary reason for splitting the files is I plan to exclude the new EH test from the fuzzing while the new spec's implementation is in progress, and I don't want to exclude the old EH tests altogether. --- scripts/fuzz_opt.py | 2 + test/lit/basic/exception-handling-old.wast | 1817 ++++++++++++++++ test/lit/basic/exception-handling.wast | 1823 +---------------- ...dling.wast => exception-handling-old.wast} | 0 4 files changed, 1826 insertions(+), 1816 deletions(-) create mode 100644 test/lit/basic/exception-handling-old.wast rename test/spec/{exception-handling.wast => exception-handling-old.wast} (100%) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 812b290f7b3..28cf4eb70d6 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -315,6 +315,8 @@ def is_git_repo(): 'multi-memory-lowering-import-error.wast', # the fuzzer does not support typed continuations 'typed_continuations.wast', + # New EH implementation is in progress + 'exception-handling.wast', ] diff --git a/test/lit/basic/exception-handling-old.wast b/test/lit/basic/exception-handling-old.wast new file mode 100644 index 00000000000..c082c1977da --- /dev/null +++ b/test/lit/basic/exception-handling-old.wast @@ -0,0 +1,1817 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + ;; CHECK-TEXT: (type $0 (func)) + + ;; CHECK-TEXT: (type $1 (func (param i32))) + + ;; CHECK-TEXT: (type $2 (func (param i64))) + + ;; CHECK-TEXT: (type $3 (func (param i32 i64))) + + ;; CHECK-TEXT: (type $4 (func (param eqref))) + + ;; CHECK-TEXT: (tag $e-i32 (param i32)) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (type $1 (func (param i32))) + + ;; CHECK-BIN: (type $2 (func (param i64))) + + ;; CHECK-BIN: (type $3 (func (param i32 i64))) + + ;; CHECK-BIN: (type $4 (func (param eqref))) + + ;; CHECK-BIN: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + ;; CHECK-TEXT: (tag $e-i64 (param i64)) + ;; CHECK-BIN: (tag $e-i64 (param i64)) + (tag $e-i64 (param i64)) + ;; CHECK-TEXT: (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-BIN: (tag $e-i32-i64 (param i32 i64)) + (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-TEXT: (tag $e-eqref (param eqref)) + ;; CHECK-BIN: (tag $e-eqref (param eqref)) + (tag $e-eqref (param (ref null eq))) + ;; CHECK-TEXT: (tag $e-empty) + ;; CHECK-BIN: (tag $e-empty) + (tag $e-empty) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo) + + ;; CHECK-TEXT: (func $bar (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $bar (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $bar) + + ;; --------------------------------------------------------------------------- + ;; Old Phase 3 exception handling + + ;; CHECK-TEXT: (func $simple-try-catch (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $simple-try-catch (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $simple-try-catch + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-catch-multivalue-tag (type $0) + ;; CHECK-TEXT-NEXT: (local $x (i32 i64)) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32-i64 + ;; CHECK-TEXT-NEXT: (local.set $x + ;; CHECK-TEXT-NEXT: (pop i32 i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (tuple.extract 2 0 + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-catch-multivalue-tag (type $0) + ;; CHECK-BIN-NEXT: (local $x i32) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 (i32 i64)) + ;; CHECK-BIN-NEXT: (local $3 i32) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32-i64 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32-i64 + ;; CHECK-BIN-NEXT: (local.set $2 + ;; CHECK-BIN-NEXT: (pop i32 i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $x + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $3 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-catch-multivalue-tag (local $x (i32 i64)) + (try + (do + (throw $e-i32-i64 (i32.const 0) (i64.const 0)) + ) + (catch $e-i32-i64 + (local.set $x (pop i32 i64)) + (drop + (tuple.extract 2 0 + (local.get $x) + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-with-block-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l10 + ;; CHECK-TEXT-NEXT: (try $l1 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br $l10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $l10) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-with-block-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-with-block-label + (try $l1 + (do + (br $l1) + ) + (catch $e-i32 + (drop (pop i32)) + (br $l1) + ) + ) + ) + + ;; CHECK-TEXT: (func $empty-try-body (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $empty-try-body (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $empty-try-body + (try + (do) + (catch $e-i32 + (drop (pop i32)) + ) + ) + ) + + ;; CHECK-TEXT: (func $multiple-insts-within-try-and-catch-bodies (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $multiple-insts-within-try-and-catch-bodies (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $multiple-insts-within-try-and-catch-bodies + (try + (do + (call $foo) + (call $bar) + ) + (catch $e-i32 + (drop (pop i32)) + (call $foo) + (call $bar) + ) + ) + ) + + ;; CHECK-TEXT: (func $multiple-catches (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i64 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $multiple-catches (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $multiple-catches + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + ) + ) + + ;; CHECK-TEXT: (func $catch-all (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catch-all (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catch-all + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch_all) + ) + ) + + ;; CHECK-TEXT: (func $catch-and-catch-all-together (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i64 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i64) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $bar) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catch-and-catch-all-together (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i64 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i64) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $bar) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catch-and-catch-all-together + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch $e-i64 + (drop (pop i64)) + ) + (catch_all + (call $foo) + (call $bar) + ) + ) + ) + + ;; CHECK-TEXT: (func $nested-try-catch (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try1 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try2 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-try-catch (type $0) + ;; CHECK-BIN-NEXT: (try $label$9 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$8 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $nested-try-catch + (try + (do + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all) + ) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all + (try + (do + (throw $e-i32 (i32.const 0)) + ) + (catch $e-i32 + (drop (pop i32)) + ) + (catch_all) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $catchless-delegateless-try (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catchless-delegateless-try (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catchless-delegateless-try + (try + (do + (throw $e-i32 (i32.const 0)) + ) + ) + ) + + ;; CHECK-TEXT: (func $inner-delegate-target-outer-catch (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try3 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $inner-delegate-target-outer-catch (type $0) + ;; CHECK-BIN-NEXT: (try $label$9 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$9) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$7 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$9) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $inner-delegate-target-outer-catch + (try $l0 + (do + (try + (do + (call $foo) + ) + (delegate $l0) ;; by label + ) + (try + (do + (call $foo) + ) + (delegate 0) ;; by depth + ) + ) + (catch_all) + ) + ) + + ;; CHECK-TEXT: (func $branch-and-delegate-target-same-try-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l05 + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l05 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try4 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (br_if $l05 + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $branch-and-delegate-target-same-try-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$10 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br_if $label$1 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$8 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (br_if $label$1 + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$10) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $branch-and-delegate-target-same-try-label + ;; When there are both a branch and a delegate that target the same try + ;; label. Because binaryen only allows blocks and loops to be targetted by + ;; branches, we wrap the try with a block and make branches that block + ;; instead, resulting in the br and delegate target different labels in the + ;; output. + (try $l0 + (do + (try + (do + (br_if $l0 (i32.const 1)) + ) + (delegate $l0) ;; by label + ) + (try + (do + (br_if $l0 (i32.const 1)) + ) + (delegate 0) ;; by depth + ) + ) + (catch_all) + ) + ) + + ;; CHECK-TEXT: (func $inner-delegate-target-outer-delegate (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $inner-delegate-target-outer-delegate (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $inner-delegate-target-outer-delegate + ;; The inner delegate targets the outer delegate, which in turn targets the + ;; caller. + (try $l0 + (do + (try + (do + (call $foo) + ) + (delegate $l0) + ) + ) + (delegate 0) + ) + ) + + ;; CHECK-TEXT: (func $empty-catch-body (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-empty + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $empty-catch-body (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-empty + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $empty-catch-body + ;; 'catch' body can be empty when the tag's type is none. + (try + (do) + (catch $e-empty) + ) + ) + + ;; CHECK-TEXT: (func $try-catch-rethrow (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-catch-rethrow (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-catch-rethrow + ;; Simple try-catch-rethrow + (try $l0 + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) ;; by label + ) + (catch_all + (rethrow 0) ;; by depth + ) + ) + ) + + ;; CHECK-TEXT: (func $branch-and-rethrow-target-same-try-label (type $0) + ;; CHECK-TEXT-NEXT: (block $l06 + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (br $l06) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $branch-and-rethrow-target-same-try-label (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $branch-and-rethrow-target-same-try-label + ;; When there are both a branch and a rethrow that target the same try + ;; label. Because binaryen only allows blocks and loops to be targetted by + ;; branches, we wrap the try with a block and make branches that block + ;; instead, resulting in the br and rethrow target different labels in the + ;; output. + (try $l0 + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) + ) + (catch_all + (br $l0) + ) + ) + ) + + ;; CHECK-TEXT: (func $nested-rethrow (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-rethrow (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $nested-rethrow + ;; One more level deep + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (rethrow $l0) ;; by label + ) + (catch_all + (rethrow 1) ;; by depth + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $rnested-rethrow-with-interleaving-block (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (block $b0 + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (block $b1 + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $rnested-rethrow-with-interleaving-block (type $0) + ;; CHECK-BIN-NEXT: (try $label$7 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (block $label$5 + ;; CHECK-BIN-NEXT: (rethrow $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (rethrow $label$7) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $rnested-rethrow-with-interleaving-block + ;; Interleaving block + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (call $foo) + ) + (catch $e-i32 + (drop (pop i32)) + (block $b0 + (rethrow $l0) ;; by label + ) + ) + (catch_all + (block $b1 + (rethrow 2) ;; by depth + ) + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $rethrow-within-nested-try-part (type $0) + ;; CHECK-TEXT-NEXT: (try $l0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $l07 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (try $try8 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (rethrow $l07) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch_all + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $rethrow-within-nested-try-part (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$12 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (try $label$11 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (rethrow $label$12) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch_all + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $rethrow-within-nested-try-part + ;; Within nested try, but rather in 'try' part and not 'catch' + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (rethrow $l0) ;; by label + ) + (catch_all) + ) + ) + ) + (try $l0 + (do + (call $foo) + ) + (catch_all + (try + (do + (rethrow 1) ;; by depth + ) + (catch_all) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $pop-within-if-condition (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-i32 + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (if (result i32) + ;; CHECK-TEXT-NEXT: (pop i32) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $pop-within-if-condition (type $0) + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-i32 + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (if (result i32) + ;; CHECK-BIN-NEXT: (pop i32) + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $pop-within-if-condition + (try + (do) + (catch $e-i32 + (throw $e-i32 + (if (result i32) + ;; pop is within an if condition, so this is OK. + (pop i32) + (i32.const 0) + (i32.const 3) + ) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $pop-can-be-supertype (type $0) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (catch $e-eqref + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (pop anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $pop-can-be-supertype (type $0) + ;; CHECK-BIN-NEXT: (try $label$3 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (catch $e-eqref + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (pop eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $pop-can-be-supertype + (try + (do) + (catch $e-eqref + (drop + (pop anyref) ;; pop can be supertype + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $catchless-try-with-inner-delegate (type $0) + ;; CHECK-TEXT-NEXT: (try $label$0 + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate $label$0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catchless-try-with-inner-delegate (type $0) + ;; CHECK-BIN-NEXT: (try $label$6 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (try $label$4 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate $label$6) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catchless-try-with-inner-delegate + (try $label$0 + (do + (try + (do + (throw $e-i32 + (i32.const 0) + ) + ) + (delegate $label$0) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $nested-delegate-within-block (type $0) + ;; CHECK-TEXT-NEXT: (block $l0 + ;; CHECK-TEXT-NEXT: (block $l1 + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try $try + ;; CHECK-TEXT-NEXT: (do + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (delegate 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-delegate-within-block (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try $label$5 + ;; CHECK-BIN-NEXT: (do + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (delegate 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $nested-delegate-within-block + ;; When 'delegate' is next to a nested block, make sure its delegate + ;; argument is parsed correctly. + (block $l0 + (block $l1) + (try + (do) + (delegate 1) ;; to caller + ) + ) + (nop) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) + +;; CHECK-BIN-NODEBUG: (type $2 (func (param i64))) + +;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 i64))) + +;; CHECK-BIN-NODEBUG: (type $4 (func (param eqref))) + +;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + +;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i64)) + +;; CHECK-BIN-NODEBUG: (tag $tag$2 (param i32 i64)) + +;; CHECK-BIN-NODEBUG: (tag $tag$3 (param eqref)) + +;; CHECK-BIN-NODEBUG: (tag $tag$4) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64)) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 i32) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$2 +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (pop i32 i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i64) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$10 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$4 +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$12 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (try $label$11 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$12) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch_all +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (if (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (pop i32) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$3 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (pop eqref) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $24 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 +;; CHECK-BIN-NODEBUG-NEXT: (do +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (delegate 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index 9191beeb2fd..945cca1af83 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -10,1322 +10,9 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module - ;; CHECK-TEXT: (type $0 (func)) + ;; CHECK-TEXT: (type $0 (func (result exnref))) - ;; CHECK-TEXT: (type $1 (func (param i32))) - - ;; CHECK-TEXT: (type $2 (func (param i64))) - - ;; CHECK-TEXT: (type $3 (func (param i32 i64))) - - ;; CHECK-TEXT: (type $4 (func (param eqref))) - - ;; CHECK-TEXT: (type $5 (func (result exnref))) - - ;; CHECK-TEXT: (tag $e-i32 (param i32)) - ;; CHECK-BIN: (type $0 (func)) - - ;; CHECK-BIN: (type $1 (func (param i32))) - - ;; CHECK-BIN: (type $2 (func (param i64))) - - ;; CHECK-BIN: (type $3 (func (param i32 i64))) - - ;; CHECK-BIN: (type $4 (func (param eqref))) - - ;; CHECK-BIN: (type $5 (func (result exnref))) - - ;; CHECK-BIN: (tag $e-i32 (param i32)) - (tag $e-i32 (param i32)) - ;; CHECK-TEXT: (tag $e-i64 (param i64)) - ;; CHECK-BIN: (tag $e-i64 (param i64)) - (tag $e-i64 (param i64)) - ;; CHECK-TEXT: (tag $e-i32-i64 (param i32 i64)) - ;; CHECK-BIN: (tag $e-i32-i64 (param i32 i64)) - (tag $e-i32-i64 (param i32 i64)) - ;; CHECK-TEXT: (tag $e-eqref (param eqref)) - ;; CHECK-BIN: (tag $e-eqref (param eqref)) - (tag $e-eqref (param (ref null eq))) - ;; CHECK-TEXT: (tag $e-empty) - ;; CHECK-BIN: (tag $e-empty) - (tag $e-empty) - - ;; CHECK-TEXT: (func $foo (type $0) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $foo (type $0) - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - (func $foo) - - ;; CHECK-TEXT: (func $bar (type $0) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $bar (type $0) - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - (func $bar) - - ;; --------------------------------------------------------------------------- - ;; Old Phase 3 exception handling - - ;; CHECK-TEXT: (func $simple-try-catch (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $simple-try-catch (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $simple-try-catch - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - ) - ) - - ;; CHECK-TEXT: (func $try-catch-multivalue-tag (type $0) - ;; CHECK-TEXT-NEXT: (local $x (i32 i64)) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i64.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32-i64 - ;; CHECK-TEXT-NEXT: (local.set $x - ;; CHECK-TEXT-NEXT: (pop i32 i64) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (tuple.extract 2 0 - ;; CHECK-TEXT-NEXT: (local.get $x) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $try-catch-multivalue-tag (type $0) - ;; CHECK-BIN-NEXT: (local $x i32) - ;; CHECK-BIN-NEXT: (local $1 i64) - ;; CHECK-BIN-NEXT: (local $2 (i32 i64)) - ;; CHECK-BIN-NEXT: (local $3 i32) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32-i64 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i64.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32-i64 - ;; CHECK-BIN-NEXT: (local.set $2 - ;; CHECK-BIN-NEXT: (pop i32 i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.set $x - ;; CHECK-BIN-NEXT: (block (result i32) - ;; CHECK-BIN-NEXT: (local.set $3 - ;; CHECK-BIN-NEXT: (tuple.extract 2 0 - ;; CHECK-BIN-NEXT: (local.get $2) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.set $1 - ;; CHECK-BIN-NEXT: (tuple.extract 2 1 - ;; CHECK-BIN-NEXT: (local.get $2) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.get $3) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (local.get $x) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $try-catch-multivalue-tag (local $x (i32 i64)) - (try - (do - (throw $e-i32-i64 (i32.const 0) (i64.const 0)) - ) - (catch $e-i32-i64 - (local.set $x (pop i32 i64)) - (drop - (tuple.extract 2 0 - (local.get $x) - ) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $try-with-block-label (type $0) - ;; CHECK-TEXT-NEXT: (block $l10 - ;; CHECK-TEXT-NEXT: (try $l1 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br $l10) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $l10) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $try-with-block-label (type $0) - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br $label$1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $try-with-block-label - (try $l1 - (do - (br $l1) - ) - (catch $e-i32 - (drop (pop i32)) - (br $l1) - ) - ) - ) - - ;; CHECK-TEXT: (func $empty-try-body (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $empty-try-body (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $empty-try-body - (try - (do) - (catch $e-i32 - (drop (pop i32)) - ) - ) - ) - - ;; CHECK-TEXT: (func $multiple-insts-within-try-and-catch-bodies (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: (call $bar) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: (call $bar) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $multiple-insts-within-try-and-catch-bodies (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $multiple-insts-within-try-and-catch-bodies - (try - (do - (call $foo) - (call $bar) - ) - (catch $e-i32 - (drop (pop i32)) - (call $foo) - (call $bar) - ) - ) - ) - - ;; CHECK-TEXT: (func $multiple-catches (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i64 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i64) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $multiple-catches (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i64 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $multiple-catches - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - ) - ) - - ;; CHECK-TEXT: (func $catch-all (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $catch-all (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $catch-all - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch_all) - ) - ) - - ;; CHECK-TEXT: (func $catch-and-catch-all-together (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i64 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i64) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: (call $bar) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $catch-and-catch-all-together (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i64 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i64) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: (call $bar) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $catch-and-catch-all-together - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch $e-i64 - (drop (pop i64)) - ) - (catch_all - (call $foo) - (call $bar) - ) - ) - ) - - ;; CHECK-TEXT: (func $nested-try-catch (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try1 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try2 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $nested-try-catch (type $0) - ;; CHECK-BIN-NEXT: (try $label$9 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$8 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $nested-try-catch - (try - (do - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all) - ) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all - (try - (do - (throw $e-i32 (i32.const 0)) - ) - (catch $e-i32 - (drop (pop i32)) - ) - (catch_all) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $catchless-delegateless-try (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $catchless-delegateless-try (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $catchless-delegateless-try - (try - (do - (throw $e-i32 (i32.const 0)) - ) - ) - ) - - ;; CHECK-TEXT: (func $inner-delegate-target-outer-catch (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try3 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $inner-delegate-target-outer-catch (type $0) - ;; CHECK-BIN-NEXT: (try $label$9 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$9) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$7 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$9) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $inner-delegate-target-outer-catch - (try $l0 - (do - (try - (do - (call $foo) - ) - (delegate $l0) ;; by label - ) - (try - (do - (call $foo) - ) - (delegate 0) ;; by depth - ) - ) - (catch_all) - ) - ) - - ;; CHECK-TEXT: (func $branch-and-delegate-target-same-try-label (type $0) - ;; CHECK-TEXT-NEXT: (block $l05 - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br_if $l05 - ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try4 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (br_if $l05 - ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $branch-and-delegate-target-same-try-label (type $0) - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$10 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$2 - ;; CHECK-BIN-NEXT: (try $label$5 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br_if $label$1 - ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$10) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$8 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (br_if $label$1 - ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$10) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $branch-and-delegate-target-same-try-label - ;; When there are both a branch and a delegate that target the same try - ;; label. Because binaryen only allows blocks and loops to be targetted by - ;; branches, we wrap the try with a block and make branches that block - ;; instead, resulting in the br and delegate target different labels in the - ;; output. - (try $l0 - (do - (try - (do - (br_if $l0 (i32.const 1)) - ) - (delegate $l0) ;; by label - ) - (try - (do - (br_if $l0 (i32.const 1)) - ) - (delegate 0) ;; by depth - ) - ) - (catch_all) - ) - ) - - ;; CHECK-TEXT: (func $inner-delegate-target-outer-delegate (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $inner-delegate-target-outer-delegate (type $0) - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$6) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $inner-delegate-target-outer-delegate - ;; The inner delegate targets the outer delegate, which in turn targets the - ;; caller. - (try $l0 - (do - (try - (do - (call $foo) - ) - (delegate $l0) - ) - ) - (delegate 0) - ) - ) - - ;; CHECK-TEXT: (func $empty-catch-body (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-empty - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $empty-catch-body (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-empty - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $empty-catch-body - ;; 'catch' body can be empty when the tag's type is none. - (try - (do) - (catch $e-empty) - ) - ) - - ;; CHECK-TEXT: (func $try-catch-rethrow (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $try-catch-rethrow (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (rethrow $label$3) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (rethrow $label$3) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $try-catch-rethrow - ;; Simple try-catch-rethrow - (try $l0 - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) ;; by label - ) - (catch_all - (rethrow 0) ;; by depth - ) - ) - ) - - ;; CHECK-TEXT: (func $branch-and-rethrow-target-same-try-label (type $0) - ;; CHECK-TEXT-NEXT: (block $l06 - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (br $l06) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $branch-and-rethrow-target-same-try-label (type $0) - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (rethrow $label$4) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (br $label$1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $branch-and-rethrow-target-same-try-label - ;; When there are both a branch and a rethrow that target the same try - ;; label. Because binaryen only allows blocks and loops to be targetted by - ;; branches, we wrap the try with a block and make branches that block - ;; instead, resulting in the br and rethrow target different labels in the - ;; output. - (try $l0 - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) - ) - (catch_all - (br $l0) - ) - ) - ) - - ;; CHECK-TEXT: (func $nested-rethrow (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $nested-rethrow (type $0) - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$5 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (rethrow $label$6) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (rethrow $label$6) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $nested-rethrow - ;; One more level deep - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (rethrow $l0) ;; by label - ) - (catch_all - (rethrow 1) ;; by depth - ) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $rnested-rethrow-with-interleaving-block (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (block $b0 - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (block $b1 - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $rnested-rethrow-with-interleaving-block (type $0) - ;; CHECK-BIN-NEXT: (try $label$7 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (block $label$5 - ;; CHECK-BIN-NEXT: (rethrow $label$7) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (rethrow $label$7) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $rnested-rethrow-with-interleaving-block - ;; Interleaving block - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (call $foo) - ) - (catch $e-i32 - (drop (pop i32)) - (block $b0 - (rethrow $l0) ;; by label - ) - ) - (catch_all - (block $b1 - (rethrow 2) ;; by depth - ) - ) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $rethrow-within-nested-try-part (type $0) - ;; CHECK-TEXT-NEXT: (try $l0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (rethrow $l0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $l07 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (call $foo) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (try $try8 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (rethrow $l07) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch_all - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $rethrow-within-nested-try-part (type $0) - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$5 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (rethrow $label$6) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$12 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (call $foo) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (try $label$11 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (rethrow $label$12) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch_all - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $rethrow-within-nested-try-part - ;; Within nested try, but rather in 'try' part and not 'catch' - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (rethrow $l0) ;; by label - ) - (catch_all) - ) - ) - ) - (try $l0 - (do - (call $foo) - ) - (catch_all - (try - (do - (rethrow 1) ;; by depth - ) - (catch_all) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $pop-within-if-condition (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-i32 - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (if (result i32) - ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i32.const 3) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $pop-within-if-condition (type $0) - ;; CHECK-BIN-NEXT: (try $label$5 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-i32 - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (if (result i32) - ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i32.const 3) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $pop-within-if-condition - (try - (do) - (catch $e-i32 - (throw $e-i32 - (if (result i32) - ;; pop is within an if condition, so this is OK. - (pop i32) - (i32.const 0) - (i32.const 3) - ) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $pop-can-be-supertype (type $0) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (catch $e-eqref - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (pop anyref) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $pop-can-be-supertype (type $0) - ;; CHECK-BIN-NEXT: (try $label$3 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (catch $e-eqref - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (pop eqref) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $pop-can-be-supertype - (try - (do) - (catch $e-eqref - (drop - (pop anyref) ;; pop can be supertype - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $catchless-try-with-inner-delegate (type $0) - ;; CHECK-TEXT-NEXT: (try $label$0 - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate $label$0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $catchless-try-with-inner-delegate (type $0) - ;; CHECK-BIN-NEXT: (try $label$6 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (try $label$4 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate $label$6) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $catchless-try-with-inner-delegate - (try $label$0 - (do - (try - (do - (throw $e-i32 - (i32.const 0) - ) - ) - (delegate $label$0) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $nested-delegate-within-block (type $0) - ;; CHECK-TEXT-NEXT: (block $l0 - ;; CHECK-TEXT-NEXT: (block $l1 - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (try $try - ;; CHECK-TEXT-NEXT: (do - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (delegate 1) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $nested-delegate-within-block (type $0) - ;; CHECK-BIN-NEXT: (block $label$1 - ;; CHECK-BIN-NEXT: (block $label$2 - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (try $label$5 - ;; CHECK-BIN-NEXT: (do - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (delegate 1) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: ) - (func $nested-delegate-within-block - ;; When 'delegate' is next to a nested block, make sure its delegate - ;; argument is parsed correctly. - (block $l0 - (block $l1) - (try - (do) - (delegate 1) ;; to caller - ) - ) - (nop) - ) - - ;; --------------------------------------------------------------------------- - ;; New exception handling - - ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $5) (result exnref) + ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $0) (result exnref) ;; CHECK-TEXT-NEXT: (local $exn exnref) ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) ;; CHECK-TEXT-NEXT: (if (result exnref) @@ -1338,7 +25,9 @@ ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $exnref-nullexnref-test (type $5) (result exnref) + ;; CHECK-BIN: (type $0 (func (result exnref))) + + ;; CHECK-BIN: (func $exnref-nullexnref-test (type $0) (result exnref) ;; CHECK-BIN-NEXT: (local $exn exnref) ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) ;; CHECK-BIN-NEXT: (if (result exnref) @@ -1363,507 +52,9 @@ ) ) ) -;; CHECK-BIN-NODEBUG: (type $0 (func)) - -;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) - -;; CHECK-BIN-NODEBUG: (type $2 (func (param i64))) - -;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 i64))) - -;; CHECK-BIN-NODEBUG: (type $4 (func (param eqref))) - -;; CHECK-BIN-NODEBUG: (type $5 (func (result exnref))) - -;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) - -;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i64)) - -;; CHECK-BIN-NODEBUG: (tag $tag$2 (param i32 i64)) - -;; CHECK-BIN-NODEBUG: (tag $tag$3 (param eqref)) - -;; CHECK-BIN-NODEBUG: (tag $tag$4) - -;; CHECK-BIN-NODEBUG: (func $0 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $1 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $2 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $3 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (local $0 i32) -;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) -;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64)) -;; CHECK-BIN-NODEBUG-NEXT: (local $3 i32) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i64.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$2 -;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 -;; CHECK-BIN-NODEBUG-NEXT: (pop i32 i64) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 -;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) -;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 -;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 -;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 -;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 -;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $4 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $5 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $6 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: (call $1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: (call $1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $7 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i64) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $8 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $9 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$1 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i64) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: (call $1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $10 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $11 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $12 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$9 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$9) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $13 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$10 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$8 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (br_if $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$10) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $14 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $15 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$4 -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $16 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$3) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $17 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$4) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $18 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $19 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$7 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$7) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $20 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$6) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$12 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (call $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (try $label$11 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (rethrow $label$12) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch_all -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $21 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (if (result i32) -;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $22 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$3 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (catch $tag$3 -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (pop eqref) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $23 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$6 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (try $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate $label$6) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $24 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (try $label$5 -;; CHECK-BIN-NODEBUG-NEXT: (do -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (delegate 1) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG: (type $0 (func (result exnref))) -;; CHECK-BIN-NODEBUG: (func $25 (type $5) (result exnref) +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) ;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) diff --git a/test/spec/exception-handling.wast b/test/spec/exception-handling-old.wast similarity index 100% rename from test/spec/exception-handling.wast rename to test/spec/exception-handling-old.wast From e9b012ff6e0e55d73d57b9a9bc4f64c15521bde1 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 13 Dec 2023 14:05:19 -0800 Subject: [PATCH 006/553] Preserve multivalue drops in IRBuilder (#6150) In Binaryen IR, we allow single `Drop` expressions to drop multiple values packaged up as a tuple. When using IRBuilder to rebuild IR containing such a drop, it previously treated the drop as a normal WebAssembly drop that dropped only a single value, producing invalid IR that had extra, undropped values. Fix the problem by preserving the arity of `Drop` inputs in IRBuilder. To avoid bloating the IR, thread the size of the desired value through IRBuilder's pop implementation so that tuple values do not need to be split up and recombined. --- src/wasm-ir-builder.h | 12 ++++++-- src/wasm/wasm-ir-builder.cpp | 44 +++++++++++++++++++++++----- test/lit/passes/outlining.wast | 52 +++++++++++++++++----------------- 3 files changed, 72 insertions(+), 36 deletions(-) diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 8b01977be3a..e1d2ce1fd2b 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -200,6 +200,8 @@ class IRBuilder : public UnifiedExpressionVisitor> { // Private functions that must be public for technical reasons. [[nodiscard]] Result<> visitExpression(Expression*); + [[nodiscard]] Result<> + visitDrop(Drop*, std::optional arity = std::nullopt); [[nodiscard]] Result<> visitIf(If*); [[nodiscard]] Result<> visitReturn(Return*); [[nodiscard]] Result<> visitStructNew(StructNew*); @@ -463,7 +465,7 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result getLabelName(Index label); [[nodiscard]] Result getDelegateLabelName(Index label); [[nodiscard]] Result addScratchLocal(Type); - [[nodiscard]] Result pop(); + [[nodiscard]] Result pop(size_t size = 1); struct HoistedVal { // The index in the stack of the original value-producing expression. @@ -478,8 +480,12 @@ class IRBuilder : public UnifiedExpressionVisitor> { // Transform the stack as necessary such that the original producer of the // hoisted value will be popped along with the final expression that produces // the value, if they are different. May only be called directly after - // hoistLastValue(). - [[nodiscard]] Result<> packageHoistedValue(const HoistedVal&); + // hoistLastValue(). `sizeHint` is the size of the type we ultimately want to + // consume, so if the hoisted value has `sizeHint` elements, it is left intact + // even if it is a tuple. Otherwise, hoisted tuple values will be broken into + // pieces. + [[nodiscard]] Result<> packageHoistedValue(const HoistedVal&, + size_t sizeHint = 1); [[nodiscard]] Result getBranchValue(Name labelName, std::optional label); diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index d3f48b1c022..fbb116aa993 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -90,7 +90,8 @@ MaybeResult IRBuilder::hoistLastValue() { return HoistedVal{Index(index), get}; } -Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted) { +Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted, + size_t sizeHint) { auto& scope = getScope(); assert(!scope.exprStack.empty()); @@ -106,7 +107,7 @@ Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted) { auto type = scope.exprStack.back()->type; - if (!type.isTuple()) { + if (type.size() == sizeHint) { if (hoisted.get) { packageAsBlock(type); } @@ -158,7 +159,8 @@ void IRBuilder::push(Expression* expr) { DBG(dump()); } -Result IRBuilder::pop() { +Result IRBuilder::pop(size_t size) { + assert(size >= 1); auto& scope = getScope(); // Find the suffix of expressions that do not produce values. @@ -173,11 +175,25 @@ Result IRBuilder::pop() { return Err{"popping from empty stack"}; } - CHECK_ERR(packageHoistedValue(*hoisted)); + CHECK_ERR(packageHoistedValue(*hoisted, size)); auto* ret = scope.exprStack.back(); - scope.exprStack.pop_back(); - return ret; + if (ret->type.size() == size) { + scope.exprStack.pop_back(); + return ret; + } + + // The last value-producing expression did not produce exactly the right + // number of values, so we need to construct a tuple piecewise instead. + assert(size > 1); + std::vector elems; + elems.resize(size); + for (int i = size - 1; i >= 0; --i) { + auto elem = pop(); + CHECK_ERR(elem); + elems[i] = *elem; + } + return builder.makeTupleMake(elems); } Result IRBuilder::build() { @@ -319,6 +335,20 @@ Result<> IRBuilder::visitExpression(Expression* curr) { return Ok{}; } +Result<> IRBuilder::visitDrop(Drop* curr, std::optional arity) { + // Multivalue drops must remain multivalue drops. + if (!arity) { + arity = curr->value->type.size(); + } + if (*arity >= 2) { + auto val = pop(*arity); + CHECK_ERR(val); + curr->value = *val; + return Ok{}; + } + return visitExpression(curr); +} + Result<> IRBuilder::visitIf(If* curr) { // Only the condition is popped from the stack. The ifTrue and ifFalse are // self-contained so we do not modify them. @@ -1183,7 +1213,7 @@ Result<> IRBuilder::makeSelect(std::optional type) { Result<> IRBuilder::makeDrop() { Drop curr; - CHECK_ERR(visitDrop(&curr)); + CHECK_ERR(visitDrop(&curr, 1)); push(builder.makeDrop(curr.value)); return Ok{}; } diff --git a/test/lit/passes/outlining.wast b/test/lit/passes/outlining.wast index 46a3de0bd36..1d7d0e6c2e7 100644 --- a/test/lit/passes/outlining.wast +++ b/test/lit/passes/outlining.wast @@ -729,20 +729,16 @@ ) ;; Test outlining works with call_indirect -;; 0 results, 2 params, 3 operands +;; 0 results, 0 params, 1 operand (module (table funcref) ;; CHECK: (type $0 (func)) - ;; CHECK: (type $1 (func (param i32 i32))) - ;; CHECK: (table $0 0 funcref) ;; CHECK: (func $outline$ (type $0) - ;; CHECK-NEXT: (call_indirect $0 (type $1) + ;; CHECK-NEXT: (call_indirect $0 (type $0) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -752,31 +748,29 @@ ;; CHECK-NEXT: ) (func $a (call_indirect - (param i32 i32) (i32.const 0) - (i32.const 1) - (i32.const 2) ) (call_indirect - (param i32 i32) (i32.const 0) - (i32.const 1) - (i32.const 2) ) ) ) ;; Test outlining works with call_indirect -;; 0 results, 0 params, 1 operand +;; 1 result, 0 params, 1 operand (module (table funcref) ;; CHECK: (type $0 (func)) + ;; CHECK: (type $1 (func (result i32))) + ;; CHECK: (table $0 0 funcref) ;; CHECK: (func $outline$ (type $0) - ;; CHECK-NEXT: (call_indirect $0 (type $0) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_indirect $0 (type $1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -785,27 +779,33 @@ ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) (func $a - (call_indirect - (i32.const 0) + (drop + (call_indirect + (result i32) + (i32.const 0) + ) ) - (call_indirect - (i32.const 0) + (drop + (call_indirect + (result i32) + (i32.const 0) + ) ) ) ) ;; Test outlining works with call_indirect -;; 1 result, 0 params, 1 operand +;; 2 results, 0 params, 1 operand (module (table funcref) ;; CHECK: (type $0 (func)) - ;; CHECK: (type $1 (func (result i32))) + ;; CHECK: (type $1 (func (result i32 i32))) ;; CHECK: (table $0 0 funcref) ;; CHECK: (func $outline$ (type $0) - ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (tuple.drop 2 ;; CHECK-NEXT: (call_indirect $0 (type $1) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -817,15 +817,15 @@ ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) (func $a - (drop + (tuple.drop 2 (call_indirect - (result i32) + (result i32 i32) (i32.const 0) ) ) - (drop + (tuple.drop 2 (call_indirect - (result i32) + (result i32 i32) (i32.const 0) ) ) From 7adc82b5da6ad2b36d2f335af6619601ccc8e36b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 13 Dec 2023 15:50:28 -0800 Subject: [PATCH 007/553] [Parser] Parse tuple operations (#6174) Parse `tuple.make`, `tuple.extract`, and `tuple.drop`. Also slightly improve the way we break up tuples into individual elements in IRBuilder by using a `local.tee` instead of a block containing a `local.set` and `local.get`. --- src/parser/contexts.h | 15 +++ src/parser/parsers.h | 29 ++++- src/wasm-ir-builder.h | 9 +- src/wasm.h | 1 + src/wasm/wasm-ir-builder.cpp | 67 ++++++++--- test/lit/passes/outlining.wast | 14 +-- test/lit/wat-kitchen-sink.wast | 196 +++++++++++++++------------------ 7 files changed, 194 insertions(+), 137 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 620d10d6093..3ed4550432d 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -430,6 +430,9 @@ struct NullInstrParserCtx { Result<> makeTableCopy(Index, TableIdxT*, TableIdxT*) { return Ok{}; } Result<> makeThrow(Index, TagIdxT) { return Ok{}; } Result<> makeRethrow(Index, LabelIdxT) { return Ok{}; } + Result<> makeTupleMake(Index, uint32_t) { return Ok{}; } + Result<> makeTupleExtract(Index, uint32_t, uint32_t) { return Ok{}; } + Result<> makeTupleDrop(Index, uint32_t) { return Ok{}; } template Result<> makeCallRef(Index, HeapTypeT, bool) { return Ok{}; } @@ -1624,6 +1627,18 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeRethrow(label)); } + Result<> makeTupleMake(Index pos, uint32_t arity) { + return withLoc(pos, irBuilder.makeTupleMake(arity)); + } + + Result<> makeTupleExtract(Index pos, uint32_t arity, uint32_t index) { + return withLoc(pos, irBuilder.makeTupleExtract(arity, index)); + } + + Result<> makeTupleDrop(Index pos, uint32_t arity) { + return withLoc(pos, irBuilder.makeTupleDrop(arity)); + } + Result<> makeCallRef(Index pos, HeapType type, bool isReturn) { return withLoc(pos, irBuilder.makeCallRef(type, isReturn)); } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 4909ad05751..dc86e0d6034 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -41,6 +41,7 @@ template Result limits64(Ctx&); template Result memtype(Ctx&); template Result tabletype(Ctx&); template Result globaltype(Ctx&); +template Result tupleArity(Ctx&); // Instructions template MaybeResult<> foldedBlockinstr(Ctx&); @@ -605,6 +606,18 @@ template Result globaltype(Ctx& ctx) { return ctx.makeGlobalType(mutability, *type); } +// arity ::= x:u32 (if x >=2 ) +template Result tupleArity(Ctx& ctx) { + auto arity = ctx.in.takeU32(); + if (!arity) { + return ctx.in.err("expected tuple arity"); + } + if (*arity < 2) { + return ctx.in.err("tuple arity must be at least 2"); + } + return *arity; +} + // ============ // Instructions // ============ @@ -1512,15 +1525,25 @@ template Result<> makeRethrow(Ctx& ctx, Index pos) { } template Result<> makeTupleMake(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto arity = tupleArity(ctx); + CHECK_ERR(arity); + return ctx.makeTupleMake(pos, *arity); } template Result<> makeTupleExtract(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto arity = tupleArity(ctx); + CHECK_ERR(arity); + auto index = ctx.in.takeU32(); + if (!index) { + return ctx.in.err("expected tuple index"); + } + return ctx.makeTupleExtract(pos, *arity, *index); } template Result<> makeTupleDrop(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto arity = tupleArity(ctx); + CHECK_ERR(arity); + return ctx.makeTupleDrop(pos, *arity); } template diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index e1d2ce1fd2b..398cd4f9a02 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -157,8 +157,9 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeTry(Name label, Type type); [[nodiscard]] Result<> makeThrow(Name tag); [[nodiscard]] Result<> makeRethrow(Index label); - // [[nodiscard]] Result<> makeTupleMake(); - // [[nodiscard]] Result<> makeTupleExtract(); + [[nodiscard]] Result<> makeTupleMake(uint32_t arity); + [[nodiscard]] Result<> makeTupleExtract(uint32_t arity, uint32_t index); + [[nodiscard]] Result<> makeTupleDrop(uint32_t arity); [[nodiscard]] Result<> makeRefI31(); [[nodiscard]] Result<> makeI31Get(bool signed_); [[nodiscard]] Result<> makeCallRef(HeapType type, bool isReturn); @@ -217,6 +218,10 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> visitThrow(Throw*); [[nodiscard]] Result<> visitStringNew(StringNew*); [[nodiscard]] Result<> visitStringEncode(StringEncode*); + [[nodiscard]] Result<> visitTupleMake(TupleMake*); + [[nodiscard]] Result<> + visitTupleExtract(TupleExtract*, + std::optional arity = std::nullopt); private: Module& wasm; diff --git a/src/wasm.h b/src/wasm.h index ce334773a2c..1b01278b02c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1501,6 +1501,7 @@ class TupleMake : public SpecificExpression { class TupleExtract : public SpecificExpression { public: + TupleExtract() = default; TupleExtract(MixedArena& allocator) {} Expression* tuple; diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index fbb116aa993..9ee7a2a18eb 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -107,17 +107,17 @@ Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted, auto type = scope.exprStack.back()->type; - if (type.size() == sizeHint) { + if (type.size() == sizeHint || type.size() <= 1) { if (hoisted.get) { packageAsBlock(type); } return Ok{}; } - // We need to break up the hoisted tuple. Create and push a block setting the - // tuple to a local and returning its first element, then push additional gets - // of each of its subsequent elements. Reuse the scratch local we used for - // hoisting, if it exists. + // We need to break up the hoisted tuple. Create and push an expression + // setting the tuple to a local and returning its first element, then push + // additional gets of each of its subsequent elements. Reuse the scratch local + // we used for hoisting, if it exists. Index scratchIdx; if (hoisted.get) { // Update the get on top of the stack to just return the first element. @@ -127,12 +127,8 @@ Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted, } else { auto scratch = addScratchLocal(type); CHECK_ERR(scratch); - auto* block = builder.makeSequence( - builder.makeLocalSet(*scratch, scope.exprStack.back()), - builder.makeTupleExtract(builder.makeLocalGet(*scratch, type), 0), - type[0]); - scope.exprStack.pop_back(); - push(block); + scope.exprStack.back() = builder.makeTupleExtract( + builder.makeLocalTee(*scratch, scope.exprStack.back(), type), 0); scratchIdx = *scratch; } for (Index i = 1, size = type.size(); i < size; ++i) { @@ -560,6 +556,33 @@ Result<> IRBuilder::visitStringEncode(StringEncode* curr) { WASM_UNREACHABLE("unexpected op"); } +Result<> IRBuilder::visitTupleMake(TupleMake* curr) { + assert(curr->operands.size() >= 2); + for (size_t i = 0, size = curr->operands.size(); i < size; ++i) { + auto elem = pop(); + CHECK_ERR(elem); + curr->operands[size - 1 - i] = *elem; + } + return Ok{}; +} + +Result<> IRBuilder::visitTupleExtract(TupleExtract* curr, + std::optional arity) { + if (!arity) { + if (curr->tuple->type == Type::unreachable) { + // Fallback to an arbitrary valid arity. + arity = 2; + } else { + arity = curr->tuple->type.size(); + } + } + assert(*arity >= 2); + auto tuple = pop(*arity); + CHECK_ERR(tuple); + curr->tuple = *tuple; + return Ok{}; +} + Result<> IRBuilder::visitFunctionStart(Function* func) { if (!scopeStack.empty()) { return Err{"unexpected start of function"}; @@ -1332,9 +1355,27 @@ Result<> IRBuilder::makeRethrow(Index label) { return Ok{}; } -// Result<> IRBuilder::makeTupleMake() {} +Result<> IRBuilder::makeTupleMake(uint32_t arity) { + TupleMake curr(wasm.allocator); + curr.operands.resize(arity); + CHECK_ERR(visitTupleMake(&curr)); + push(builder.makeTupleMake(curr.operands)); + return Ok{}; +} + +Result<> IRBuilder::makeTupleExtract(uint32_t arity, uint32_t index) { + TupleExtract curr; + CHECK_ERR(visitTupleExtract(&curr, arity)); + push(builder.makeTupleExtract(curr.tuple, index)); + return Ok{}; +} -// Result<> IRBuilder::makeTupleExtract() {} +Result<> IRBuilder::makeTupleDrop(uint32_t arity) { + Drop curr; + CHECK_ERR(visitDrop(&curr, arity)); + push(builder.makeDrop(curr.value)); + return Ok{}; +} Result<> IRBuilder::makeRefI31() { RefI31 curr; diff --git a/test/lit/passes/outlining.wast b/test/lit/passes/outlining.wast index 1d7d0e6c2e7..349513dde3f 100644 --- a/test/lit/passes/outlining.wast +++ b/test/lit/passes/outlining.wast @@ -645,13 +645,10 @@ ;; CHECK-NEXT: (local $scratch_1 (i32 i32)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $scratch + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.tee $scratch ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 0 - ;; CHECK-NEXT: (local.get $scratch) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (tuple.extract 2 1 ;; CHECK-NEXT: (local.get $scratch) @@ -660,13 +657,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $scratch_1 + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.tee $scratch_1 ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 0 - ;; CHECK-NEXT: (local.get $scratch_1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (tuple.extract 2 1 ;; CHECK-NEXT: (local.get $scratch_1) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 31910686bab..98795e5eec2 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -34,26 +34,26 @@ (rec) - ;; CHECK: (type $any-array (array (mut anyref))) - ;; CHECK: (type $packed-i8 (array (mut i8))) ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) - ;; CHECK: (type $14 (func)) + ;; CHECK: (type $13 (func)) - ;; CHECK: (type $15 (func (param i32))) + ;; CHECK: (type $14 (func (param i32))) - ;; CHECK: (type $16 (func (param i32 i64 v128))) + ;; CHECK: (type $15 (func (param i32 i64 v128))) ;; CHECK: (type $a0 (array i32)) - ;; CHECK: (type $18 (func (param i32 i32 i32))) + ;; CHECK: (type $17 (func (param i32 i32 i32))) - ;; CHECK: (type $19 (func (param v128 i32) (result v128))) + ;; CHECK: (type $18 (func (param v128 i32) (result v128))) ;; CHECK: (type $packed-i16 (array (mut i16))) + ;; CHECK: (type $any-array (array (mut anyref))) + ;; CHECK: (type $21 (func (param stringref))) ;; CHECK: (type $22 (func (param stringref stringref) (result i32))) @@ -106,69 +106,67 @@ ;; CHECK: (type $46 (func (param i32) (result (ref $a1)))) - ;; CHECK: (type $47 (func (param i32 i32) (result (ref $any-array)))) - - ;; CHECK: (type $48 (func (param i32 i32) (result (ref $a1)))) + ;; CHECK: (type $47 (func (param i32 i32) (result (ref $a1)))) - ;; CHECK: (type $49 (func (param (ref $a1) i32) (result i64))) + ;; CHECK: (type $48 (func (param (ref $a1) i32) (result i64))) - ;; CHECK: (type $50 (func (param (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $49 (func (param (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $51 (func (param (ref $packed-i16) i32) (result i32))) + ;; CHECK: (type $50 (func (param (ref $packed-i16) i32) (result i32))) - ;; CHECK: (type $52 (func (param (ref $a2) i32 f32))) + ;; CHECK: (type $51 (func (param (ref $a2) i32 f32))) - ;; CHECK: (type $53 (func (param arrayref) (result i32))) + ;; CHECK: (type $52 (func (param arrayref) (result i32))) - ;; CHECK: (type $54 (func (param (ref $a2) i32 (ref $a2) i32 i32))) + ;; CHECK: (type $53 (func (param (ref $a2) i32 (ref $a2) i32 i32))) - ;; CHECK: (type $55 (func (param (ref $a2) i32 f32 i32))) + ;; CHECK: (type $54 (func (param (ref $a2) i32 f32 i32))) - ;; CHECK: (type $56 (func (param (ref $a2) i32 i32 i32))) + ;; CHECK: (type $55 (func (param (ref $a2) i32 i32 i32))) - ;; CHECK: (type $57 (func (param (ref $any-array) i32 i32 i32))) + ;; CHECK: (type $56 (func (param (ref $any-array) i32 i32 i32))) - ;; CHECK: (type $58 (func (param externref))) + ;; CHECK: (type $57 (func (param externref))) - ;; CHECK: (type $59 (func (param i32 i32) (result stringref))) + ;; CHECK: (type $58 (func (param i32 i32) (result stringref))) - ;; CHECK: (type $60 (func (param (ref $packed-i8) i32 i32) (result stringref))) + ;; CHECK: (type $59 (func (param (ref $packed-i8) i32 i32) (result stringref))) - ;; CHECK: (type $61 (func (param i32) (result stringref))) + ;; CHECK: (type $60 (func (param i32) (result stringref))) - ;; CHECK: (type $62 (func (result (ref string)))) + ;; CHECK: (type $61 (func (result (ref string)))) - ;; CHECK: (type $63 (func (param stringref) (result i32))) + ;; CHECK: (type $62 (func (param stringref) (result i32))) - ;; CHECK: (type $64 (func (param stringview_wtf16) (result i32))) + ;; CHECK: (type $63 (func (param stringview_wtf16) (result i32))) - ;; CHECK: (type $65 (func (param stringref (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $64 (func (param stringref (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $66 (func (param stringref stringref) (result (ref string)))) + ;; CHECK: (type $65 (func (param stringref stringref) (result (ref string)))) - ;; CHECK: (type $67 (func (param stringref) (result stringview_wtf8))) + ;; CHECK: (type $66 (func (param stringref) (result stringview_wtf8))) - ;; CHECK: (type $68 (func (param stringref) (result (ref stringview_wtf16)))) + ;; CHECK: (type $67 (func (param stringref) (result (ref stringview_wtf16)))) - ;; CHECK: (type $69 (func (param stringref) (result stringview_iter))) + ;; CHECK: (type $68 (func (param stringref) (result stringview_iter))) - ;; CHECK: (type $70 (func (param (ref stringview_wtf8) i32 i32) (result i32))) + ;; CHECK: (type $69 (func (param (ref stringview_wtf8) i32 i32) (result i32))) - ;; CHECK: (type $71 (func (param stringview_wtf16 i32) (result i32))) + ;; CHECK: (type $70 (func (param stringview_wtf16 i32) (result i32))) - ;; CHECK: (type $72 (func (param stringview_iter) (result i32))) + ;; CHECK: (type $71 (func (param stringview_iter) (result i32))) - ;; CHECK: (type $73 (func (param stringview_iter i32) (result i32))) + ;; CHECK: (type $72 (func (param stringview_iter i32) (result i32))) - ;; CHECK: (type $74 (func (param (ref stringview_iter) i32) (result i32))) + ;; CHECK: (type $73 (func (param (ref stringview_iter) i32) (result i32))) - ;; CHECK: (type $75 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) + ;; CHECK: (type $74 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) - ;; CHECK: (type $76 (func (param stringview_iter i32) (result (ref string)))) + ;; CHECK: (type $75 (func (param stringview_iter i32) (result (ref string)))) - ;; CHECK: (type $77 (func (param i64 v128) (result v128))) + ;; CHECK: (type $76 (func (param i64 v128) (result v128))) - ;; CHECK: (type $78 (func (param i64 v128))) + ;; CHECK: (type $77 (func (param i64 v128))) ;; CHECK: (type $s2 (struct (field i32))) (type $s2 (struct i32)) @@ -233,7 +231,8 @@ ;; globals (global (mut i32) i32.const 0) - ;; CHECK: (type $89 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) + + ;; CHECK: (type $88 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) ;; CHECK: (import "" "mem" (memory $mimport$0 0)) @@ -382,11 +381,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK: (func $f1 (type $15) (param $0 i32) + ;; CHECK: (func $f1 (type $14) (param $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f1 (param i32)) - ;; CHECK: (func $f2 (type $15) (param $x i32) + ;; CHECK: (func $f2 (type $14) (param $x i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f2 (param $x i32)) @@ -917,8 +916,8 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (local.set $scratch_2 - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $scratch_1 + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.tee $scratch_1 ;; CHECK-NEXT: (block $1 (type $ret2) (result i32 i32) ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (block $2 (result i32) @@ -934,9 +933,6 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 0 - ;; CHECK-NEXT: (local.get $scratch_1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2555,7 +2551,7 @@ drop ) - ;; CHECK: (func $select (type $18) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $select (type $17) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $0) @@ -2847,7 +2843,7 @@ i32x4.extract_lane 3 ) - ;; CHECK: (func $simd-replace (type $19) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-replace (type $18) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i32x4.replace_lane 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2885,7 +2881,7 @@ v128.bitselect ) - ;; CHECK: (func $simd-shift (type $19) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-shift (type $18) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i8x16.shl ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2918,7 +2914,7 @@ drop ) - ;; CHECK: (func $simd-load-store-lane (type $16) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $simd-load-store-lane (type $15) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load16_lane $mimport$0 7 ;; CHECK-NEXT: (local.get $0) @@ -2940,7 +2936,7 @@ v128.store64_lane 4 align=4 0 ) - ;; CHECK: (func $memory-init (type $18) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $memory-init (type $17) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (memory.init $mem-i32 $passive ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3373,15 +3369,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (local.set $scratch_4 - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $scratch + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.tee $scratch ;; CHECK-NEXT: (call_ref $ret2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 0 - ;; CHECK-NEXT: (local.get $scratch) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -3395,8 +3388,8 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result anyref) ;; CHECK-NEXT: (local.set $scratch_6 - ;; CHECK-NEXT: (block (result anyref) - ;; CHECK-NEXT: (local.set $scratch_5 + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.tee $scratch_5 ;; CHECK-NEXT: (call_ref $many ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i64.const 1) @@ -3405,9 +3398,6 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 0 - ;; CHECK-NEXT: (local.get $scratch_5) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -3648,19 +3638,7 @@ array.new_default 11 ) - ;; CHECK: (func $array-new-elem (type $47) (param $0 i32) (param $1 i32) (result (ref $any-array)) - ;; CHECK-NEXT: (array.new_elem $any-array $passive-2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $array-new-elem (param i32 i32) (result (ref $any-array)) - local.get 0 - local.get 1 - array.new_elem $any-array $passive-2 - ) - - ;; CHECK: (func $array-new-data (type $48) (param $0 i32) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-data (type $47) (param $0 i32) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_data $a1 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3694,7 +3672,7 @@ drop ) - ;; CHECK: (func $array-get (type $49) (param $0 (ref $a1)) (param $1 i32) (result i64) + ;; CHECK: (func $array-get (type $48) (param $0 (ref $a1)) (param $1 i32) (result i64) ;; CHECK-NEXT: (array.get $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3706,7 +3684,7 @@ array.get $a1 ) - ;; CHECK: (func $array-get-s (type $50) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-s (type $49) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_s $packed-i8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3718,7 +3696,7 @@ array.get_s 15 ) - ;; CHECK: (func $array-get-u (type $51) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-u (type $50) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_u $packed-i16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3730,7 +3708,7 @@ array.get_u $packed-i16 ) - ;; CHECK: (func $array-set (type $52) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) + ;; CHECK: (func $array-set (type $51) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) ;; CHECK-NEXT: (array.set $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3744,7 +3722,7 @@ array.set $a2 ) - ;; CHECK: (func $array-len (type $53) (param $0 arrayref) (result i32) + ;; CHECK: (func $array-len (type $52) (param $0 arrayref) (result i32) ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3754,7 +3732,7 @@ array.len ) - ;; CHECK: (func $array-copy (type $54) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) + ;; CHECK: (func $array-copy (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) ;; CHECK-NEXT: (array.copy $a2 $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3772,7 +3750,7 @@ array.copy $a2 $a2 ) - ;; CHECK: (func $array-fill (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) + ;; CHECK: (func $array-fill (type $54) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) ;; CHECK-NEXT: (array.fill $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3788,7 +3766,7 @@ array.fill $a2 ) - ;; CHECK: (func $array-init-data (type $56) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-data (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_data $a2 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3804,7 +3782,7 @@ array.init_data $a2 0 ) - ;; CHECK: (func $array-init-elem (type $57) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-elem (type $56) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_elem $any-array $passive-2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3833,7 +3811,7 @@ drop ) - ;; CHECK: (func $any-convert-extern (type $58) (param $0 externref) + ;; CHECK: (func $any-convert-extern (type $57) (param $0 externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.internalize ;; CHECK-NEXT: (local.get $0) @@ -3859,7 +3837,7 @@ drop ) - ;; CHECK: (func $string-new (type $59) (param $0 i32) (param $1 i32) (result stringref) + ;; CHECK: (func $string-new (type $58) (param $0 i32) (param $1 i32) (result stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_utf8_try ;; CHECK-NEXT: (local.get $0) @@ -3901,7 +3879,7 @@ string.new_wtf16 ) - ;; CHECK: (func $string-new-gc (type $60) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) + ;; CHECK: (func $string-new-gc (type $59) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) ;; CHECK-NEXT: (string.new_utf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3915,7 +3893,7 @@ string.new_utf8_array ) - ;; CHECK: (func $string-new-code-point (type $61) (param $0 i32) (result stringref) + ;; CHECK: (func $string-new-code-point (type $60) (param $0 i32) (result stringref) ;; CHECK-NEXT: (string.from_code_point ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3925,7 +3903,7 @@ string.from_code_point ) - ;; CHECK: (func $string-const (type $62) (result (ref string)) + ;; CHECK: (func $string-const (type $61) (result (ref string)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.const "foobar") ;; CHECK-NEXT: ) @@ -3974,7 +3952,7 @@ drop ) - ;; CHECK: (func $string-hash (type $63) (param $0 stringref) (result i32) + ;; CHECK: (func $string-hash (type $62) (param $0 stringref) (result i32) ;; CHECK-NEXT: (string.hash ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3984,7 +3962,7 @@ string.hash ) - ;; CHECK: (func $stringview-length (type $64) (param $0 stringview_wtf16) (result i32) + ;; CHECK: (func $stringview-length (type $63) (param $0 stringview_wtf16) (result i32) ;; CHECK-NEXT: (stringview_wtf16.length ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4039,7 +4017,7 @@ drop ) - ;; CHECK: (func $string-encode-gc (type $65) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) + ;; CHECK: (func $string-encode-gc (type $64) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) ;; CHECK-NEXT: (string.encode_wtf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4053,7 +4031,7 @@ string.encode_wtf8_array ) - ;; CHECK: (func $string-concat (type $66) (param $0 stringref) (param $1 stringref) (result (ref string)) + ;; CHECK: (func $string-concat (type $65) (param $0 stringref) (param $1 stringref) (result (ref string)) ;; CHECK-NEXT: (string.concat ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4089,7 +4067,7 @@ string.compare ) - ;; CHECK: (func $string-as-wtf8 (type $67) (param $0 stringref) (result stringview_wtf8) + ;; CHECK: (func $string-as-wtf8 (type $66) (param $0 stringref) (result stringview_wtf8) ;; CHECK-NEXT: (string.as_wtf8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4099,7 +4077,7 @@ string.as_wtf8 ) - ;; CHECK: (func $string-as-wtf16 (type $68) (param $0 stringref) (result (ref stringview_wtf16)) + ;; CHECK: (func $string-as-wtf16 (type $67) (param $0 stringref) (result (ref stringview_wtf16)) ;; CHECK-NEXT: (string.as_wtf16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4109,7 +4087,7 @@ string.as_wtf16 ) - ;; CHECK: (func $string-as-iter (type $69) (param $0 stringref) (result stringview_iter) + ;; CHECK: (func $string-as-iter (type $68) (param $0 stringref) (result stringview_iter) ;; CHECK-NEXT: (string.as_iter ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4119,7 +4097,7 @@ string.as_iter ) - ;; CHECK: (func $string-advance (type $70) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK: (func $string-advance (type $69) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf8.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4133,7 +4111,7 @@ stringview_wtf8.advance ) - ;; CHECK: (func $string-get (type $71) (param $0 stringview_wtf16) (param $1 i32) (result i32) + ;; CHECK: (func $string-get (type $70) (param $0 stringview_wtf16) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf16.get_codeunit ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4145,7 +4123,7 @@ stringview_wtf16.get_codeunit ) - ;; CHECK: (func $string-iter-next (type $72) (param $0 stringview_iter) (result i32) + ;; CHECK: (func $string-iter-next (type $71) (param $0 stringview_iter) (result i32) ;; CHECK-NEXT: (stringview_iter.next ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4155,7 +4133,7 @@ stringview_iter.next ) - ;; CHECK: (func $string-iter-advance (type $73) (param $0 stringview_iter) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-advance (type $72) (param $0 stringview_iter) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4167,7 +4145,7 @@ stringview_iter.advance ) - ;; CHECK: (func $string-iter-rewind (type $74) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-rewind (type $73) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.rewind ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4179,7 +4157,7 @@ stringview_iter.rewind ) - ;; CHECK: (func $string-slice (type $75) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) + ;; CHECK: (func $string-slice (type $74) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (stringview_wtf8.slice ;; CHECK-NEXT: (local.get $0) @@ -4208,7 +4186,7 @@ drop ) - ;; CHECK: (func $string-iter-slice (type $76) (param $0 stringview_iter) (param $1 i32) (result (ref string)) + ;; CHECK: (func $string-iter-slice (type $75) (param $0 stringview_iter) (param $1 i32) (result (ref string)) ;; CHECK-NEXT: (stringview_iter.slice ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4244,7 +4222,7 @@ return_call $return_call ) - ;; CHECK: (func $call-indirect (type $16) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4273,7 +4251,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $77) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $76) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4306,7 +4284,7 @@ drop ) - ;; CHECK: (func $return-call-indirect (type $16) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $return-call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4334,7 +4312,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $78) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $77) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4365,7 +4343,7 @@ return_call_indirect (param i64 v128) ) - ;; CHECK: (func $use-types (type $89) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) + ;; CHECK: (func $use-types (type $88) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-types From bdd96e8c21d23a57a99dcca9d4d802ff471243c3 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 14 Dec 2023 10:27:53 -0800 Subject: [PATCH 008/553] [Parser] Parse explicit exports (#6179) --- src/parser/contexts.h | 13 ++++++++ src/parser/parsers.h | 55 ++++++++++++++++++++++++++++++++++ src/parser/wat-parser.cpp | 10 +++++++ test/lit/wat-kitchen-sink.wast | 18 +++++++++-- 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 3ed4550432d..e09f8bbd0aa 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -548,6 +548,9 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { std::vector dataDefs; std::vector tagDefs; + // Positions of export definitions. + std::vector exportDefs; + // Positions of typeuses that might implicitly define new types. std::vector implicitTypeDefs; @@ -684,6 +687,11 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { ImportNames* import, TypeUseT type, Index pos); + + Result<> addExport(Index pos, Ok, Name, ExternalKind) { + exportDefs.push_back(pos); + return Ok{}; + } }; // Phase 2: Parse type definitions into a TypeBuilder. @@ -1265,6 +1273,11 @@ struct ParseDefsCtx : TypeParserCtx { Result<> addData(Name, Name* mem, std::optional offset, DataStringT, Index pos); + Result<> addExport(Index, Name value, Name name, ExternalKind kind) { + wasm.addExport(builder.makeExport(name, value, kind)); + return Ok{}; + } + Result addScratchLocal(Index pos, Type type) { if (!func) { return in.err(pos, diff --git a/src/parser/parsers.h b/src/parser/parsers.h index dc86e0d6034..54644cafcb2 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -194,6 +194,7 @@ template MaybeResult<> func(Ctx&); template MaybeResult<> table(Ctx&); template MaybeResult<> memory(Ctx&); template MaybeResult<> global(Ctx&); +template MaybeResult<> export_(Ctx&); template MaybeResult maybeElemexpr(Ctx&); template Result elemlist(Ctx&, bool); template MaybeResult<> elem(Ctx&); @@ -2371,6 +2372,56 @@ template MaybeResult<> global(Ctx& ctx) { return Ok{}; } +// export ::= '(' 'export' nm:name exportdesc ')' +// exportdesc ::= '(' 'func' x:funcidx ')' +// | '(' 'table' x:tableidx ')' +// | '(' 'memory' x:memidx ')' +// | '(' 'global' x:globalidx ')' +// | '(' 'tag' x:tagidx ')' +template MaybeResult<> export_(Ctx& ctx) { + auto pos = ctx.in.getPos(); + if (!ctx.in.takeSExprStart("export"sv)) { + return {}; + } + + auto name = ctx.in.takeName(); + if (!name) { + return ctx.in.err("expected export name"); + } + + if (ctx.in.takeSExprStart("func"sv)) { + auto idx = funcidx(ctx); + CHECK_ERR(idx); + CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Function)); + } else if (ctx.in.takeSExprStart("table"sv)) { + auto idx = tableidx(ctx); + CHECK_ERR(idx); + CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Table)); + } else if (ctx.in.takeSExprStart("memory"sv)) { + auto idx = memidx(ctx); + CHECK_ERR(idx); + CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Memory)); + } else if (ctx.in.takeSExprStart("global"sv)) { + auto idx = globalidx(ctx); + CHECK_ERR(idx); + CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Global)); + } else if (ctx.in.takeSExprStart("tag"sv)) { + auto idx = tagidx(ctx); + CHECK_ERR(idx); + CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Tag)); + } else { + return ctx.in.err("expected export description"); + } + + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of export description"); + } + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of export"); + } + return Ok{}; +} + // elemexpr ::= '(' 'item' expr ')' | '(' instr ')' template MaybeResult maybeElemexpr(Ctx& ctx) { @@ -2611,6 +2662,10 @@ template MaybeResult<> modulefield(Ctx& ctx) { CHECK_ERR(res); return Ok{}; } + if (auto res = export_(ctx)) { + CHECK_ERR(res); + return Ok{}; + } if (auto res = elem(ctx)) { CHECK_ERR(res); return Ok{}; diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp index cc0f582fc15..95dfa1405fb 100644 --- a/src/parser/wat-parser.cpp +++ b/src/parser/wat-parser.cpp @@ -178,6 +178,16 @@ Result<> parseModule(Module& wasm, std::string_view input) { CHECK_ERR(parsed); assert(parsed); } + + // Parse exports. + // TODO: It would be more technically correct to interleave these properly + // with the implicit inline exports in other module field definitions. + for (auto pos : decls.exportDefs) { + WithPosition with(ctx, pos); + auto parsed = export_(ctx); + CHECK_ERR(parsed); + assert(parsed); + } } return Ok{}; diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 98795e5eec2..4368a1cb2f2 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -354,9 +354,7 @@ ;; CHECK: (tag $tag-pair (param i32 i64)) (tag $tag-pair (param i32 i64)) - ;; functions - (func) - + ;; explicit exports ;; CHECK: (export "g1" (global $g1)) ;; CHECK: (export "g1.1" (global $g1)) @@ -377,6 +375,20 @@ ;; CHECK: (export "t0.1" (tag $imported)) + ;; CHECK: (export "exported-func" (func $fimport$0)) + (export "exported-func" (func 0)) + ;; CHECK: (export "exported-table" (table $timport$0)) + (export "exported-table" (table 0)) + ;; CHECK: (export "exported-memory" (memory $mimport$0)) + (export "exported-memory" (memory 0)) + ;; CHECK: (export "exported-global" (global $g1)) + (export "exported-global" (global 0)) + ;; CHECK: (export "exported-tag" (tag $imported)) + (export "exported-tag" (tag 0)) + + ;; functions + (func) + ;; CHECK: (func $1 (type $void) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) From cad983c975a05bc262437a6d7ed3a61020ef4e8d Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 14 Dec 2023 10:34:39 -0800 Subject: [PATCH 009/553] Remove empty _ARRAY/_VECTOR defines (NFC) (#6182) `_VECTOR` or `_ARRAY` defines in `wasm-delegations-fields.def` are supposed to be defined in terms of their non-vector/array counterparts when undefined. This removes empty `_VECTOR`/`_ARRAY` defines when including `wasm-delegations-fields.def`, while adding definitions for `DELEGATE_GET_FIELD` in case it is missing. --- src/ir/branch-utils.h | 9 ++------- src/ir/iteration.h | 3 --- src/ir/memory-utils.cpp | 3 --- src/ir/properties.h | 3 --- src/ir/type-updating.cpp | 3 --- src/passes/MemoryPacking.cpp | 3 --- src/passes/RemoveUnusedModuleElements.cpp | 3 --- src/tools/wasm-merge.cpp | 3 --- src/tools/wasm-metadce.cpp | 3 --- src/wasm-traversal.h | 3 --- src/wasm/wasm-ir-builder.cpp | 4 +--- 11 files changed, 3 insertions(+), 37 deletions(-) diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h index 3527f1b3693..9598e283025 100644 --- a/src/ir/branch-utils.h +++ b/src/ir/branch-utils.h @@ -54,13 +54,10 @@ template void operateOnScopeNameUses(Expression* expr, T func) { #define DELEGATE_FIELD_INT(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) -#define DELEGATE_FIELD_CHILD_VECTOR(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #include "wasm-delegations-fields.def" } @@ -110,20 +107,18 @@ template void operateOnScopeNameDefs(Expression* expr, T func) { #define DELEGATE_START(id) [[maybe_unused]] auto* cast = expr->cast(); +#define DELEGATE_GET_FIELD(id, field) cast->field + #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) func(cast->field) #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) -#define DELEGATE_FIELD_CHILD_VECTOR(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #include "wasm-delegations-fields.def" } diff --git a/src/ir/iteration.h b/src/ir/iteration.h index 3b2c5ce28b6..bfbf3bb6263 100644 --- a/src/ir/iteration.h +++ b/src/ir/iteration.h @@ -102,13 +102,10 @@ template class AbstractChildIterator { } #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) diff --git a/src/ir/memory-utils.cpp b/src/ir/memory-utils.cpp index 5c9dde235b6..dddcdd1f181 100644 --- a/src/ir/memory-utils.cpp +++ b/src/ir/memory-utils.cpp @@ -50,13 +50,10 @@ bool flatten(Module& wasm) { #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ diff --git a/src/ir/properties.h b/src/ir/properties.h index e8a17b10659..914a26919bf 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -447,13 +447,10 @@ inline Index getNumChildren(Expression* curr) { } #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 42ab2849a17..e9cf1859b8c 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -229,13 +229,10 @@ void GlobalTypeRewriter::mapTypes(const TypeMap& oldToNewTypes) { #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #include "wasm-delegations-fields.def" diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp index 79e7b83a9be..1d214abdccc 100644 --- a/src/passes/MemoryPacking.cpp +++ b/src/passes/MemoryPacking.cpp @@ -481,13 +481,10 @@ void MemoryPacking::getSegmentReferrers(Module* module, #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index ed3c9ed7ba1..6ceab013209 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -88,13 +88,10 @@ struct ReferenceFinder #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ diff --git a/src/tools/wasm-merge.cpp b/src/tools/wasm-merge.cpp index d3269e8fd10..088317eec6c 100644 --- a/src/tools/wasm-merge.cpp +++ b/src/tools/wasm-merge.cpp @@ -202,13 +202,10 @@ void updateNames(Module& wasm, KindNameUpdates& kindNameUpdates) { #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp index c88a9fd3dbd..5be60c2986d 100644 --- a/src/tools/wasm-metadce.cpp +++ b/src/tools/wasm-metadce.cpp @@ -216,13 +216,10 @@ struct MetaDCEGraph { #define DELEGATE_FIELD_CHILD(id, field) #define DELEGATE_FIELD_OPTIONAL_CHILD(id, field) #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) #define DELEGATE_FIELD_NAME_KIND(id, field, kind) \ diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 57e3a021fe7..1a458bdf7cb 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -383,13 +383,10 @@ struct PostWalker : public Walker { self->maybePushTask(SubType::scan, &cast->field); #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) #define DELEGATE_FIELD_ADDRESS(id, field) diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 9ee7a2a18eb..0877666a498 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -297,6 +297,7 @@ Result<> IRBuilder::visitExpression(Expression* curr) { #define DELEGATE_ID curr->_id #define DELEGATE_START(id) [[maybe_unused]] auto* expr = curr->cast(); +#define DELEGATE_GET_FIELD(id, field) expr->field #define DELEGATE_FIELD_CHILD(id, field) \ auto field = pop(); \ CHECK_ERR(field); \ @@ -315,12 +316,9 @@ Result<> IRBuilder::visitExpression(Expression* curr) { " has child vector " #field); #define DELEGATE_FIELD_INT(id, field) -#define DELEGATE_FIELD_INT_ARRAY(id, field) #define DELEGATE_FIELD_LITERAL(id, field) #define DELEGATE_FIELD_NAME(id, field) -#define DELEGATE_FIELD_NAME_VECTOR(id, field) #define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) -#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) #define DELEGATE_FIELD_TYPE(id, field) #define DELEGATE_FIELD_HEAPTYPE(id, field) From 4c53361b205ad30acc05136388b789296a4180f7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 19 Dec 2023 11:10:27 -0800 Subject: [PATCH 010/553] [EH] Add instructions for new proposal (#6181) This adds basic support for the new instructions in the new EH proposal passed at the Oct CG hybrid CG meeting: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md This mainly adds two instructions: `try_table` and `throw_ref`. This is the bare minimum required to read and write text and binary format, and does not include analyses or optimizations. (It includes some analysis required for validation of existing instructions.) Validation for the new instructions is not yet included. `try_table` faces the same problem with the `resume` instruction in #6083 that without the module-level tag info, we are unable to know the 'sent types' of `try_table`. This solves it with a similar approach taken in #6083: this adds `Module*` parameter to `finalize` methods, which defaults to `nullptr` when not given. The `Module*` parameter is given when called from the binary and text parser, and we cache those tag types in `sentTypes` array within `TryTable` class. In later optimization passes, as long as they don't touch tags, it is fine to call `finalize` without the `Module*`. Refer to https://github.com/WebAssembly/binaryen/pull/6083#issuecomment-1854634679 and #6096 for related discussions when `resume` was added. --- scripts/gen-s-parser.py | 4 +- src/gen-s-parser.inc | 47 +- src/ir/ExpressionAnalyzer.cpp | 2 + src/ir/ExpressionManipulator.cpp | 2 + src/ir/LocalStructuralDominance.cpp | 8 + src/ir/ReFinalize.cpp | 2 + src/ir/branch-utils.h | 14 +- src/ir/cost.h | 5 + src/ir/effects.h | 10 + src/ir/possible-contents.cpp | 5 + src/ir/properties.h | 6 +- src/ir/subtype-exprs.h | 2 + src/parser/parsers.h | 5 + src/passes/Print.cpp | 34 ++ src/passes/TypeGeneralizing.cpp | 2 + src/wasm-binary.h | 12 +- src/wasm-builder.h | 25 + src/wasm-delegations-fields.def | 48 ++ src/wasm-delegations.def | 2 + src/wasm-interpreter.h | 2 + src/wasm-ir-builder.h | 2 + src/wasm-s-parser.h | 3 +- src/wasm-stack.h | 11 + src/wasm.h | 45 ++ src/wasm/parsing.cpp | 5 +- src/wasm/wasm-binary.cpp | 69 ++- src/wasm/wasm-ir-builder.cpp | 4 + src/wasm/wasm-s-parser.cpp | 68 ++- src/wasm/wasm-stack.cpp | 30 +- src/wasm/wasm-validator.cpp | 13 +- src/wasm/wasm.cpp | 41 ++ src/wasm2js.h | 8 + test/binaryen.js/exception-handling.js.txt | 4 +- test/binaryen.js/kitchen-sink.js.txt | 66 +-- test/lit/basic/exception-handling.wast | 651 ++++++++++++++++++++- 35 files changed, 1185 insertions(+), 72 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 0dfe220b5f5..f716302d042 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -554,8 +554,10 @@ # # exception handling instructions ("try", "makeTry(s)"), + ("try_table", "makeTryTable(s)"), ("throw", "makeThrow(s)"), ("rethrow", "makeRethrow(s)"), + ("throw_ref", "makeThrowRef(s)"), # Multivalue pseudoinstructions ("tuple.make", "makeTupleMake(s)"), ("tuple.extract", "makeTupleExtract(s)"), @@ -714,7 +716,7 @@ def instruction_parser(new_parser=False): inst_length = 0 for inst, expr in instructions: if new_parser and inst in {"block", "loop", "if", "try", "then", - "else"}: + "else", "try_table"}: # These are either control flow handled manually or not real # instructions. Skip them. continue diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index bc0a03dd304..2c284d56180 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3393,15 +3393,31 @@ switch (buf[0]) { case 'e': if (op == "then"sv) { return makeThenOrElse(s); } goto parse_error; - case 'r': - if (op == "throw"sv) { return makeThrow(s); } + case 'r': { + switch (buf[5]) { + case '\0': + if (op == "throw"sv) { return makeThrow(s); } + goto parse_error; + case '_': + if (op == "throw_ref"sv) { return makeThrowRef(s); } + goto parse_error; + default: goto parse_error; + } + } + default: goto parse_error; + } + } + case 'r': { + switch (buf[3]) { + case '\0': + if (op == "try"sv) { return makeTry(s); } + goto parse_error; + case '_': + if (op == "try_table"sv) { return makeTryTable(s); } goto parse_error; default: goto parse_error; } } - case 'r': - if (op == "try"sv) { return makeTry(s); } - goto parse_error; case 'u': { switch (buf[6]) { case 'd': @@ -8646,12 +8662,23 @@ switch (buf[0]) { default: goto parse_error; } } - case 'h': - if (op == "throw"sv) { - CHECK_ERR(makeThrow(ctx, pos)); - return Ok{}; + case 'h': { + switch (buf[5]) { + case '\0': + if (op == "throw"sv) { + CHECK_ERR(makeThrow(ctx, pos)); + return Ok{}; + } + goto parse_error; + case '_': + if (op == "throw_ref"sv) { + CHECK_ERR(makeThrowRef(ctx, pos)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 'u': { switch (buf[6]) { case 'd': diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index 62ad3ed3e5c..a75abd6ce9f 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -205,7 +205,9 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left, } #define DELEGATE_FIELD_INT_ARRAY(id, field) COMPARE_LIST(field) +#define DELEGATE_FIELD_INT_VECTOR(id, field) COMPARE_LIST(field) #define DELEGATE_FIELD_NAME_VECTOR(id, field) COMPARE_LIST(field) +#define DELEGATE_FIELD_TYPE_VECTOR(id, field) COMPARE_LIST(field) #define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) \ if (castLeft->field.is() != castRight->field.is()) { \ diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp index 9232dddf269..4cac87a01b1 100644 --- a/src/ir/ExpressionManipulator.cpp +++ b/src/ir/ExpressionManipulator.cpp @@ -94,8 +94,10 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { #define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) COPY_VECTOR(field) #define DELEGATE_FIELD_NAME_VECTOR(id, field) COPY_VECTOR(field) +#define DELEGATE_FIELD_TYPE_VECTOR(id, field) COPY_VECTOR(field) #define DELEGATE_FIELD_INT_ARRAY(id, field) COPY_ARRAY(field) +#define DELEGATE_FIELD_INT_VECTOR(id, field) COPY_VECTOR(field) #include "wasm-delegations-fields.def" diff --git a/src/ir/LocalStructuralDominance.cpp b/src/ir/LocalStructuralDominance.cpp index 183ca7b3fe8..37cd7f4bae6 100644 --- a/src/ir/LocalStructuralDominance.cpp +++ b/src/ir/LocalStructuralDominance.cpp @@ -207,6 +207,14 @@ LocalStructuralDominance::LocalStructuralDominance(Function* func, currp = &curr->cast()->body; continue; } + case Expression::Id::TryTableId: { + self->pushTask(Scanner::doEndScope, currp); + // Just call the task immediately. + doBeginScope(self, currp); + // Immediately continue in the try_table. + currp = &curr->cast()->body; + continue; + } default: { // Control flow structures have been handled. This is an expression, diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 3d74b1422f1..65f5c472463 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -127,8 +127,10 @@ void ReFinalize::visitTableGrow(TableGrow* curr) { curr->finalize(); } void ReFinalize::visitTableFill(TableFill* curr) { curr->finalize(); } void ReFinalize::visitTableCopy(TableCopy* curr) { curr->finalize(); } void ReFinalize::visitTry(Try* curr) { curr->finalize(); } +void ReFinalize::visitTryTable(TryTable* curr) { curr->finalize(); } void ReFinalize::visitThrow(Throw* curr) { curr->finalize(); } void ReFinalize::visitRethrow(Rethrow* curr) { curr->finalize(); } +void ReFinalize::visitThrowRef(ThrowRef* curr) { curr->finalize(); } void ReFinalize::visitNop(Nop* curr) { curr->finalize(); } void ReFinalize::visitUnreachable(Unreachable* curr) { curr->finalize(); } void ReFinalize::visitPop(Pop* curr) { curr->finalize(); } diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h index 9598e283025..3c02757015a 100644 --- a/src/ir/branch-utils.h +++ b/src/ir/branch-utils.h @@ -75,6 +75,13 @@ void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) { func(name, sw->value ? sw->value->type : Type::none); } else if (auto* br = expr->dynCast()) { func(name, br->getSentType()); + } else if (auto* tt = expr->dynCast()) { + for (Index i = 0; i < tt->catchTags.size(); i++) { + auto dest = tt->catchDests[i]; + if (dest == name) { + func(name, tt->sentTypes[i]); + } + } } else { assert(expr->is() || expr->is()); // delegate or rethrow } @@ -82,7 +89,8 @@ void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) { } // Similar to operateOnScopeNameUses, but also passes in the expression that is -// sent if the branch is taken. nullptr is given if there is no value. +// sent if the branch is taken. nullptr is given if there is no value or there +// is a value but it is not known statically. template void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) { operateOnScopeNameUses(expr, [&](Name& name) { @@ -94,6 +102,10 @@ void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) { func(name, sw->value); } else if (auto* br = expr->dynCast()) { func(name, br->ref); + } else if (auto* tt = expr->dynCast()) { + // The values are supplied by throwing instructions, so we are unable to + // know what they will be here. + func(name, nullptr); } else { assert(expr->is() || expr->is()); // delegate or rethrow } diff --git a/src/ir/cost.h b/src/ir/cost.h index d3a48353581..0e87317a624 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -584,6 +584,10 @@ struct CostAnalyzer : public OverriddenVisitor { // We assume no exception will be thrown in most cases return visit(curr->body); } + CostType visitTryTable(TryTable* curr) { + // We assume no exception will be thrown in most cases + return visit(curr->body); + } CostType visitThrow(Throw* curr) { CostType ret = Unacceptable; for (auto* child : curr->operands) { @@ -592,6 +596,7 @@ struct CostAnalyzer : public OverriddenVisitor { return ret; } CostType visitRethrow(Rethrow* curr) { return Unacceptable; } + CostType visitThrowRef(ThrowRef* curr) { return Unacceptable; } CostType visitTupleMake(TupleMake* curr) { CostType ret = 0; for (auto* child : curr->operands) { diff --git a/src/ir/effects.h b/src/ir/effects.h index 0e45ec70c4b..1156cd82350 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -706,6 +706,11 @@ class EffectAnalyzer { parent.delegateTargets.insert(curr->delegateTarget); } } + void visitTryTable(TryTable* curr) { + for (auto name : curr->catchDests) { + parent.breakTargets.insert(name); + } + } void visitThrow(Throw* curr) { if (parent.tryDepth == 0) { parent.throws_ = true; @@ -715,6 +720,11 @@ class EffectAnalyzer { if (parent.tryDepth == 0) { parent.throws_ = true; } + } + void visitThrowRef(ThrowRef* curr) { + if (parent.tryDepth == 0) { + parent.throws_ = true; + } // traps when the arg is null parent.implicitTrap = true; } diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index e7e0cd4fd47..67b33553d55 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1152,6 +1152,10 @@ struct InfoCollector #endif } } + void visitTryTable(TryTable* curr) { + // TODO: optimize when possible + addRoot(curr); + } void visitThrow(Throw* curr) { auto& operands = curr->operands; if (!isRelevant(operands)) { @@ -1165,6 +1169,7 @@ struct InfoCollector } } void visitRethrow(Rethrow* curr) {} + void visitThrowRef(ThrowRef* curr) {} void visitTupleMake(TupleMake* curr) { if (isRelevant(curr->type)) { diff --git a/src/ir/properties.h b/src/ir/properties.h index 914a26919bf..301f15e16ef 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -59,7 +59,7 @@ inline bool isSymmetric(Binary* binary) { inline bool isControlFlowStructure(Expression* curr) { return curr->is() || curr->is() || curr->is() || - curr->is(); + curr->is() || curr->is(); } // Check if an expression is a control flow construct with a name, which implies @@ -475,8 +475,8 @@ inline bool isResultFallthrough(Expression* curr) { // unreachable, for example, but then there is no meaningful answer to give // anyhow. return curr->is() || curr->is() || curr->is() || - curr->is() || curr->is() || curr->is() || curr->is(); } inline bool canEmitSelectWithArms(Expression* ifTrue, Expression* ifFalse) { diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h index dc9ea1432f0..86805f88a7b 100644 --- a/src/ir/subtype-exprs.h +++ b/src/ir/subtype-exprs.h @@ -212,6 +212,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor { self()->noteSubtype(body, curr); } } + void visitTryTable(TryTable* curr) { self()->noteSubtype(curr->body, curr); } void visitThrow(Throw* curr) { Type params = self()->getModule()->getTag(curr->tag)->sig.params; assert(params.size() == curr->operands.size()); @@ -220,6 +221,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor { } } void visitRethrow(Rethrow* curr) {} + void visitThrowRef(ThrowRef* curr) {} void visitTupleMake(TupleMake* curr) {} void visitTupleExtract(TupleExtract* curr) {} void visitRefI31(RefI31* curr) {} diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 54644cafcb2..7f4005c3d2a 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -118,6 +118,7 @@ template Result<> makeTableFill(Ctx&, Index); template Result<> makeTableCopy(Ctx&, Index); template Result<> makeThrow(Ctx&, Index); template Result<> makeRethrow(Ctx&, Index); +template Result<> makeThrowRef(Ctx&, Index); template Result<> makeTupleMake(Ctx&, Index); template Result<> makeTupleExtract(Ctx&, Index); template Result<> makeTupleDrop(Ctx&, Index); @@ -1525,6 +1526,10 @@ template Result<> makeRethrow(Ctx& ctx, Index pos) { return ctx.makeRethrow(pos, *label); } +template Result<> makeThrowRef(Ctx& ctx, Index pos) { + return ctx.in.err("unimplemented instruction"); +} + template Result<> makeTupleMake(Ctx& ctx, Index pos) { auto arity = tupleArity(ctx); CHECK_ERR(arity); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 3feebd1213e..71181566d5e 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -299,6 +299,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor { void visitIf(If* curr); void visitLoop(Loop* curr); void visitTry(Try* curr); + void visitTryTable(TryTable* curr); void maybePrintUnreachableReplacement(Expression* curr, Type type); void maybePrintUnreachableOrNullReplacement(Expression* curr, Type type); void visitCallRef(CallRef* curr) { @@ -1974,6 +1975,25 @@ struct PrintExpressionContents printBlockType(Signature(Type::none, curr->type)); } } + void visitTryTable(TryTable* curr) { + printMedium(o, "try_table"); + if (curr->type.isConcrete()) { + o << ' '; + printBlockType(Signature(Type::none, curr->type)); + } + for (Index i = 0; i < curr->catchTags.size(); i++) { + o << " ("; + if (curr->catchTags[i]) { + printMedium(o, curr->catchRefs[i] ? "catch_ref " : "catch "); + printName(curr->catchTags[i], o); + o << ' '; + } else { + printMedium(o, curr->catchRefs[i] ? "catch_all_ref " : "catch_all "); + } + printName(curr->catchDests[i], o); + o << ')'; + } + } void visitThrow(Throw* curr) { printMedium(o, "throw "); printName(curr->tag, o); @@ -1982,6 +2002,7 @@ struct PrintExpressionContents printMedium(o, "rethrow "); printName(curr->target, o); } + void visitThrowRef(ThrowRef* curr) { printMedium(o, "throw_ref "); } void visitNop(Nop* curr) { printMinor(o, "nop"); } void visitUnreachable(Unreachable* curr) { printMinor(o, "unreachable"); } void visitPop(Pop* curr) { @@ -2728,6 +2749,19 @@ void PrintSExpression::visitTry(Try* curr) { } } +void PrintSExpression::visitTryTable(TryTable* curr) { + controlFlowDepth++; + o << '('; + printExpressionContents(curr); + incIndent(); + maybePrintImplicitBlock(curr->body, true); + decIndent(); + if (full) { + o << " ;; end if"; + } + controlFlowDepth--; +} + void PrintSExpression::maybePrintUnreachableReplacement(Expression* curr, Type type) { // See the parallel function diff --git a/src/passes/TypeGeneralizing.cpp b/src/passes/TypeGeneralizing.cpp index 6b9df651078..d167b89a9f4 100644 --- a/src/passes/TypeGeneralizing.cpp +++ b/src/passes/TypeGeneralizing.cpp @@ -499,8 +499,10 @@ struct TransferFn : OverriddenVisitor { } void visitTry(Try* curr) { WASM_UNREACHABLE("TODO"); } + void visitTryTable(TryTable* curr) { WASM_UNREACHABLE("TODO"); } void visitThrow(Throw* curr) { WASM_UNREACHABLE("TODO"); } void visitRethrow(Rethrow* curr) { WASM_UNREACHABLE("TODO"); } + void visitThrowRef(ThrowRef* curr) { WASM_UNREACHABLE("TODO"); } void visitTupleMake(TupleMake* curr) { WASM_UNREACHABLE("TODO"); } void visitTupleExtract(TupleExtract* curr) { WASM_UNREACHABLE("TODO"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9e68ca33039..84720865ea1 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1170,11 +1170,17 @@ enum ASTNodes { // exception handling opcodes Try = 0x06, - Catch = 0x07, - CatchAll = 0x19, + Catch_P3 = 0x07, // Old Phase 3 'catch' + CatchAll_P3 = 0x19, // Old Phase 3 'catch_all' Delegate = 0x18, Throw = 0x08, Rethrow = 0x09, + TryTable = 0x1f, + Catch = 0x00, + CatchRef = 0x01, + CatchAll = 0x02, + CatchAllRef = 0x03, + ThrowRef = 0x0a, // typed function references opcodes @@ -1909,8 +1915,10 @@ class WasmBinaryReader { void visitTableGet(TableGet* curr); void visitTableSet(TableSet* curr); void visitTryOrTryInBlock(Expression*& out); + void visitTryTable(TryTable* curr); void visitThrow(Throw* curr); void visitRethrow(Rethrow* curr); + void visitThrowRef(ThrowRef* curr); void visitCallRef(CallRef* curr); void visitRefAsCast(RefCast* curr, uint32_t code); void visitRefAs(RefAs* curr, uint8_t code); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 2f379b4e107..fdb489c33ac 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -846,6 +846,31 @@ class Builder { Try* makeTry(Name name, Expression* body, Name delegateTarget, Type type) { return makeTry(name, body, {}, {}, delegateTarget, type, true); } + TryTable* makeTryTable(Expression* body, + const std::vector& catchTags, + const std::vector& catchDests, + const std::vector& catchRefs) { + auto* ret = wasm.allocator.alloc(); + ret->body = body; + ret->catchTags.set(catchTags); + ret->catchDests.set(catchDests); + ret->catchRefs.set(catchRefs); + ret->finalize(&wasm); + return ret; + } + TryTable* makeTryTable(Expression* body, + const std::vector& catchTags, + const std::vector& catchDests, + const std::vector& catchRefs, + Type type) { + auto* ret = wasm.allocator.alloc(); + ret->body = body; + ret->catchTags.set(catchTags); + ret->catchDests.set(catchDests); + ret->catchRefs.set(catchRefs); + ret->finalize(type, &wasm); + return ret; + } Throw* makeThrow(Tag* tag, const std::vector& args) { return makeThrow(tag->name, args); } diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def index d7567b38dcd..3f8072445c0 100644 --- a/src/wasm-delegations-fields.def +++ b/src/wasm-delegations-fields.def @@ -52,6 +52,10 @@ // DELEGATE_FIELD_INT_ARRAY(id, field) - called for a std::array of fixed size // of integer values (like a SIMD mask). If this is not defined, and // DELEGATE_GET_FIELD is, then DELEGATE_FIELD_INT is called on them. + +// DELEGATE_FIELD_INT_VECTOR(id, field) - called for a variable-sized vector +// of integer values. If this is not defined, and DELEGATE_GET_FIELD is, then +// DELEGATE_FIELD_INT is called on them. // // DELEGATE_FIELD_LITERAL(id, field) - called for a Literal. // @@ -85,6 +89,10 @@ // // DELEGATE_FIELD_TYPE(id, field) - called for a Type. // +// DELEGATE_FIELD_TYPE_VECTOR(id, field) - called for a variable-sized vector +// of Types. If this is not defined, and DELEGATE_GET_FIELD is, then +// DELEGATE_FIELD_TYPE is called on them. +// // DELEGATE_FIELD_HEAPTYPE(id, field) - called for a HeapType. // // DELEGATE_FIELD_ADDRESS(id, field) - called for an Address. @@ -131,6 +139,17 @@ #endif #endif +#ifndef DELEGATE_FIELD_INT_VECTOR +#ifdef DELEGATE_GET_FIELD +#define DELEGATE_FIELD_INT_VECTOR(id, field) \ + for (Index i = 0; i < (DELEGATE_GET_FIELD(id, field)).size(); i++) { \ + DELEGATE_FIELD_INT(id, field[i]); \ + } +#else +#error please define DELEGATE_FIELD_INT_VECTOR(id, field) +#endif +#endif + #ifndef DELEGATE_FIELD_LITERAL #error please define DELEGATE_FIELD_LITERAL(id, field) #endif @@ -190,6 +209,17 @@ #error please define DELEGATE_FIELD_TYPE(id, field) #endif +#ifndef DELEGATE_FIELD_TYPE_VECTOR +#ifdef DELEGATE_GET_FIELD +#define DELEGATE_FIELD_TYPE_VECTOR(id, field) \ + for (Index i = 0; i < (DELEGATE_GET_FIELD(id, field)).size(); i++) { \ + DELEGATE_FIELD_TYPE(id, field[i]); \ + } +#else +#error please define DELEGATE_FIELD_TYPE_VECTOR(id, field) +#endif +#endif + #ifndef DELEGATE_FIELD_HEAPTYPE #error please define DELEGATE_FIELD_HEAPTYPE(id, field) #endif @@ -596,6 +626,16 @@ switch (DELEGATE_ID) { DELEGATE_END(Try); break; } + case Expression::Id::TryTableId: { + DELEGATE_START(TryTable); + DELEGATE_FIELD_TYPE_VECTOR(TryTable, sentTypes); + DELEGATE_FIELD_INT_VECTOR(TryTable, catchRefs); + DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(TryTable, catchDests); + DELEGATE_FIELD_NAME_KIND_VECTOR(TryTable, catchTags, ModuleItemKind::Tag); + DELEGATE_FIELD_CHILD(TryTable, body); + DELEGATE_END(TryTable); + break; + } case Expression::Id::ThrowId: { DELEGATE_START(Throw); DELEGATE_FIELD_CHILD_VECTOR(Throw, operands); @@ -609,6 +649,12 @@ switch (DELEGATE_ID) { DELEGATE_END(Rethrow); break; } + case Expression::Id::ThrowRefId: { + DELEGATE_START(ThrowRef); + DELEGATE_FIELD_CHILD(ThrowRef, exnref); + DELEGATE_END(ThrowRef); + break; + } case Expression::Id::NopId: { DELEGATE_START(Nop); DELEGATE_END(Nop); @@ -909,6 +955,7 @@ switch (DELEGATE_ID) { #undef DELEGATE_FIELD_CHILD_VECTOR #undef DELEGATE_FIELD_INT #undef DELEGATE_FIELD_INT_ARRAY +#undef DELEGATE_FIELD_INT_VECTOR #undef DELEGATE_FIELD_LITERAL #undef DELEGATE_FIELD_NAME #undef DELEGATE_FIELD_NAME_VECTOR @@ -918,6 +965,7 @@ switch (DELEGATE_ID) { #undef DELEGATE_FIELD_NAME_KIND #undef DELEGATE_FIELD_NAME_KIND_VECTOR #undef DELEGATE_FIELD_TYPE +#undef DELEGATE_FIELD_TYPE_VECTOR #undef DELEGATE_FIELD_HEAPTYPE #undef DELEGATE_FIELD_ADDRESS #undef DELEGATE_GET_FIELD diff --git a/src/wasm-delegations.def b/src/wasm-delegations.def index 903b19bf798..e486c490fdb 100644 --- a/src/wasm-delegations.def +++ b/src/wasm-delegations.def @@ -65,8 +65,10 @@ DELEGATE(TableGrow); DELEGATE(TableFill); DELEGATE(TableCopy); DELEGATE(Try); +DELEGATE(TryTable); DELEGATE(Throw); DELEGATE(Rethrow); +DELEGATE(ThrowRef); DELEGATE(TupleMake); DELEGATE(TupleExtract); DELEGATE(RefI31); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 3599def9097..eb0a1274abc 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1394,6 +1394,7 @@ class ExpressionRunner : public OverriddenVisitor { Flow visitTableFill(TableFill* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTableCopy(TableCopy* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTry(Try* curr) { WASM_UNREACHABLE("unimp"); } + Flow visitTryTable(TryTable* curr) { WASM_UNREACHABLE("unimp"); } Flow visitThrow(Throw* curr) { NOTE_ENTER("Throw"); Literals arguments; @@ -1411,6 +1412,7 @@ class ExpressionRunner : public OverriddenVisitor { WASM_UNREACHABLE("throw"); } Flow visitRethrow(Rethrow* curr) { WASM_UNREACHABLE("unimp"); } + Flow visitThrowRef(ThrowRef* curr) { WASM_UNREACHABLE("unimp"); } Flow visitRefI31(RefI31* curr) { NOTE_ENTER("RefI31"); Flow flow = visit(curr->value); diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 398cd4f9a02..dcb25efa785 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -155,8 +155,10 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeTableFill(Name table); [[nodiscard]] Result<> makeTableCopy(Name destTable, Name srcTable); [[nodiscard]] Result<> makeTry(Name label, Type type); + // [[nodiscard]] Result<> makeTryTable(); [[nodiscard]] Result<> makeThrow(Name tag); [[nodiscard]] Result<> makeRethrow(Index label); + // [[nodiscard]] Result<> makeThrowRef(); [[nodiscard]] Result<> makeTupleMake(uint32_t arity); [[nodiscard]] Result<> makeTupleExtract(uint32_t arity, uint32_t index); [[nodiscard]] Result<> makeTupleDrop(uint32_t arity); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 446f2a292ef..7921378de4d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -284,9 +284,10 @@ class SExpressionWasmBuilder { Expression* makeTableFill(Element& s); Expression* makeTableCopy(Element& s); Expression* makeTry(Element& s); - Expression* makeTryOrCatchBody(Element& s, Type type, bool isTry); + Expression* makeTryTable(Element& s); Expression* makeThrow(Element& s); Expression* makeRethrow(Element& s); + Expression* makeThrowRef(Element& s); Expression* makeTupleMake(Element& s); Expression* makeTupleExtract(Element& s); Expression* makeTupleDrop(Element& s); diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 1f66212ad81..a195f1a84bd 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -170,6 +170,7 @@ class BinaryenIRWriter : public Visitor> { void visitIf(If* curr); void visitLoop(Loop* curr); void visitTry(Try* curr); + void visitTryTable(TryTable* curr); protected: Function* func = nullptr; @@ -404,6 +405,16 @@ template void BinaryenIRWriter::visitTry(Try* curr) { } } +template +void BinaryenIRWriter::visitTryTable(TryTable* curr) { + emit(curr); + visitPossibleBlockContents(curr->body); + emitScopeEnd(curr); + if (curr->type == Type::unreachable) { + emitUnreachable(); + } +} + // Binaryen IR to binary writer class BinaryenIRToBinaryWriter : public BinaryenIRWriter { diff --git a/src/wasm.h b/src/wasm.h index 1b01278b02c..576a0d0f19d 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -42,6 +42,8 @@ namespace wasm { +class Module; + // An index in a wasm module using Index = uint32_t; @@ -701,8 +703,10 @@ class Expression { TableFillId, TableCopyId, TryId, + TryTableId, ThrowId, RethrowId, + ThrowRefId, TupleMakeId, TupleExtractId, RefI31Id, @@ -1452,6 +1456,7 @@ class TableCopy : public SpecificExpression { void finalize(); }; +// 'try' from the old (Phase 3) EH proposal class Try : public SpecificExpression { public: Try(MixedArena& allocator) : catchTags(allocator), catchBodies(allocator) {} @@ -1471,6 +1476,35 @@ class Try : public SpecificExpression { void finalize(Type type_); }; +// 'try_table' from the new EH proposal +class TryTable : public SpecificExpression { +public: + TryTable(MixedArena& allocator) + : catchTags(allocator), catchDests(allocator), catchRefs(allocator), + sentTypes(allocator) {} + + Expression* body; + + // Tag names. Empty names (Name()) for catch_all and catch_all_ref + ArenaVector catchTags; + // catches' destination blocks + ArenaVector catchDests; + // true for catch_ref and catch_all_ref + ArenaVector catchRefs; + + bool hasCatchAll() const; + + // When 'Module*' parameter is given, we cache catch tags' types into + // 'sentTypes' array, so that the types can be accessed in other analyses + // without accessing the module. + void finalize(Module* wasm = nullptr); + void finalize(Type type_, Module* wasm = nullptr); + + // Caches tags' types in the catch clauses in order not to query the module + // every time we query the sent types + ArenaVector sentTypes; +}; + class Throw : public SpecificExpression { public: Throw(MixedArena& allocator) : operands(allocator) {} @@ -1481,6 +1515,7 @@ class Throw : public SpecificExpression { void finalize(); }; +// 'rethrow' from the old (Phase 3) EH proposal class Rethrow : public SpecificExpression { public: Rethrow(MixedArena& allocator) {} @@ -1490,6 +1525,16 @@ class Rethrow : public SpecificExpression { void finalize(); }; +// 'throw_ref' from the new EH proposal +class ThrowRef : public SpecificExpression { +public: + ThrowRef(MixedArena& allocator) {} + + Expression* exnref; + + void finalize(); +}; + class TupleMake : public SpecificExpression { public: TupleMake(MixedArena& allocator) : operands(allocator) {} diff --git a/src/wasm/parsing.cpp b/src/wasm/parsing.cpp index c6134922a70..1606a2dd1ff 100644 --- a/src/wasm/parsing.cpp +++ b/src/wasm/parsing.cpp @@ -84,10 +84,11 @@ Name UniqueNameMapper::sourceToUnique(Name sName) { return DELEGATE_CALLER_TARGET; } if (labelMappings.find(sName) == labelMappings.end()) { - throw ParseException("bad label in sourceToUnique"); + throw ParseException("bad label in sourceToUnique: " + sName.toString()); } if (labelMappings[sName].empty()) { - throw ParseException("use of popped label in sourceToUnique"); + throw ParseException("use of popped label in sourceToUnique: " + + sName.toString()); } return labelMappings[sName].back(); } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index be1c27d039a..bf14efeb182 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3010,7 +3010,7 @@ void WasmBinaryReader::processExpressions() { } auto peek = input[pos]; if (peek == BinaryConsts::End || peek == BinaryConsts::Else || - peek == BinaryConsts::Catch || peek == BinaryConsts::CatchAll || + peek == BinaryConsts::Catch_P3 || peek == BinaryConsts::CatchAll_P3 || peek == BinaryConsts::Delegate) { BYN_TRACE("== processExpressions finished with unreachable" << std::endl); @@ -3955,8 +3955,8 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { } break; case BinaryConsts::Else: - case BinaryConsts::Catch: - case BinaryConsts::CatchAll: { + case BinaryConsts::Catch_P3: + case BinaryConsts::CatchAll_P3: { curr = nullptr; if (DWARF && currFunction) { assert(!controlFlowStack.empty()); @@ -4014,12 +4014,18 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { case BinaryConsts::Try: visitTryOrTryInBlock(curr); break; + case BinaryConsts::TryTable: + visitTryTable((curr = allocator.alloc())->cast()); + break; case BinaryConsts::Throw: visitThrow((curr = allocator.alloc())->cast()); break; case BinaryConsts::Rethrow: visitRethrow((curr = allocator.alloc())->cast()); break; + case BinaryConsts::ThrowRef: + visitThrowRef((curr = allocator.alloc())->cast()); + break; case BinaryConsts::MemorySize: { auto size = allocator.alloc(); curr = size; @@ -6917,9 +6923,9 @@ void WasmBinaryReader::visitTryOrTryInBlock(Expression*& out) { // here, then do that later. std::vector tagIndexes; - while (lastSeparator == BinaryConsts::Catch || - lastSeparator == BinaryConsts::CatchAll) { - if (lastSeparator == BinaryConsts::Catch) { + while (lastSeparator == BinaryConsts::Catch_P3 || + lastSeparator == BinaryConsts::CatchAll_P3) { + if (lastSeparator == BinaryConsts::Catch_P3) { auto index = getU32LEB(); if (index >= wasm.tags.size()) { throwError("bad tag index"); @@ -7030,6 +7036,51 @@ void WasmBinaryReader::visitTryOrTryInBlock(Expression*& out) { breakTargetNames.erase(catchLabel); } +void WasmBinaryReader::visitTryTable(TryTable* curr) { + BYN_TRACE("zz node: TryTable\n"); + + // For simplicity of implementation, like if scopes, we create a hidden block + // within each try-body, and let branches target those inner blocks instead. + curr->type = getType(); + auto numCatches = getU32LEB(); + // We cannot immediately update tagRefs in the loop below, as catchTags is + // being grown, an so references would get invalidated. Store the indexes + // here, then do that later. + std::vector tagIndexes; + + for (size_t i = 0; i < numCatches; i++) { + uint8_t code = getInt8(); + if (code == BinaryConsts::Catch || code == BinaryConsts::CatchRef) { + auto index = getU32LEB(); + if (index >= wasm.tags.size()) { + throwError("bad tag index"); + } + tagIndexes.push_back(index); + auto* tag = wasm.tags[index].get(); + curr->catchTags.push_back(tag->name); + } else { + tagIndexes.push_back(-1); // unused + curr->catchTags.push_back(Name()); + } + curr->catchDests.push_back(getBreakTarget(getU32LEB()).name); + curr->catchRefs.push_back(code == BinaryConsts::CatchRef || + code == BinaryConsts::CatchAllRef); + } + + for (Index i = 0; i < tagIndexes.size(); i++) { + if (curr->catchTags[i]) { + // We don't know the final name yet. + tagRefs[tagIndexes[i]].push_back(&curr->catchTags[i]); + } + } + + // catch_*** clauses should refer to block labels without entering the try + // scope. So we do this after reading catch clauses. + startControlFlow(curr); + curr->body = getBlockOrSingleton(curr->type); + curr->finalize(curr->type, &wasm); +} + void WasmBinaryReader::visitThrow(Throw* curr) { BYN_TRACE("zz node: Throw\n"); auto index = getU32LEB(); @@ -7058,6 +7109,12 @@ void WasmBinaryReader::visitRethrow(Rethrow* curr) { curr->finalize(); } +void WasmBinaryReader::visitThrowRef(ThrowRef* curr) { + BYN_TRACE("zz node: ThrowRef\n"); + curr->exnref = popNonVoidExpression(); + curr->finalize(); +} + void WasmBinaryReader::visitCallRef(CallRef* curr) { BYN_TRACE("zz node: CallRef\n"); curr->target = popNonVoidExpression(); diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 0877666a498..3cfe0ea30c2 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1337,6 +1337,8 @@ Result<> IRBuilder::makeTry(Name label, Type type) { return visitTryStart(tryy, label); } +// Result<> IRBuilder::makeTryTable() {} + Result<> IRBuilder::makeThrow(Name tag) { Throw curr(wasm.allocator); curr.tag = tag; @@ -1353,6 +1355,8 @@ Result<> IRBuilder::makeRethrow(Index label) { return Ok{}; } +// Result<> IRBuilder::makeThrowRef() {} + Result<> IRBuilder::makeTupleMake(uint32_t arity) { TupleMake curr(wasm.allocator); curr.operands.resize(arity); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 94b434dfba9..49cf1ccfc71 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2794,7 +2794,7 @@ Expression* SExpressionWasmBuilder::makeTry(Element& s) { if (!wasm.getTagOrNull(tag)) { throw SParseException("bad tag name", s, inner); } - ret->catchTags.push_back(getTagName(*inner[1])); + ret->catchTags.push_back(tag); ret->catchBodies.push_back(makeMaybeBlock(inner, 2, type)); } @@ -2837,6 +2837,65 @@ Expression* SExpressionWasmBuilder::makeTry(Element& s) { return ret; } +Expression* SExpressionWasmBuilder::makeTryTable(Element& s) { + auto ret = allocator.alloc(); + Index i = 1; + Name sName; + if (s.size() > i && s[i]->dollared()) { + // the try_table is labeled + sName = s[i++]->str(); + } else { + sName = "try_table"; + } + auto label = nameMapper.pushLabelName(sName); + Type type = parseBlockType(s, i); // signature + + while (i < s.size()) { + Element& inner = *s[i]; + + if (elementStartsWith(inner, "catch") || + elementStartsWith(inner, "catch_ref")) { + bool isRef = elementStartsWith(inner, "catch_ref"); + if (inner.size() < 3) { + throw SParseException("invalid catch/catch_ref block", s, inner); + } + Name tag = getTagName(*inner[1]); + if (!wasm.getTagOrNull(tag)) { + throw SParseException("bad tag name", s, inner); + } + ret->catchTags.push_back(tag); + ret->catchDests.push_back(getLabel(*inner[2])); + ret->catchRefs.push_back(isRef); + } else if (elementStartsWith(inner, "catch_all") || + elementStartsWith(inner, "catch_all_ref")) { + bool isRef = elementStartsWith(inner, "catch_all_ref"); + if (inner.size() < 2) { + throw SParseException( + "invalid catch_all/catch_all_ref block", s, inner); + } + ret->catchTags.push_back(Name()); + ret->catchDests.push_back(getLabel(*inner[1])); + ret->catchRefs.push_back(isRef); + } else { + break; + } + i++; + } + + ret->body = makeMaybeBlock(s, i, type); + ret->finalize(type, &wasm); + nameMapper.popLabelName(label); + // create a break target if we must + if (BranchUtils::BranchSeeker::has(ret, label)) { + auto* block = allocator.alloc(); + block->name = label; + block->list.push_back(ret); + block->finalize(type); + return block; + } + return ret; +} + Expression* SExpressionWasmBuilder::makeThrow(Element& s) { auto ret = allocator.alloc(); Index i = 1; @@ -2859,6 +2918,13 @@ Expression* SExpressionWasmBuilder::makeRethrow(Element& s) { return ret; } +Expression* SExpressionWasmBuilder::makeThrowRef(Element& s) { + auto ret = allocator.alloc(); + ret->exnref = parseExpression(s[1]); + ret->finalize(); + return ret; +} + Expression* SExpressionWasmBuilder::makeTupleMake(Element& s) { auto ret = allocator.alloc(); size_t arity = std::stoll(s[1]->toString()); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 0f8facfd510..3b14b3c35ba 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -16,6 +16,7 @@ #include "wasm-stack.h" #include "ir/find_all.h" +#include "wasm-binary.h" #include "wasm-debug.h" namespace wasm { @@ -1953,11 +1954,32 @@ void BinaryInstWriter::visitTry(Try* curr) { emitResultType(curr->type); } +void BinaryInstWriter::visitTryTable(TryTable* curr) { + o << int8_t(BinaryConsts::TryTable); + emitResultType(curr->type); + o << U32LEB(curr->catchTags.size()); + for (Index i = 0; i < curr->catchTags.size(); i++) { + if (curr->catchTags[i]) { + o << (curr->catchRefs[i] ? int8_t(BinaryConsts::CatchRef) + : int8_t(BinaryConsts::Catch)); + o << U32LEB(parent.getTagIndex(curr->catchTags[i])); + } else { + o << (curr->catchRefs[i] ? int8_t(BinaryConsts::CatchAllRef) + : int8_t(BinaryConsts::CatchAll)); + } + o << U32LEB(getBreakIndex(curr->catchDests[i])); + } + // the binary format requires this; we have a block if we need one + // catch_*** clauses should refer to block labels without entering the try + // scope. So we do this at the end. + breakStack.emplace_back(IMPOSSIBLE_CONTINUE); +} + void BinaryInstWriter::emitCatch(Try* curr, Index i) { if (func && !sourceMap) { parent.writeExtraDebugLocation(curr, func, i); } - o << int8_t(BinaryConsts::Catch) + o << int8_t(BinaryConsts::Catch_P3) << U32LEB(parent.getTagIndex(curr->catchTags[i])); } @@ -1965,7 +1987,7 @@ void BinaryInstWriter::emitCatchAll(Try* curr) { if (func && !sourceMap) { parent.writeExtraDebugLocation(curr, func, curr->catchBodies.size()); } - o << int8_t(BinaryConsts::CatchAll); + o << int8_t(BinaryConsts::CatchAll_P3); } void BinaryInstWriter::emitDelegate(Try* curr) { @@ -1986,6 +2008,10 @@ void BinaryInstWriter::visitRethrow(Rethrow* curr) { o << int8_t(BinaryConsts::Rethrow) << U32LEB(getBreakIndex(curr->target)); } +void BinaryInstWriter::visitThrowRef(ThrowRef* curr) { + o << int8_t(BinaryConsts::ThrowRef); +} + void BinaryInstWriter::visitNop(Nop* curr) { o << int8_t(BinaryConsts::Nop); } void BinaryInstWriter::visitUnreachable(Unreachable* curr) { diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index cb54e1597d4..c1b4a86e78d 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -354,7 +354,8 @@ struct FunctionValidator : public WalkerPass> { case Expression::ReturnId: case Expression::UnreachableId: case Expression::ThrowId: - case Expression::RethrowId: { + case Expression::RethrowId: + case Expression::ThrowRefId: { // These can all be unreachable without an unreachable child. return; } @@ -445,8 +446,10 @@ struct FunctionValidator : public WalkerPass> { void noteDelegate(Name name, Expression* curr); void noteRethrow(Name name, Expression* curr); void visitTry(Try* curr); + void visitTryTable(TryTable* curr); void visitThrow(Throw* curr); void visitRethrow(Rethrow* curr); + void visitThrowRef(ThrowRef* curr); void visitTupleMake(TupleMake* curr); void visitTupleExtract(TupleExtract* curr); void visitCallRef(CallRef* curr); @@ -2442,6 +2445,10 @@ void FunctionValidator::visitTry(Try* curr) { rethrowTargetNames.erase(curr->name); } +void FunctionValidator::visitTryTable(TryTable* curr) { + // TODO +} + void FunctionValidator::visitThrow(Throw* curr) { shouldBeTrue( getModule()->features.hasExceptionHandling(), @@ -2516,6 +2523,10 @@ void FunctionValidator::visitTupleMake(TupleMake* curr) { "Type of tuple.make does not match types of its operands"); } +void FunctionValidator::visitThrowRef(ThrowRef* curr) { + // TODO +} + void FunctionValidator::visitTupleExtract(TupleExtract* curr) { shouldBeTrue(getModule()->features.hasMultivalue(), curr, diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 8ff2dc978aa..6589ca06984 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -900,6 +900,47 @@ void Throw::finalize() { type = Type::unreachable; } void Rethrow::finalize() { type = Type::unreachable; } +void ThrowRef::finalize() { type = Type::unreachable; } + +bool TryTable::hasCatchAll() const { + return std::any_of( + catchTags.begin(), catchTags.end(), [](Name t) { return !t; }); +} + +static void populateTryTableSentTypes(TryTable* curr, Module* wasm) { + if (!wasm) { + return; + } + curr->sentTypes.clear(); + Type exnref = Type(HeapType::exn, Nullable); + for (Index i = 0; i < curr->catchTags.size(); i++) { + auto tagName = curr->catchTags[i]; + std::vector sentType; + if (tagName) { + for (auto t : wasm->getTag(tagName)->sig.params) { + sentType.push_back(t); + } + } + if (curr->catchRefs[i]) { + sentType.push_back(exnref); + } + curr->sentTypes.push_back(sentType.empty() ? Type::none : Type(sentType)); + } +} + +void TryTable::finalize(Module* wasm) { + type = body->type; + populateTryTableSentTypes(this, wasm); +} + +void TryTable::finalize(Type type_, Module* wasm) { + type = type_; + if (type == Type::none && body->type == Type::unreachable) { + type = Type::unreachable; + } + populateTryTableSentTypes(this, wasm); +} + void TupleMake::finalize() { std::vector types; types.reserve(operands.size()); diff --git a/src/wasm2js.h b/src/wasm2js.h index 4aef8c3789a..c3f3b5fa60d 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -2263,6 +2263,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, unimplemented(curr); WASM_UNREACHABLE("unimp"); } + Ref visitTryTable(TryTable* curr) { + unimplemented(curr); + WASM_UNREACHABLE("unimp"); + } Ref visitThrow(Throw* curr) { unimplemented(curr); WASM_UNREACHABLE("unimp"); @@ -2271,6 +2275,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, unimplemented(curr); WASM_UNREACHABLE("unimp"); } + Ref visitThrowRef(ThrowRef* curr) { + unimplemented(curr); + WASM_UNREACHABLE("unimp"); + } Ref visitPop(Pop* curr) { unimplemented(curr); WASM_UNREACHABLE("unimp"); diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt index 062f05202d6..d2a0c6dd62f 100644 --- a/test/binaryen.js/exception-handling.js.txt +++ b/test/binaryen.js/exception-handling.js.txt @@ -34,7 +34,7 @@ ) ) -getExpressionInfo(throw) = {"id":52,"type":1,"tag":"e"} -getExpressionInfo(rethrow) = {"id":53,"type":1,"target":"l0"} +getExpressionInfo(throw) = {"id":53,"type":1,"tag":"e"} +getExpressionInfo(rethrow) = {"id":54,"type":1,"target":"l0"} getExpressionInfo(try_catch) = {"id":51,"type":1,"name":"l0","hasCatchAll":0,"delegateTarget":"","isDelegate":0} getExpressionInfo(try_delegate) = {"id":51,"type":0,"name":"try_outer","hasCatchAll":1,"delegateTarget":"","isDelegate":0} diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index c3513b6ba7d..168bc00733f 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -83,39 +83,39 @@ TableSetId: 46 TableSizeId: 47 TableGrowId: 48 TryId: 51 -ThrowId: 52 -RethrowId: 53 -TupleMakeId: 54 -TupleExtractId: 55 -RefI31Id: 56 -I31GetId: 57 -CallRefId: 58 -RefTestId: 59 -RefCastId: 60 -BrOnId: 61 -StructNewId: 62 -StructGetId: 63 -StructSetId: 64 -ArrayNewId: 65 -ArrayNewFixedId: 68 -ArrayGetId: 69 -ArraySetId: 70 -ArrayLenId: 71 -ArrayCopy: 72 -RefAs: 76 -StringNew: 77 -StringConst: 78 -StringMeasure: 79 -StringEncode: 80 -StringConcat: 81 -StringEq: 82 -StringAs: 83 -StringWTF8Advance: 84 -StringWTF16Get: 85 -StringIterNext: 86 -StringIterMove: 87 -StringSliceWTF: 88 -StringSliceIter: 89 +ThrowId: 53 +RethrowId: 54 +TupleMakeId: 56 +TupleExtractId: 57 +RefI31Id: 58 +I31GetId: 59 +CallRefId: 60 +RefTestId: 61 +RefCastId: 62 +BrOnId: 63 +StructNewId: 64 +StructGetId: 65 +StructSetId: 66 +ArrayNewId: 67 +ArrayNewFixedId: 70 +ArrayGetId: 71 +ArraySetId: 72 +ArrayLenId: 73 +ArrayCopy: 74 +RefAs: 78 +StringNew: 79 +StringConst: 80 +StringMeasure: 81 +StringEncode: 82 +StringConcat: 83 +StringEq: 84 +StringAs: 85 +StringWTF8Advance: 86 +StringWTF16Get: 87 +StringIterNext: 88 +StringIterMove: 89 +StringSliceWTF: 90 +StringSliceIter: 91 getExpressionInfo={"id":15,"type":4,"op":6} (f32.neg (f32.const -33.61199951171875) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index 945cca1af83..a06e377e666 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -10,9 +10,71 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module - ;; CHECK-TEXT: (type $0 (func (result exnref))) + ;; CHECK-TEXT: (type $0 (func)) - ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $0) (result exnref) + ;; CHECK-TEXT: (type $1 (func (result exnref))) + + ;; CHECK-TEXT: (type $2 (func (result i32))) + + ;; CHECK-TEXT: (type $3 (func (result i32 i64))) + + ;; CHECK-TEXT: (type $4 (func (result i32 i64 exnref))) + + ;; CHECK-TEXT: (type $5 (func (result i32 exnref))) + + ;; CHECK-TEXT: (type $6 (func (param i32))) + + ;; CHECK-TEXT: (type $7 (func (param i64))) + + ;; CHECK-TEXT: (type $8 (func (param i32 i64))) + + ;; CHECK-TEXT: (type $9 (func (param eqref))) + + ;; CHECK-TEXT: (tag $e-i32 (param i32)) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (type $1 (func (result exnref))) + + ;; CHECK-BIN: (type $2 (func (result i32))) + + ;; CHECK-BIN: (type $3 (func (result i32 i64))) + + ;; CHECK-BIN: (type $4 (func (result i32 i64 exnref))) + + ;; CHECK-BIN: (type $5 (func (result i32 exnref))) + + ;; CHECK-BIN: (type $6 (func (param i32))) + + ;; CHECK-BIN: (type $7 (func (param i64))) + + ;; CHECK-BIN: (type $8 (func (param i32 i64))) + + ;; CHECK-BIN: (type $9 (func (param eqref))) + + ;; CHECK-BIN: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + ;; CHECK-TEXT: (tag $e-i64 (param i64)) + ;; CHECK-BIN: (tag $e-i64 (param i64)) + (tag $e-i64 (param i64)) + ;; CHECK-TEXT: (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-BIN: (tag $e-i32-i64 (param i32 i64)) + (tag $e-i32-i64 (param i32 i64)) + ;; CHECK-TEXT: (tag $e-eqref (param eqref)) + ;; CHECK-BIN: (tag $e-eqref (param eqref)) + (tag $e-eqref (param (ref null eq))) + ;; CHECK-TEXT: (tag $e-empty) + ;; CHECK-BIN: (tag $e-empty) + (tag $e-empty) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $foo (type $0) + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + (func $foo) + + ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $1) (result exnref) ;; CHECK-TEXT-NEXT: (local $exn exnref) ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) ;; CHECK-TEXT-NEXT: (if (result exnref) @@ -25,9 +87,7 @@ ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (type $0 (func (result exnref))) - - ;; CHECK-BIN: (func $exnref-nullexnref-test (type $0) (result exnref) + ;; CHECK-BIN: (func $exnref-nullexnref-test (type $1) (result exnref) ;; CHECK-BIN-NEXT: (local $exn exnref) ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) ;; CHECK-BIN-NEXT: (if (result exnref) @@ -51,10 +111,413 @@ (local.get $exn) ) ) + + ;; CHECK-TEXT: (func $catchless-try-table (type $0) + ;; CHECK-TEXT-NEXT: (try_table + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (try_table + ;; CHECK-TEXT-NEXT: (throw $e-empty) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $catchless-try-table (type $0) + ;; CHECK-BIN-NEXT: (try_table + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (try_table + ;; CHECK-BIN-NEXT: (throw $e-empty) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $catchless-try-table + (try_table) + (try_table + (throw $e-empty) + ) + ) + + ;; CHECK-TEXT: (func $simple-try-table-and-throw (type $2) (result i32) + ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch) + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $simple-try-table-and-throw (type $2) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$1) + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $simple-try-table-and-throw (result i32) + (block $l-catch (result i32) + (try_table (catch $e-i32 $l-catch) + (throw $e-i32 (i32.const 0)) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-and-throw-ref (type $0) + ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) + ;; CHECK-TEXT-NEXT: (try_table (catch_all_ref $l-catch-all-ref) + ;; CHECK-TEXT-NEXT: (throw $e-i64 + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-and-throw-ref (type $0) + ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (block $label$1 (result exnref) + ;; CHECK-BIN-NEXT: (try_table (catch_all_ref $label$1) + ;; CHECK-BIN-NEXT: (throw $e-i64 + ;; CHECK-BIN-NEXT: (i64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-and-throw-ref + (throw_ref + (block $l-catch-all-ref (result exnref) + (try_table (catch_all_ref $l-catch-all-ref) + (throw $e-i64 (i64.const 0)) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-multivalue-tag (type $0) + ;; CHECK-TEXT-NEXT: (block $outer + ;; CHECK-TEXT-NEXT: (tuple.drop 3 + ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $4) (result i32 i64 exnref) + ;; CHECK-TEXT-NEXT: (tuple.drop 2 + ;; CHECK-TEXT-NEXT: (block $l-catch (type $3) (result i32 i64) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32-i64 $l-catch) (catch_ref $e-i32-i64 $l-catch-ref) + ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (i64.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-multivalue-tag (type $0) + ;; CHECK-BIN-NEXT: (local $0 (i32 i64)) + ;; CHECK-BIN-NEXT: (local $1 i32) + ;; CHECK-BIN-NEXT: (local $2 (i32 i64 exnref)) + ;; CHECK-BIN-NEXT: (local $3 i64) + ;; CHECK-BIN-NEXT: (local $4 i32) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (local.set $2 + ;; CHECK-BIN-NEXT: (block $label$2 (type $4) (result i32 i64 exnref) + ;; CHECK-BIN-NEXT: (local.set $0 + ;; CHECK-BIN-NEXT: (block $label$3 (type $3) (result i32 i64) + ;; CHECK-BIN-NEXT: (try_table (catch $e-i32-i64 $label$3) (catch_ref $e-i32-i64 $label$2) + ;; CHECK-BIN-NEXT: (throw $e-i32-i64 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (i64.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $4 + ;; CHECK-BIN-NEXT: (tuple.extract 3 0 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i64) + ;; CHECK-BIN-NEXT: (local.set $3 + ;; CHECK-BIN-NEXT: (tuple.extract 3 1 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (tuple.extract 3 2 + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-multivalue-tag + (block $outer + (tuple.drop 3 + (block $l-catch-ref (result i32 i64 exnref) + (tuple.drop 2 + (block $l-catch (result i32 i64) + (try_table (catch $e-i32-i64 $l-catch) + (catch_ref $e-i32-i64 $l-catch-ref) + (throw $e-i32-i64 (i32.const 0) (i64.const 0)) + ) + ) + ) + (br $outer) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-all-catch-clauses (type $0) + ;; CHECK-TEXT-NEXT: (block $outer + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) + ;; CHECK-TEXT-NEXT: (tuple.drop 2 + ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $5) (result i32 exnref) + ;; CHECK-TEXT-NEXT: (block $l-catch-all + ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch) (catch_ref $e-i32 $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-all-catch-clauses (type $0) + ;; CHECK-BIN-NEXT: (local $0 (i32 exnref)) + ;; CHECK-BIN-NEXT: (local $1 i32) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$2 (result i32) + ;; CHECK-BIN-NEXT: (local.set $0 + ;; CHECK-BIN-NEXT: (block $label$3 (type $5) (result i32 exnref) + ;; CHECK-BIN-NEXT: (block $label$4 + ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) + ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$2) (catch_ref $e-i32 $label$3) (catch_all $label$4) (catch_all_ref $label$5) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-all-catch-clauses + (block $outer + (drop + (block $l-catch (result i32) + (tuple.drop 2 + (block $l-catch-ref (result i32 exnref) + (block $l-catch-all + (throw_ref + (block $l-catch-all-ref (result exnref) + (try_table (catch $e-i32 $l-catch) + (catch_ref $e-i32 $l-catch-ref) + (catch_all $l-catch-all) + (catch_all_ref $l-catch-all-ref) + (call $foo) + (call $foo) + ) + (br $outer) + ) + ) + ) + (br $outer) + ) + ) + (br $outer) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-with-label-and-br (type $2) (result i32) + ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) + ;; CHECK-TEXT-NEXT: (block $l (result i32) + ;; CHECK-TEXT-NEXT: (try_table (result i32) (catch $e-i32 $l-catch) + ;; CHECK-TEXT-NEXT: (br $l + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-with-label-and-br (type $2) (result i32) + ;; CHECK-BIN-NEXT: (block $label$1 (result i32) + ;; CHECK-BIN-NEXT: (block $label$2 (result i32) + ;; CHECK-BIN-NEXT: (try_table (result i32) (catch $e-i32 $label$1) + ;; CHECK-BIN-NEXT: (br $label$2 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-with-label-and-br (result i32) + (block $l-catch (result i32) + (try_table $l (result i32) (catch $e-i32 $l-catch) + (br $l (i32.const 0)) + ) + ) + ) + + ;; CHECK-TEXT: (func $nested-try-table (type $1) (result exnref) + ;; CHECK-TEXT-NEXT: (block $l-catch-outer (result exnref) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l-catch-inner (result i32) + ;; CHECK-TEXT-NEXT: (try_table (catch_all_ref $l-catch-outer) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch-inner) + ;; CHECK-TEXT-NEXT: (if + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (throw $e-eqref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null noexn) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $nested-try-table (type $1) (result exnref) + ;; CHECK-BIN-NEXT: (block $label$1 (result exnref) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$2 (result i32) + ;; CHECK-BIN-NEXT: (try_table (catch_all_ref $label$1) + ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$2) + ;; CHECK-BIN-NEXT: (if + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (throw $e-eqref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null noexn) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $nested-try-table (result exnref) + (block $l-catch-outer (result exnref) + (drop + (block $l-catch-inner (result i32) + (try_table (catch_all_ref $l-catch-outer) + (try_table (catch $e-i32 $l-catch-inner) + (if + (i32.const 0) + (throw $e-i32 (i32.const 3)) + (throw $e-eqref (ref.null eq)) + ) + ) + ) + ) + ) + (ref.null noexn) + ) + ) ) -;; CHECK-BIN-NODEBUG: (type $0 (func (result exnref))) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (type $1 (func (result exnref))) + +;; CHECK-BIN-NODEBUG: (type $2 (func (result i32))) + +;; CHECK-BIN-NODEBUG: (type $3 (func (result i32 i64))) + +;; CHECK-BIN-NODEBUG: (type $4 (func (result i32 i64 exnref))) + +;; CHECK-BIN-NODEBUG: (type $5 (func (result i32 exnref))) + +;; CHECK-BIN-NODEBUG: (type $6 (func (param i32))) + +;; CHECK-BIN-NODEBUG: (type $7 (func (param i64))) + +;; CHECK-BIN-NODEBUG: (type $8 (func (param i32 i64))) + +;; CHECK-BIN-NODEBUG: (type $9 (func (param eqref))) + +;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + +;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i64)) -;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result exnref) +;; CHECK-BIN-NODEBUG: (tag $tag$2 (param i32 i64)) + +;; CHECK-BIN-NODEBUG: (tag $tag$3 (param eqref)) + +;; CHECK-BIN-NODEBUG: (tag $tag$4) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) ;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) @@ -67,3 +530,177 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (try_table +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (try_table +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $2) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$1) +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch_all_ref $label$1) +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$1 +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 (i32 i64)) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 (i32 i64 exnref)) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $4 i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (type $4) (result i32 i64 exnref) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $3) (result i32 i64) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$2 $label$3) (catch_ref $tag$2 $label$2) +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (i64.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $4 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 (i32 exnref)) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $5) (result i32 exnref) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$2) (catch_ref $tag$0 $label$3) (catch_all $label$4) (catch_all_ref $label$5) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $2) (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (result i32) (catch $tag$0 $label$1) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $1) (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch_all_ref $label$1) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$2) +;; CHECK-BIN-NODEBUG-NEXT: (if +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$3 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null noexn) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) From eb5666eeb0a2b74314e1aaf27e57193cb8fd4a99 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 19 Dec 2023 13:30:43 -0800 Subject: [PATCH 011/553] Add tuple.drop validation (#6186) Without this fuzzer testcases fail if the initial content has a tuple.drop but multivalue is disabled (then the initial content validates erroneously, and that content is remixed into more content using multivalue which fails to validate). --- src/wasm/wasm-validator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index c1b4a86e78d..8c165b70042 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2123,6 +2123,11 @@ void FunctionValidator::visitDrop(Drop* curr) { curr->value->type == Type::unreachable, curr, "can only drop a valid value"); + if (curr->value->type.isTuple()) { + shouldBeTrue(getModule()->features.hasMultivalue(), + curr, + "Tuples drops are not allowed unless multivalue is enabled"); + } } void FunctionValidator::visitReturn(Return* curr) { From 11e3af054a1fd137a892499ee0d5813f6c15d07e Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 20 Dec 2023 10:48:42 -0800 Subject: [PATCH 012/553] [EH] Add validation for new instructions (#6185) This adds validation for the new EH instructions (`try_table` and `throw_ref`): https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md This also adds a spec test for checking invalid modules. We cannot check the executions yet because we don't have the interpreter implementation. The new test file also contains tests for the existing `throw`, because this is meant to replace the old spec test someday. --- src/wasm/wasm-validator.cpp | 83 +++++++++++++++++++++++++++++-- test/spec/exception-handling.wast | 64 ++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 test/spec/exception-handling.wast diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 8c165b70042..7ea8b0bdb4b 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2451,7 +2451,75 @@ void FunctionValidator::visitTry(Try* curr) { } void FunctionValidator::visitTryTable(TryTable* curr) { - // TODO + shouldBeTrue( + getModule()->features.hasExceptionHandling(), + curr, + "try_table requires exception-handling [--enable-exception-handling]"); + if (curr->type != Type::unreachable) { + shouldBeSubType(curr->body->type, + curr->type, + curr->body, + "try_table's type does not match try_table body's type"); + } + + shouldBeEqual(curr->catchTags.size(), + curr->catchDests.size(), + curr, + "the number of catch tags and catch destinations do not match"); + shouldBeEqual(curr->catchTags.size(), + curr->catchRefs.size(), + curr, + "the number of catch tags and catch refs do not match"); + shouldBeEqual(curr->catchTags.size(), + curr->sentTypes.size(), + curr, + "the number of catch tags and sent types do not match"); + + const char* invalidSentTypeMsg = "invalid catch sent type information"; + Type exnref = Type(HeapType::exn, Nullable); + for (Index i = 0; i < curr->catchTags.size(); i++) { + auto sentType = curr->sentTypes[i]; + size_t tagTypeSize; + + Name tagName = curr->catchTags[i]; + if (!tagName) { // catch_all or catch_all_ref + tagTypeSize = 0; + } else { // catch or catch_ref + // Check tag validity + auto* tag = getModule()->getTagOrNull(tagName); + if (!shouldBeTrue(tag != nullptr, curr, "")) { + getStream() << "catch's tag name is invalid: " << tagName << "\n"; + } else if (!shouldBeEqual(tag->sig.results, Type(Type::none), curr, "")) { + getStream() + << "catch's tag (" << tagName + << ") has result values, which is not allowed for exception handling"; + } + + // tagType and sentType should be the same (except for the possible exnref + // at the end of sentType) + auto tagType = tag->sig.params; + tagTypeSize = tagType.size(); + for (Index j = 0; j < tagType.size(); j++) { + shouldBeEqual(tagType[j], sentType[j], curr, invalidSentTypeMsg); + } + } + + // If this is catch_ref or catch_all_ref, sentType.size() should be + // tagType.size() + 1 because there is an exrnef tacked at the end. If + // this is catch/catch_all, the two sizes should be the same. + if (curr->catchRefs[i]) { + if (shouldBeTrue( + sentType.size() == tagTypeSize + 1, curr, invalidSentTypeMsg)) { + shouldBeEqual( + sentType[sentType.size() - 1], exnref, curr, invalidSentTypeMsg); + } + } else { + shouldBeTrue(sentType.size() == tagTypeSize, curr, invalidSentTypeMsg); + } + + // Note catch destinations with sent types + noteBreak(curr->catchDests[i], curr->sentTypes[i], curr); + } } void FunctionValidator::visitThrow(Throw* curr) { @@ -2475,9 +2543,10 @@ void FunctionValidator::visitThrow(Throw* curr) { Type(Type::none), curr, "tags with result types must not be used for exception handling"); - if (!shouldBeTrue(curr->operands.size() == tag->sig.params.size(), - curr, - "tag's param numbers must match")) { + if (!shouldBeEqual(curr->operands.size(), + tag->sig.params.size(), + curr, + "tag's param numbers must match")) { return; } size_t i = 0; @@ -2529,7 +2598,11 @@ void FunctionValidator::visitTupleMake(TupleMake* curr) { } void FunctionValidator::visitThrowRef(ThrowRef* curr) { - // TODO + Type exnref = Type(HeapType::exn, Nullable); + shouldBeSubType(curr->exnref->type, + exnref, + curr, + "throw_ref's argument should be a subtype of exnref"); } void FunctionValidator::visitTupleExtract(TupleExtract* curr) { diff --git a/test/spec/exception-handling.wast b/test/spec/exception-handling.wast new file mode 100644 index 00000000000..95350b77b80 --- /dev/null +++ b/test/spec/exception-handling.wast @@ -0,0 +1,64 @@ +(assert_invalid + (module + (tag $e-i32 (param i32)) + (func $f0 + (try_table + (i32.const 0) + ) + ) + ) + "try_table's type does not match try_table body's type" +) + +(assert_invalid + (module + (tag $e-i32 (param i32)) + (func $f0 + (throw $e-i32 (f32.const 0)) + ) + ) + "tag param types must match" +) + +(assert_invalid + (module + (tag $e-i32 (param i32 f32)) + (func $f0 + (throw $e-i32 (f32.const 0)) + ) + ) + "tag's param numbers must match" +) + +(assert_invalid + (module + (func $f0 + (block $l + (try_table (catch $e $l)) + ) + ) + ) + "catch's tag name is invalid: e" +) + +(assert_invalid + (module + (tag $e (param i32) (result i32)) + (func $f0 + (throw $e (i32.const 5)) + ) + ) + "tags with result types must not be used for exception handling" +) + +(assert_invalid + (module + (tag $e (param i32) (result i32)) + (func $f0 + (block $l + (try_table (catch $e $l)) + ) + ) + ) + "catch's tag (e) has result values, which is not allowed for exception handling" +) From a5235cb51df4853220e8cb3fc6103143afd5db7f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 20 Dec 2023 10:53:58 -0800 Subject: [PATCH 013/553] [NFC] Fix typo in Inlining (#6187) --- src/passes/Inlining.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 2f48ff29920..3ae63face6c 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -765,8 +765,8 @@ struct FunctionSplitter { return InliningMode::Uninlineable; } } else { - // This is an if without an else, and so the type is either none of - // unreachable; + // This is an if without an else, and so the type is either none or + // unreachable, and we ruled out none before. assert(iff->ifTrue->type == Type::unreachable); } } From 2b81d39e133ff443c09837c7b0bf77e661d15345 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 20 Dec 2023 11:58:11 -0800 Subject: [PATCH 014/553] [EH][test] Add a few more tests (#6189) This adds tests that test all four kinds of `catch` clauses for an empty tag and a multivalue tag. (Previously we had this test only for an `i32` tag.) --- test/lit/basic/exception-handling.wast | 364 ++++++++++++++++++++++--- 1 file changed, 331 insertions(+), 33 deletions(-) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index a06e377e666..cf0e8a62e70 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -12,13 +12,13 @@ (module ;; CHECK-TEXT: (type $0 (func)) - ;; CHECK-TEXT: (type $1 (func (result exnref))) + ;; CHECK-TEXT: (type $1 (func (result i32 i64))) - ;; CHECK-TEXT: (type $2 (func (result i32))) + ;; CHECK-TEXT: (type $2 (func (result i32 i64 exnref))) - ;; CHECK-TEXT: (type $3 (func (result i32 i64))) + ;; CHECK-TEXT: (type $3 (func (result exnref))) - ;; CHECK-TEXT: (type $4 (func (result i32 i64 exnref))) + ;; CHECK-TEXT: (type $4 (func (result i32))) ;; CHECK-TEXT: (type $5 (func (result i32 exnref))) @@ -33,13 +33,13 @@ ;; CHECK-TEXT: (tag $e-i32 (param i32)) ;; CHECK-BIN: (type $0 (func)) - ;; CHECK-BIN: (type $1 (func (result exnref))) + ;; CHECK-BIN: (type $1 (func (result i32 i64))) - ;; CHECK-BIN: (type $2 (func (result i32))) + ;; CHECK-BIN: (type $2 (func (result i32 i64 exnref))) - ;; CHECK-BIN: (type $3 (func (result i32 i64))) + ;; CHECK-BIN: (type $3 (func (result exnref))) - ;; CHECK-BIN: (type $4 (func (result i32 i64 exnref))) + ;; CHECK-BIN: (type $4 (func (result i32))) ;; CHECK-BIN: (type $5 (func (result i32 exnref))) @@ -74,7 +74,7 @@ ;; CHECK-BIN-NEXT: ) (func $foo) - ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $1) (result exnref) + ;; CHECK-TEXT: (func $exnref-nullexnref-test (type $3) (result exnref) ;; CHECK-TEXT-NEXT: (local $exn exnref) ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) ;; CHECK-TEXT-NEXT: (if (result exnref) @@ -87,7 +87,7 @@ ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $exnref-nullexnref-test (type $1) (result exnref) + ;; CHECK-BIN: (func $exnref-nullexnref-test (type $3) (result exnref) ;; CHECK-BIN-NEXT: (local $exn exnref) ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) ;; CHECK-BIN-NEXT: (if (result exnref) @@ -135,7 +135,7 @@ ) ) - ;; CHECK-TEXT: (func $simple-try-table-and-throw (type $2) (result i32) + ;; CHECK-TEXT: (func $simple-try-table-and-throw (type $4) (result i32) ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch) ;; CHECK-TEXT-NEXT: (throw $e-i32 @@ -144,7 +144,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $simple-try-table-and-throw (type $2) (result i32) + ;; CHECK-BIN: (func $simple-try-table-and-throw (type $4) (result i32) ;; CHECK-BIN-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$1) ;; CHECK-BIN-NEXT: (throw $e-i32 @@ -196,9 +196,9 @@ ;; CHECK-TEXT: (func $try-table-multivalue-tag (type $0) ;; CHECK-TEXT-NEXT: (block $outer ;; CHECK-TEXT-NEXT: (tuple.drop 3 - ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $4) (result i32 i64 exnref) + ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $2) (result i32 i64 exnref) ;; CHECK-TEXT-NEXT: (tuple.drop 2 - ;; CHECK-TEXT-NEXT: (block $l-catch (type $3) (result i32 i64) + ;; CHECK-TEXT-NEXT: (block $l-catch (type $1) (result i32 i64) ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32-i64 $l-catch) (catch_ref $e-i32-i64 $l-catch-ref) ;; CHECK-TEXT-NEXT: (throw $e-i32-i64 ;; CHECK-TEXT-NEXT: (i32.const 0) @@ -220,9 +220,9 @@ ;; CHECK-BIN-NEXT: (local $4 i32) ;; CHECK-BIN-NEXT: (block $label$1 ;; CHECK-BIN-NEXT: (local.set $2 - ;; CHECK-BIN-NEXT: (block $label$2 (type $4) (result i32 i64 exnref) + ;; CHECK-BIN-NEXT: (block $label$2 (type $2) (result i32 i64 exnref) ;; CHECK-BIN-NEXT: (local.set $0 - ;; CHECK-BIN-NEXT: (block $label$3 (type $3) (result i32 i64) + ;; CHECK-BIN-NEXT: (block $label$3 (type $1) (result i32 i64) ;; CHECK-BIN-NEXT: (try_table (catch $e-i32-i64 $label$3) (catch_ref $e-i32-i64 $label$2) ;; CHECK-BIN-NEXT: (throw $e-i32-i64 ;; CHECK-BIN-NEXT: (i32.const 0) @@ -294,7 +294,82 @@ ) ) - ;; CHECK-TEXT: (func $try-table-all-catch-clauses (type $0) + ;; CHECK-TEXT: (func $try-table-all-catch-clauses-empty-tag (type $0) + ;; CHECK-TEXT-NEXT: (block $outer + ;; CHECK-TEXT-NEXT: (block $l-catch + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $l-catch-ref (result exnref) + ;; CHECK-TEXT-NEXT: (block $l-catch-all + ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-empty $l-catch) (catch_ref $e-empty $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-all-catch-clauses-empty-tag (type $0) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$3 (result exnref) + ;; CHECK-BIN-NEXT: (block $label$4 + ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) + ;; CHECK-BIN-NEXT: (try_table (catch $e-empty $label$2) (catch_ref $e-empty $label$3) (catch_all $label$4) (catch_all_ref $label$5) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-all-catch-clauses-empty-tag + ;; try_table with all kinds of catch clauses when using a tag with an empty + ;; param type + (block $outer + (block $l-catch + (drop + (block $l-catch-ref (result exnref) + (block $l-catch-all + (throw_ref + (block $l-catch-all-ref (result exnref) + (try_table (catch $e-empty $l-catch) + (catch_ref $e-empty $l-catch-ref) + (catch_all $l-catch-all) + (catch_all_ref $l-catch-all-ref) + (call $foo) + (call $foo) + ) + (br $outer) + ) + ) + ) + (br $outer) + ) + ) + (br $outer) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-all-catch-clauses-i32-tag (type $0) ;; CHECK-TEXT-NEXT: (block $outer ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) @@ -319,7 +394,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $try-table-all-catch-clauses (type $0) + ;; CHECK-BIN: (func $try-table-all-catch-clauses-i32-tag (type $0) ;; CHECK-BIN-NEXT: (local $0 (i32 exnref)) ;; CHECK-BIN-NEXT: (local $1 i32) ;; CHECK-BIN-NEXT: (block $label$1 @@ -361,7 +436,9 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $try-table-all-catch-clauses + (func $try-table-all-catch-clauses-i32-tag + ;; try_table with all kinds of catch clauses when using a tag with an i32 + ;; param type (block $outer (drop (block $l-catch (result i32) @@ -390,7 +467,133 @@ ) ) - ;; CHECK-TEXT: (func $try-table-with-label-and-br (type $2) (result i32) + ;; CHECK-TEXT: (func $try-table-all-catch-clauses-multivalue-tag (type $0) + ;; CHECK-TEXT-NEXT: (block $outer + ;; CHECK-TEXT-NEXT: (tuple.drop 2 + ;; CHECK-TEXT-NEXT: (block $l-catch (type $1) (result i32 i64) + ;; CHECK-TEXT-NEXT: (tuple.drop 3 + ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $2) (result i32 i64 exnref) + ;; CHECK-TEXT-NEXT: (block $l-catch-all + ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) + ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32-i64 $l-catch) (catch_ref $e-i32-i64 $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: (call $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (br $outer) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $try-table-all-catch-clauses-multivalue-tag (type $0) + ;; CHECK-BIN-NEXT: (local $0 (i32 i64 exnref)) + ;; CHECK-BIN-NEXT: (local $1 i64) + ;; CHECK-BIN-NEXT: (local $2 i32) + ;; CHECK-BIN-NEXT: (local $3 (i32 i64)) + ;; CHECK-BIN-NEXT: (local $4 i32) + ;; CHECK-BIN-NEXT: (block $label$1 + ;; CHECK-BIN-NEXT: (local.set $3 + ;; CHECK-BIN-NEXT: (block $label$2 (type $1) (result i32 i64) + ;; CHECK-BIN-NEXT: (local.set $0 + ;; CHECK-BIN-NEXT: (block $label$3 (type $2) (result i32 i64 exnref) + ;; CHECK-BIN-NEXT: (block $label$4 + ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) + ;; CHECK-BIN-NEXT: (try_table (catch $e-i32-i64 $label$2) (catch_ref $e-i32-i64 $label$3) (catch_all $label$4) (catch_all_ref $label$5) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: (call $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $2 + ;; CHECK-BIN-NEXT: (tuple.extract 3 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i64) + ;; CHECK-BIN-NEXT: (local.set $1 + ;; CHECK-BIN-NEXT: (tuple.extract 3 1 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (tuple.extract 3 2 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $2) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (br $label$1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block (result i32) + ;; CHECK-BIN-NEXT: (local.set $4 + ;; CHECK-BIN-NEXT: (tuple.extract 2 0 + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (tuple.extract 2 1 + ;; CHECK-BIN-NEXT: (local.get $3) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $4) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $try-table-all-catch-clauses-multivalue-tag + ;; try_table with all kinds of catch clauses when using a tag with a + ;; multivalue param type + (block $outer + (tuple.drop 2 + (block $l-catch (result i32 i64) + (tuple.drop 3 + (block $l-catch-ref (result i32 i64 exnref) + (block $l-catch-all + (throw_ref + (block $l-catch-all-ref (result exnref) + (try_table (catch $e-i32-i64 $l-catch) + (catch_ref $e-i32-i64 $l-catch-ref) + (catch_all $l-catch-all) + (catch_all_ref $l-catch-all-ref) + (call $foo) + (call $foo) + ) + (br $outer) + ) + ) + ) + (br $outer) + ) + ) + (br $outer) + ) + ) + ) + ) + + ;; CHECK-TEXT: (func $try-table-with-label-and-br (type $4) (result i32) ;; CHECK-TEXT-NEXT: (block $l-catch (result i32) ;; CHECK-TEXT-NEXT: (block $l (result i32) ;; CHECK-TEXT-NEXT: (try_table (result i32) (catch $e-i32 $l-catch) @@ -401,7 +604,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $try-table-with-label-and-br (type $2) (result i32) + ;; CHECK-BIN: (func $try-table-with-label-and-br (type $4) (result i32) ;; CHECK-BIN-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NEXT: (block $label$2 (result i32) ;; CHECK-BIN-NEXT: (try_table (result i32) (catch $e-i32 $label$1) @@ -420,7 +623,7 @@ ) ) - ;; CHECK-TEXT: (func $nested-try-table (type $1) (result exnref) + ;; CHECK-TEXT: (func $nested-try-table (type $3) (result exnref) ;; CHECK-TEXT-NEXT: (block $l-catch-outer (result exnref) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l-catch-inner (result i32) @@ -442,7 +645,7 @@ ;; CHECK-TEXT-NEXT: (ref.null noexn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $nested-try-table (type $1) (result exnref) + ;; CHECK-BIN: (func $nested-try-table (type $3) (result exnref) ;; CHECK-BIN-NEXT: (block $label$1 (result exnref) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $label$2 (result i32) @@ -485,13 +688,13 @@ ) ;; CHECK-BIN-NODEBUG: (type $0 (func)) -;; CHECK-BIN-NODEBUG: (type $1 (func (result exnref))) +;; CHECK-BIN-NODEBUG: (type $1 (func (result i32 i64))) -;; CHECK-BIN-NODEBUG: (type $2 (func (result i32))) +;; CHECK-BIN-NODEBUG: (type $2 (func (result i32 i64 exnref))) -;; CHECK-BIN-NODEBUG: (type $3 (func (result i32 i64))) +;; CHECK-BIN-NODEBUG: (type $3 (func (result exnref))) -;; CHECK-BIN-NODEBUG: (type $4 (func (result i32 i64 exnref))) +;; CHECK-BIN-NODEBUG: (type $4 (func (result i32))) ;; CHECK-BIN-NODEBUG: (type $5 (func (result i32 exnref))) @@ -517,7 +720,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $1 (type $1) (result exnref) +;; CHECK-BIN-NODEBUG: (func $1 (type $3) (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) ;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) @@ -540,7 +743,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $2) (result i32) +;; CHECK-BIN-NODEBUG: (func $3 (type $4) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$1) ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 @@ -570,9 +773,9 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local $4 i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 ;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 -;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (type $4) (result i32 i64 exnref) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (type $2) (result i32 i64 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 -;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $3) (result i32 i64) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $1) (result i32 i64) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$2 $label$3) (catch_ref $tag$2 $label$2) ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$2 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) @@ -628,6 +831,30 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $6 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$4 $label$2) (catch_ref $tag$4 $label$3) (catch_all $label$4) (catch_all_ref $label$5) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 (i32 exnref)) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 @@ -670,7 +897,78 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $7 (type $2) (result i32) +;; CHECK-BIN-NODEBUG: (func $8 (type $0) +;; CHECK-BIN-NODEBUG-NEXT: (local $0 (i32 i64 exnref)) +;; CHECK-BIN-NODEBUG-NEXT: (local $1 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (local $3 (i32 i64)) +;; CHECK-BIN-NODEBUG-NEXT: (local $4 i32) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.set $3 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (type $1) (result i32 i64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $2) (result i32 i64 exnref) +;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) +;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$2 $label$2) (catch_ref $tag$2 $label$3) (catch_all $label$4) (catch_all_ref $label$5) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: (call $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $2 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i64) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 3 2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (local.set $4 +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (tuple.extract 2 1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $4) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $4) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (result i32) (catch $tag$0 $label$1) @@ -682,7 +980,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $8 (type $1) (result exnref) +;; CHECK-BIN-NODEBUG: (func $10 (type $3) (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) From fb7d00b336c8d682cbaaf02c96dab64b39d941ba Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 20 Dec 2023 14:17:35 -0800 Subject: [PATCH 015/553] Drop support for non-standard quoted function names (#6188) We previously supported a non-standard `(func "name" ...` syntax for declaring functions exported with the quoted name. Since that is not part of the standard text format, drop support for it, replacing it with the standard `(func $name (export "name") ...` syntax instead. Also replace our other usage of the quoted form in our text output, which was where we quoted names containing characters that are not allowed to appear in standard names. To handle that case, adjust our output from `"$name"` to `$"name"`, which is the standards-track way of supporting such names. Also fix how we detect non-standard name characters to match the spec. Update the lit test output generation script to account for these changes, including by making the `$` prefix on names mandatory. This causes the script to stop interpreting declarative element segments with the `(elem declare ...` syntax as being named "declare", so prevent our generated output from regressing by counting "declare" as a name in the script. --- scripts/update_lit_checks.py | 10 +- src/passes/Heap2Local.cpp | 2 +- src/passes/Print.cpp | 87 +++--- src/wasm/wasm-s-parser.cpp | 6 +- test/binaryen.js/kitchen-sink.js.txt | 28 +- test/ctor-eval/gc-2.wast | 4 +- test/ctor-eval/gc-2.wast.out | 4 +- test/ctor-eval/gc-array.wast | 5 +- test/ctor-eval/gc-array.wast.out | 4 +- test/ctor-eval/gc.wast | 4 +- test/ctor-eval/gc.wast.out | 8 +- test/ctor-eval/ignore-external-input-gc.wast | 6 +- .../ignore-external-input-gc.wast.out | 8 +- test/ctor-eval/ignore-external-input.wast | 8 +- test/ctor-eval/ignore-external-input.wast.out | 4 +- test/ctor-eval/imported-global-2.wast | 4 +- test/ctor-eval/imported-global-2.wast.out | 8 +- test/ctor-eval/memory-init.wast | 3 +- test/ctor-eval/memory-init.wast.out | 4 +- test/ctor-eval/params.wast | 2 +- test/ctor-eval/params.wast.out | 4 +- test/ctor-eval/results.wast | 2 +- test/ctor-eval/results.wast.out | 4 +- test/example/c-api-kitchen-sink.txt | 18 +- test/lit/basic/complexTextNames.wast | 17 +- test/lit/basic/newsyntax.wast | 60 ++--- test/lit/ctor-eval/array_new_data.wast | 22 +- test/lit/ctor-eval/data_drop.wast | 28 +- test/lit/ctor-eval/high_memory.wast | 31 ++- test/lit/exec/array.wast | 2 +- test/lit/exec/delegate-vacuum.wast | 4 +- test/lit/exec/eh-gc.wast | 2 +- test/lit/exec/eh-print.wast | 5 +- test/lit/exec/eh.wast | 8 +- test/lit/exec/gc-cycle-leak.wast | 2 +- test/lit/exec/host-limit.wast | 3 +- test/lit/exec/i31.wast | 14 +- test/lit/exec/intrinsics.wast | 3 +- test/lit/exec/memory.grow.wast | 4 +- test/lit/exec/negative-zero.wast | 16 +- test/lit/exec/no-compare-refs.wast | 2 +- test/lit/exec/non-nullable.wast | 2 +- test/lit/exec/read-nn-null.wast | 14 +- test/lit/exec/strings.wast | 34 +-- test/lit/merge/table_elem.wat | 69 +++-- test/lit/merge/table_elem.wat.second | 2 +- test/lit/passes/O1.wast | 22 +- test/lit/passes/O1_skip.wast | 6 +- test/lit/passes/O3_Oz.wast | 32 +-- test/lit/passes/O_fast-math.wast | 154 ++++++----- test/lit/passes/dae-gc-refine-params.wast | 66 ++--- test/lit/passes/dae-gc-refine-return.wast | 8 +- test/lit/passes/dae_all-features.wast | 27 +- test/lit/passes/flatten_all-features.wast | 26 +- .../passes/flatten_dfo_O3_enable-threads.wast | 113 ++++---- .../passes/flatten_i64-to-i32-lowering.wast | 247 +++++++++--------- ...tten_simplify-locals-nonesting_dfo_O3.wast | 112 ++++---- ...g_souperify-single-use_enable-threads.wast | 87 +++--- ...ls-nonesting_souperify_enable-threads.wast | 87 +++--- test/lit/passes/gto-removals.wast | 12 +- ...e-unused-module-elements_all-features.wast | 32 +-- test/lit/passes/stack-check-memory64.wast | 71 +++-- test/lit/passes/vacuum_all-features.wast | 190 +++++++------- test/lit/validation/intrinsics.wast | 3 +- test/lit/wat-kitchen-sink.wast | 5 +- ...O2_precompute-propagate_print-stack-ir.txt | 8 +- ...2_precompute-propagate_print-stack-ir.wast | 3 +- test/passes/Oz_fuzz-exec_all-features.txt | 70 ++--- test/passes/Oz_fuzz-exec_all-features.wast | 40 +-- ...cate-function-elimination_all-features.txt | 4 +- ...ate-function-elimination_all-features.wast | 2 +- test/passes/duplicate-import-elimination.txt | 4 +- test/passes/duplicate-import-elimination.wast | 3 +- test/passes/fuzz-exec_O.txt | 20 +- test/passes/fuzz-exec_O.wast | 18 +- test/passes/fuzz-exec_all-features.txt | 36 +-- test/passes/fuzz-exec_all-features.wast | 18 +- .../optimize-instructions_fuzz-exec.txt | 32 +-- .../optimize-instructions_fuzz-exec.wast | 16 +- test/passes/roundtrip.txt | 4 +- test/passes/roundtrip.wast | 2 +- ...implify-globals_all-features_fuzz-exec.txt | 4 +- ...mplify-globals_all-features_fuzz-exec.wast | 2 +- test/passes/simplify-locals_all-features.txt | 8 +- test/passes/simplify-locals_all-features.wast | 4 +- .../stack-check_enable-mutable-globals.txt | 4 +- .../stack-check_enable-mutable-globals.wast | 2 +- test/reduce/atomics-and-bulk-memory.wast | 2 +- test/unit/input/asyncify-coroutine.wat | 7 +- test/unit/input/asyncify-sleep.wat | 23 +- test/unit/input/asyncify-stackOverflow.wat | 3 +- test/unit/input/stack_ir.wat | 3 +- test/wasm2js/atomics_32.2asm.js | 4 +- test/wasm2js/atomics_32.2asm.js.opt | 4 +- test/wasm2js/atomics_32.wast | 2 +- test/wasm2js/br_table_hoisting.2asm.js | 16 +- test/wasm2js/br_table_hoisting.2asm.js.opt | 16 +- test/wasm2js/br_table_hoisting.wast | 9 +- test/wasm2js/br_table_to_loop.2asm.js | 8 +- test/wasm2js/br_table_to_loop.2asm.js.opt | 8 +- test/wasm2js/br_table_to_loop.wast | 4 +- test/wasm2js/deterministic.2asm.js | 4 +- test/wasm2js/deterministic.2asm.js.opt | 4 +- test/wasm2js/deterministic.wast | 2 +- test/wasm2js/dot_import.2asm.js | 4 +- test/wasm2js/dot_import.2asm.js.opt | 4 +- test/wasm2js/dot_import.wast | 2 +- test/wasm2js/global_i64.2asm.js | 4 +- test/wasm2js/global_i64.2asm.js.opt | 4 +- test/wasm2js/global_i64.wast | 2 +- test/wasm2js/indirect-select.2asm.js | 8 +- test/wasm2js/indirect-select.2asm.js.opt | 16 +- test/wasm2js/indirect-select.wast | 4 +- test/wasm2js/minified-memory.2asm.js | 4 +- test/wasm2js/minified-memory.2asm.js.opt | 4 +- test/wasm2js/minified-memory.wast | 2 +- test/wasm2js/reinterpret_scratch.2asm.js | 8 +- test/wasm2js/reinterpret_scratch.2asm.js.opt | 10 +- test/wasm2js/reinterpret_scratch.wast | 2 +- test/wasm2js/sign_ext.2asm.js | 80 +++--- test/wasm2js/sign_ext.2asm.js.opt | 44 ++-- test/wasm2js/sign_ext.wast | 10 +- 122 files changed, 1228 insertions(+), 1288 deletions(-) diff --git a/scripts/update_lit_checks.py b/scripts/update_lit_checks.py index ef1dc6aaef9..79af92ab986 100755 --- a/scripts/update_lit_checks.py +++ b/scripts/update_lit_checks.py @@ -39,7 +39,11 @@ ALL_ITEMS = '|'.join(['type', 'import', 'global', 'memory', 'data', 'table', 'elem', 'tag', 'export', 'start', 'func']) -ITEM_NAME = r'\$?[^\s()]*|"[^\s()]*"' + +# Regular names as well as the "declare" in (elem declare ... to get declarative +# segments included in the output. +ITEM_NAME = r'\$[^\s()]*|"[^\s()]*"|declare' + # FIXME: This does not handle nested string contents. For example, # (data (i32.const 10) "hello(") # will look unterminated, due to the '(' inside the string. As a result, the @@ -152,9 +156,9 @@ def parse_output_fuzz_exec(text): for line in text.split('\n'): func = FUZZ_EXEC_FUNC.match(line) if func: - # Add quotes around the name because that is how it will be parsed + # Add a '$' prefix to the name because that is how it will be parsed # in the input. - name = f'"{func.group("name")}"' + name = '$' + func.group("name") items.append((('func', name), [line])) elif line.startswith('[host limit'): # Skip mentions of host limits that we hit. This can happen even diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 0f569374b2d..fcf0d88863b 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -38,7 +38,7 @@ // // (import "env" "import" (func $import (param i32) (result i32))) // -// (func "example" +// (func $example // (local $ref (ref null $boxed-int)) // // ;; Allocate a boxed integer of 42 and save the reference to it. diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 71181566d5e..5ea62c9f21d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -51,40 +51,6 @@ bool isFullForced() { return false; } -std::ostream& printName(Name name, std::ostream& o) { - assert(name && "Cannot print an empty name"); - // We need to quote names if they have tricky chars. - // TODO: This is not spec-compliant since the spec does not support quoted - // identifiers and has a limited set of valid idchars. We need a more robust - // escaping scheme here. Reusing `printEscapedString` is not sufficient, - // either. - if (name.str.find_first_of("()") == std::string_view::npos) { - o << '$' << name.str; - } else { - o << "\"$" << name.str << '"'; - } - return o; -} - -std::ostream& printMemoryName(Name name, std::ostream& o, Module* wasm) { - if (!wasm || wasm->memories.size() > 1) { - o << ' '; - printName(name, o); - } - return o; -} - -std::ostream& printLocal(Index index, Function* func, std::ostream& o) { - Name name; - if (func) { - name = func->getLocalNameOrDefault(index); - } - if (!name) { - name = Name::fromInt(index); - } - return printName(name, o); -} - std::ostream& printEscapedString(std::ostream& os, std::string_view str) { os << '"'; for (unsigned char c : str) { @@ -119,6 +85,56 @@ std::ostream& printEscapedString(std::ostream& os, std::string_view str) { return os << '"'; } +// TODO: Use unicode rather than char. +bool isIDChar(char c) { + if ('0' <= c && c <= '9') { + return true; + } + if ('A' <= c && c <= 'Z') { + return true; + } + if ('a' <= c && c <= 'z') { + return true; + } + static std::array otherIDChars = { + {'!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '/', ':', + '<', '=', '>', '?', '@', '\\', '^', '_', '`', '|', '~'}}; + return std::find(otherIDChars.begin(), otherIDChars.end(), c) != + otherIDChars.end(); +} + +std::ostream& printName(Name name, std::ostream& o) { + assert(name && "Cannot print an empty name"); + // We need to quote names if they have tricky chars. + // TODO: This is not spec-compliant since the spec does not yet support quoted + // identifiers and has a limited set of valid idchars. + o << '$'; + if (std::all_of(name.str.begin(), name.str.end(), isIDChar)) { + return o << name.str; + } else { + return printEscapedString(o, name.str); + } +} + +std::ostream& printMemoryName(Name name, std::ostream& o, Module* wasm) { + if (!wasm || wasm->memories.size() > 1) { + o << ' '; + printName(name, o); + } + return o; +} + +std::ostream& printLocal(Index index, Function* func, std::ostream& o) { + Name name; + if (func) { + name = func->getLocalNameOrDefault(index); + } + if (!name) { + name = Name::fromInt(index); + } + return printName(name, o); +} + // Print a name from the type section, if available. Otherwise print the type // normally. void printTypeOrName(Type type, std::ostream& o, Module* wasm) { @@ -3266,7 +3282,8 @@ void PrintSExpression::visitModule(Module* curr) { printMedium(o, "(elem"); o << " declare func"; for (auto name : elemDeclareNames) { - o << " $" << name; + o << ' '; + printName(name, o); } o << ')' << maybeNewLine; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 49cf1ccfc71..42785e40eba 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1073,11 +1073,7 @@ size_t SExpressionWasmBuilder::parseFunctionNames(Element& s, Name& exportName) { size_t i = 1; while (i < s.size() && i < 3 && s[i]->isStr()) { - if (s[i]->quoted()) { - // an export name - exportName = s[i]->str(); - i++; - } else if (s[i]->dollared()) { + if (s[i]->dollared()) { name = s[i]->str(); i++; } else { diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 168bc00733f..8c6138413a9 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -143,14 +143,14 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (data $0 (i32.const 10) "hello, world") (data $1 "I am passive") (table $t0 1 funcref) - (elem $e0 (i32.const 0) "$kitchen()sinker") + (elem $e0 (i32.const 0) $"kitchen()sinker") (tag $a-tag (param i32)) (export "mem" (memory $0)) - (export "kitchen_sinker" (func "$kitchen()sinker")) + (export "kitchen_sinker" (func $"kitchen()sinker")) (export "a-global-exp" (global $a-global)) (export "a-tag-exp" (tag $a-tag)) (start $starter) - (func "$kitchen()sinker" (type $0) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) + (func $"kitchen()sinker" (type $0) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) (local $4 i32) (block $the-body (result i32) (block $the-nothing @@ -1979,7 +1979,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i32.eqz - (call "$kitchen()sinker" + (call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -2057,7 +2057,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (return (i32.const 1337) ) - (return_call "$kitchen()sinker" + (return_call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -2082,13 +2082,13 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (ref.is_null - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") ) ) (drop (select (result funcref) (ref.null nofunc) - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") (i32.const 1) ) ) @@ -2247,14 +2247,14 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (data $0 (i32.const 10) "hello, world") (data $1 "I am passive") (table $t0 1 funcref) - (elem $e0 (i32.const 0) "$kitchen()sinker") + (elem $e0 (i32.const 0) $"kitchen()sinker") (tag $a-tag (param i32)) (export "mem" (memory $0)) - (export "kitchen_sinker" (func "$kitchen()sinker")) + (export "kitchen_sinker" (func $"kitchen()sinker")) (export "a-global-exp" (global $a-global)) (export "a-tag-exp" (tag $a-tag)) (start $starter) - (func "$kitchen()sinker" (type $0) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) + (func $"kitchen()sinker" (type $0) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) (local $4 i32) (block $the-body (result i32) (block $the-nothing @@ -4083,7 +4083,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i32.eqz - (call "$kitchen()sinker" + (call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -4161,7 +4161,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (return (i32.const 1337) ) - (return_call "$kitchen()sinker" + (return_call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -4186,13 +4186,13 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (ref.is_null - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") ) ) (drop (select (result funcref) (ref.null nofunc) - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") (i32.const 1) ) ) diff --git a/test/ctor-eval/gc-2.wast b/test/ctor-eval/gc-2.wast index 731f704681e..561ac617623 100644 --- a/test/ctor-eval/gc-2.wast +++ b/test/ctor-eval/gc-2.wast @@ -29,13 +29,13 @@ ) ) - (func "test1" + (func $test (export "test1") (global.set $global2 (global.get $global3) ) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) (select (struct.get $struct 0 (ref.cast (ref $struct) diff --git a/test/ctor-eval/gc-2.wast.out b/test/ctor-eval/gc-2.wast.out index cec7f943057..4d80f764e36 100644 --- a/test/ctor-eval/gc-2.wast.out +++ b/test/ctor-eval/gc-2.wast.out @@ -10,8 +10,8 @@ (i32.const 1337) )) (global $global1 (ref any) (global.get $ctor-eval$global)) - (export "keepalive" (func $1)) - (func $1 (type $1) (result i32) + (export "keepalive" (func $keepalive)) + (func $keepalive (type $1) (result i32) (select (struct.get $struct 0 (ref.cast (ref $struct) diff --git a/test/ctor-eval/gc-array.wast b/test/ctor-eval/gc-array.wast index 0ad3d031479..2ecb92d5ed3 100644 --- a/test/ctor-eval/gc-array.wast +++ b/test/ctor-eval/gc-array.wast @@ -21,7 +21,7 @@ ) ) - (func "test1" + (func $test1 (export "test1") (array.set $array (global.get $global2) (i32.const 1) @@ -29,7 +29,7 @@ ) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) (i32.add (array.get $array (global.get $global1) @@ -42,4 +42,3 @@ ) ) ) - diff --git a/test/ctor-eval/gc-array.wast.out b/test/ctor-eval/gc-array.wast.out index eadedfc4833..ed21823b8c7 100644 --- a/test/ctor-eval/gc-array.wast.out +++ b/test/ctor-eval/gc-array.wast.out @@ -11,8 +11,8 @@ (i32.const 42) (i32.const 1337) )) - (export "keepalive" (func $1)) - (func $1 (type $1) (result i32) + (export "keepalive" (func $keepalive)) + (func $keepalive (type $1) (result i32) (i32.add (array.get $array (global.get $global1) diff --git a/test/ctor-eval/gc.wast b/test/ctor-eval/gc.wast index 46ce6b49a2c..00c593121a5 100644 --- a/test/ctor-eval/gc.wast +++ b/test/ctor-eval/gc.wast @@ -21,7 +21,7 @@ ;; so a new (immutable) global will appear, and we will read from it. (global $global2 (mut (ref null $struct)) (ref.null $struct)) - (func "test1" + (func $test1 (export "test1") ;; The locals will be optimized into a single non-nullable one by the ;; optimizer. (local $temp1 (ref null $struct)) @@ -51,7 +51,7 @@ (call $import (local.get $temp2)) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) (i32.add (struct.get $struct 0 (global.get $global1) diff --git a/test/ctor-eval/gc.wast.out b/test/ctor-eval/gc.wast.out index 8999d475690..ae3e21a180e 100644 --- a/test/ctor-eval/gc.wast.out +++ b/test/ctor-eval/gc.wast.out @@ -14,9 +14,9 @@ (global $ctor-eval$global_4 (ref $struct) (struct.new $struct (i32.const 99) )) - (export "test1" (func $0_3)) - (export "keepalive" (func $1)) - (func $1 (type $2) (result i32) + (export "test1" (func $test1_3)) + (export "keepalive" (func $keepalive)) + (func $keepalive (type $2) (result i32) (i32.add (struct.get $struct 0 (global.get $global1) @@ -26,7 +26,7 @@ ) ) ) - (func $0_3 (type $3) + (func $test1_3 (type $3) (local $0 (ref $struct)) (local.set $0 (global.get $ctor-eval$global_4) diff --git a/test/ctor-eval/ignore-external-input-gc.wast b/test/ctor-eval/ignore-external-input-gc.wast index 16558336c2d..67fcb30e851 100644 --- a/test/ctor-eval/ignore-external-input-gc.wast +++ b/test/ctor-eval/ignore-external-input-gc.wast @@ -2,7 +2,7 @@ (global $global1 (mut i32) (i32.const 10)) (global $global2 (mut i32) (i32.const 20)) - (func "test1" (param $any (ref null any)) + (func $test1 (export "test1") (param $any (ref null any)) ;; This is ok to call: when ignoring external input we assume 0 for the ;; parameters, and this parameter is nullable. (drop @@ -13,7 +13,7 @@ ) ) - (func "test2" (param $any (ref any)) + (func $test2 (export "test2") (param $any (ref any)) ;; This is *not* ok to call: when ignoring external input we assume 0 for ;; the parameters, and this parameter is not nullable. (drop @@ -24,7 +24,7 @@ ) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) (i32.add (global.get $global1) (global.get $global2) diff --git a/test/ctor-eval/ignore-external-input-gc.wast.out b/test/ctor-eval/ignore-external-input-gc.wast.out index 9b10b808b7d..571c8198796 100644 --- a/test/ctor-eval/ignore-external-input-gc.wast.out +++ b/test/ctor-eval/ignore-external-input-gc.wast.out @@ -3,14 +3,14 @@ (type $1 (func (result i32))) (global $global1 (mut i32) (i32.const 11)) (global $global2 (mut i32) (i32.const 20)) - (export "test2" (func $1)) - (export "keepalive" (func $2)) - (func $1 (type $0) (param $any (ref any)) + (export "test2" (func $test2)) + (export "keepalive" (func $keepalive)) + (func $test2 (type $0) (param $any (ref any)) (global.set $global2 (i32.const 22) ) ) - (func $2 (type $1) (result i32) + (func $keepalive (type $1) (result i32) (i32.add (global.get $global1) (global.get $global2) diff --git a/test/ctor-eval/ignore-external-input.wast b/test/ctor-eval/ignore-external-input.wast index 56201160577..d581c7e04e7 100644 --- a/test/ctor-eval/ignore-external-input.wast +++ b/test/ctor-eval/ignore-external-input.wast @@ -10,7 +10,7 @@ (memory 256 256) (data (i32.const 0) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") ;; the final 4 'a's will remain - (func "test1" + (func $test1 (export "test1") ;; This is ok to call: when ignoring external input we assume there is no ;; environment to read. (i32.store @@ -29,7 +29,7 @@ ) ) - (func "test2" + (func $test2 (export "test2") ;; This is also ok to call: when ignoring external input we assume there are ;; not args passed to main. (i32.store @@ -48,7 +48,7 @@ ) ) - (func "test2b" (param $x i32) + (func $test2b (export "test2b") (param $x i32) ;; This is also ok to call: when ignoring external input we assume the ;; args are zeros. (i32.store @@ -57,7 +57,7 @@ ) ) - (func "test3" + (func $test3 (export "test3") ;; This is *not* ok to call, and we will *not* reach the final store after ;; this call. This function will not be evalled and will remain in the ;; output. diff --git a/test/ctor-eval/ignore-external-input.wast.out b/test/ctor-eval/ignore-external-input.wast.out index 43de6066590..a557ec99e29 100644 --- a/test/ctor-eval/ignore-external-input.wast.out +++ b/test/ctor-eval/ignore-external-input.wast.out @@ -4,8 +4,8 @@ (import "wasi_snapshot_preview1" "something_else" (func $wasi_something_else (type $0) (result i32))) (memory $0 256 256) (data $0 (i32.const 28) "aaaa") - (export "test3" (func $3)) - (func $3 (type $1) + (export "test3" (func $test3)) + (func $test3 (type $1) (drop (call $wasi_something_else) ) diff --git a/test/ctor-eval/imported-global-2.wast b/test/ctor-eval/imported-global-2.wast index e10dc70802c..0662fb76056 100644 --- a/test/ctor-eval/imported-global-2.wast +++ b/test/ctor-eval/imported-global-2.wast @@ -4,7 +4,7 @@ ;; imports must not be used (import "env" "imported" (global $imported i32)) - (func "test1" (result i32) + (func $test1 (export "test1") (result i32) (local $temp i32) ;; this errors, and we never get to evalling the store after it @@ -20,7 +20,7 @@ (local.get $temp) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) (drop (i32.load (i32.const 13) diff --git a/test/ctor-eval/imported-global-2.wast.out b/test/ctor-eval/imported-global-2.wast.out index 0347b4970c3..bc276175e2a 100644 --- a/test/ctor-eval/imported-global-2.wast.out +++ b/test/ctor-eval/imported-global-2.wast.out @@ -2,9 +2,9 @@ (type $0 (func (result i32))) (import "env" "imported" (global $imported i32)) (memory $0 256 256) - (export "test1" (func $0)) - (export "keepalive" (func $1)) - (func $0 (type $0) (result i32) + (export "test1" (func $test1)) + (export "keepalive" (func $keepalive)) + (func $test1 (type $0) (result i32) (local $temp i32) (local.set $temp (global.get $imported) @@ -15,7 +15,7 @@ ) (local.get $temp) ) - (func $1 (type $0) (result i32) + (func $keepalive (type $0) (result i32) (drop (i32.load (i32.const 13) diff --git a/test/ctor-eval/memory-init.wast b/test/ctor-eval/memory-init.wast index b910aa2f3c1..bef35c7e0ff 100644 --- a/test/ctor-eval/memory-init.wast +++ b/test/ctor-eval/memory-init.wast @@ -2,7 +2,7 @@ (memory $0 1) (data (i32.const 0) "__________") (data (i32.const 20) "__________") - (func "test1" + (func $test1 (export "test1") ;; A store that can be evalled. (i32.store8 (i32.const 4) @@ -19,4 +19,3 @@ ) ) ) - diff --git a/test/ctor-eval/memory-init.wast.out b/test/ctor-eval/memory-init.wast.out index 59c4b691def..3726b5ef240 100644 --- a/test/ctor-eval/memory-init.wast.out +++ b/test/ctor-eval/memory-init.wast.out @@ -3,8 +3,8 @@ (memory $0 1) (data $0 (i32.const 0) "__________") (data $1 (i32.const 20) "__________") - (export "test1" (func $0)) - (func $0 (type $0) + (export "test1" (func $test1)) + (func $test1 (type $0) (i32.store8 (i32.const 4) (i32.const 100) diff --git a/test/ctor-eval/params.wast b/test/ctor-eval/params.wast index cb346bb3b38..196a2ebae1a 100644 --- a/test/ctor-eval/params.wast +++ b/test/ctor-eval/params.wast @@ -1,5 +1,5 @@ (module - (func "test1" (param $x i32) + (func $test1 (export "test1") (param $x i32) ;; The presence of params stops us from evalling this function, at least ;; not with --ignore-external-input (see ignore-external-input.wast) (nop) diff --git a/test/ctor-eval/params.wast.out b/test/ctor-eval/params.wast.out index 1352c0187a1..5af29aab5e6 100644 --- a/test/ctor-eval/params.wast.out +++ b/test/ctor-eval/params.wast.out @@ -1,7 +1,7 @@ (module (type $0 (func (param i32))) - (export "test1" (func $0)) - (func $0 (type $0) (param $x i32) + (export "test1" (func $test1)) + (func $test1 (type $0) (param $x i32) (nop) ) ) diff --git a/test/ctor-eval/results.wast b/test/ctor-eval/results.wast index bbc48db3cdc..bfefa2756c2 100644 --- a/test/ctor-eval/results.wast +++ b/test/ctor-eval/results.wast @@ -63,7 +63,7 @@ (i32.const 100) ) - (func "keepalive" (result i32) + (func $keepalive (export "keepalive") (result i32) ;; Keep everything alive to see the changes. ;; These should call the original $test1, not the one that is nopped out diff --git a/test/ctor-eval/results.wast.out b/test/ctor-eval/results.wast.out index 358320e081d..5f750a1a8ce 100644 --- a/test/ctor-eval/results.wast.out +++ b/test/ctor-eval/results.wast.out @@ -10,7 +10,7 @@ (export "test1" (func $test1_7)) (export "test3" (func $test3_8)) (export "test5" (func $test5_9)) - (export "keepalive" (func $5)) + (export "keepalive" (func $keepalive)) (func $test1 (type $1) (global.set $global1 (i32.const 11) @@ -40,7 +40,7 @@ (call $import) (i32.const 100) ) - (func $5 (type $0) (result i32) + (func $keepalive (type $0) (result i32) (call $test1) (call $test2) (drop diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 1554a418419..8955921b85b 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -59,7 +59,7 @@ BinaryenFeatureAll: 131071 ) (table.set $0 (i32.const 0) - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") ) (table.get $0 (i32.const 0) @@ -93,13 +93,13 @@ BinaryenFeatureAll: 131071 (data $1 "I am passive") (table $tab 0 100 funcref) (table $0 1 1 funcref) - (elem $0 (table $0) (i32.const 0) func "$kitchen()sinker") - (elem $passive func "$kitchen()sinker") + (elem $0 (table $0) (i32.const 0) func $"kitchen()sinker") + (elem $passive func $"kitchen()sinker") (tag $a-tag (param i32)) (export "mem" (memory $0)) - (export "kitchen_sinker" (func "$kitchen()sinker")) + (export "kitchen_sinker" (func $"kitchen()sinker")) (start $starter) - (func "$kitchen()sinker" (type $2) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) + (func $"kitchen()sinker" (type $2) (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32) (local $4 i32) (local $5 externref) (block $the-body (result i32) @@ -2014,7 +2014,7 @@ BinaryenFeatureAll: 131071 ) (drop (i32.eqz - (call "$kitchen()sinker" + (call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -2092,7 +2092,7 @@ BinaryenFeatureAll: 131071 (return (i32.const 1337) ) - (return_call "$kitchen()sinker" + (return_call $"kitchen()sinker" (i32.const 13) (i64.const 37) (f32.const 1.2999999523162842) @@ -2112,13 +2112,13 @@ BinaryenFeatureAll: 131071 ) (drop (ref.is_null - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") ) ) (drop (select (result funcref) (ref.null nofunc) - (ref.func "$kitchen()sinker") + (ref.func $"kitchen()sinker") (i32.const 1) ) ) diff --git a/test/lit/basic/complexTextNames.wast b/test/lit/basic/complexTextNames.wast index 4605f0165f1..88240e038d8 100644 --- a/test/lit/basic/complexTextNames.wast +++ b/test/lit/basic/complexTextNames.wast @@ -12,34 +12,27 @@ (module ;; CHECK-TEXT: (type $0 (func)) - ;; CHECK-TEXT: (export "$zoo (.bar)" (func $1)) - ;; CHECK-TEXT: (func $foo\20\28.bar\29 (type $0) ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $0 (func)) - ;; CHECK-BIN: (export "$zoo (.bar)" (func $1)) - ;; CHECK-BIN: (func $foo\20\28.bar\29 (type $0) ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) (func $foo\20\28.bar\29) - (func "$zoo (.bar)" (call $foo\20\28.bar\29)) + ;; CHECK-TEXT: (func $"zoo (.bar)" (type $0) + ;; CHECK-TEXT-NEXT: (call $foo\20\28.bar\29) + ;; CHECK-TEXT-NEXT: ) + (func $"zoo (.bar)" (call $foo\20\28.bar\29)) ) -;; CHECK-TEXT: (func $1 (type $0) -;; CHECK-TEXT-NEXT: (call $foo\20\28.bar\29) -;; CHECK-TEXT-NEXT: ) - -;; CHECK-BIN: (func $1 (type $0) +;; CHECK-BIN: (func $zoo\20\28.bar\29 (type $0) ;; CHECK-BIN-NEXT: (call $foo\20\28.bar\29) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NODEBUG: (type $0 (func)) -;; CHECK-BIN-NODEBUG: (export "$zoo (.bar)" (func $1)) - ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/newsyntax.wast b/test/lit/basic/newsyntax.wast index 0811ec07e8d..204bed3ab08 100644 --- a/test/lit/basic/newsyntax.wast +++ b/test/lit/basic/newsyntax.wast @@ -27,43 +27,41 @@ ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) (import "env" "table" (table 9 9 funcref)) - (func "call_indirect" + ;; CHECK-TEXT: (export "call_indirect" (func $call_indirect)) + + ;; CHECK-TEXT: (func $call_indirect (type $0) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $1) + ;; CHECK-TEXT-NEXT: (i32.const 10) + ;; CHECK-TEXT-NEXT: (f64.const 20) + ;; CHECK-TEXT-NEXT: (i32.const 30) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $0) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (export "call_indirect" (func $call_indirect)) + + ;; CHECK-BIN: (func $call_indirect (type $0) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $1) + ;; CHECK-BIN-NEXT: (i32.const 10) + ;; CHECK-BIN-NEXT: (f64.const 20) + ;; CHECK-BIN-NEXT: (i32.const 30) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $0) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $call_indirect (export "call_indirect") (drop (call_indirect (param i32) (param f64) (result i32) (i32.const 10) (f64.const 20) (i32.const 30)) ) (call_indirect (i32.const 1)) ) ) -;; CHECK-TEXT: (export "call_indirect" (func $0)) - -;; CHECK-TEXT: (func $0 (type $0) -;; CHECK-TEXT-NEXT: (drop -;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $1) -;; CHECK-TEXT-NEXT: (i32.const 10) -;; CHECK-TEXT-NEXT: (f64.const 20) -;; CHECK-TEXT-NEXT: (i32.const 30) -;; CHECK-TEXT-NEXT: ) -;; CHECK-TEXT-NEXT: ) -;; CHECK-TEXT-NEXT: (call_indirect $timport$0 (type $0) -;; CHECK-TEXT-NEXT: (i32.const 1) -;; CHECK-TEXT-NEXT: ) -;; CHECK-TEXT-NEXT: ) - -;; CHECK-BIN: (export "call_indirect" (func $0)) - -;; CHECK-BIN: (func $0 (type $0) -;; CHECK-BIN-NEXT: (drop -;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $1) -;; CHECK-BIN-NEXT: (i32.const 10) -;; CHECK-BIN-NEXT: (f64.const 20) -;; CHECK-BIN-NEXT: (i32.const 30) -;; CHECK-BIN-NEXT: ) -;; CHECK-BIN-NEXT: ) -;; CHECK-BIN-NEXT: (call_indirect $timport$0 (type $0) -;; CHECK-BIN-NEXT: (i32.const 1) -;; CHECK-BIN-NEXT: ) -;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NODEBUG: (export "call_indirect" (func $0)) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) diff --git a/test/lit/ctor-eval/array_new_data.wast b/test/lit/ctor-eval/array_new_data.wast index 248b71ba438..a185c171f0c 100644 --- a/test/lit/ctor-eval/array_new_data.wast +++ b/test/lit/ctor-eval/array_new_data.wast @@ -14,7 +14,17 @@ ;; CHECK: (data $1 (i32.const 0) "") (data $1 (i32.const 0) "") - (func "test" + ;; CHECK: (export "test" (func $test)) + + ;; CHECK: (func $test (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_data $[i8] $1 + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (export "test") ;; An array.new_data cannot be evalled since ctor-eval flattens memory segments ;; atm. In fact the module would not validate as we refer to segment 1 here ;; but after flattening only segment 0 exists. @@ -26,13 +36,3 @@ ) ) ) -;; CHECK: (export "test" (func $0)) - -;; CHECK: (func $0 (type $0) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (array.new_data $[i8] $1 -;; CHECK-NEXT: (i32.const 16) -;; CHECK-NEXT: (i32.const 8) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/data_drop.wast b/test/lit/ctor-eval/data_drop.wast index c1bfd487ca1..5833cf4a007 100644 --- a/test/lit/ctor-eval/data_drop.wast +++ b/test/lit/ctor-eval/data_drop.wast @@ -9,7 +9,20 @@ (data (i32.const 0) "__________") (data (i32.const 20) "__________") - (func "test" + ;; CHECK: (data $0 (i32.const 0) "__________") + + ;; CHECK: (data $1 (i32.const 20) "__________") + + ;; CHECK: (export "test" (func $test)) + + ;; CHECK: (func $test (type $0) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (data.drop $1) + ;; CHECK-NEXT: ) + (func $test (export "test") ;; A store that can be evalled, but we do not do so because of the ;; instruction after us. (i32.store8 @@ -23,16 +36,3 @@ (data.drop 1) ) ) -;; CHECK: (data $0 (i32.const 0) "__________") - -;; CHECK: (data $1 (i32.const 20) "__________") - -;; CHECK: (export "test" (func $0)) - -;; CHECK: (func $0 (type $0) -;; CHECK-NEXT: (i32.store8 -;; CHECK-NEXT: (i32.const 4) -;; CHECK-NEXT: (i32.const 100) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (data.drop $1) -;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/high_memory.wast b/test/lit/ctor-eval/high_memory.wast index 86e3827f47e..b7a9f60eb47 100644 --- a/test/lit/ctor-eval/high_memory.wast +++ b/test/lit/ctor-eval/high_memory.wast @@ -7,7 +7,7 @@ ;; CHECK: (memory $0 1616) (memory $0 1616) ;; 101 MB - (func "test1" + (func $test1 (export "test1") ;; This write will be evalled into a data segment and removed. (i32.store8 (i32.const 0x63fffff) ;; 100 MB - 1 @@ -15,7 +15,19 @@ ) ) - (func "test2" + ;; CHECK: (data $0 (i32.const 104857599) "*") + + ;; CHECK: (export "test1" (func $test1_2)) + + ;; CHECK: (export "test2" (func $test2)) + + ;; CHECK: (func $test2 (type $0) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 104857600) + ;; CHECK-NEXT: (i32.const 43) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test2 (export "test2") ;; We stop at this write to a high address (wasm-ctor-eval generally only ;; writes to low addresses, so it is tuned for that) (i32.store8 @@ -24,19 +36,6 @@ ) ) ) -;; CHECK: (data $0 (i32.const 104857599) "*") - -;; CHECK: (export "test1" (func $0_2)) - -;; CHECK: (export "test2" (func $1)) - -;; CHECK: (func $1 (type $0) -;; CHECK-NEXT: (i32.store8 -;; CHECK-NEXT: (i32.const 104857600) -;; CHECK-NEXT: (i32.const 43) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $0_2 (type $0) +;; CHECK: (func $test1_2 (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) diff --git a/test/lit/exec/array.wast b/test/lit/exec/array.wast index 7e74c7b7d74..fb6a8b34616 100644 --- a/test/lit/exec/array.wast +++ b/test/lit/exec/array.wast @@ -7,7 +7,7 @@ ;; CHECK: [fuzz-exec] calling func ;; CHECK-NEXT: [fuzz-exec] note result: func => 1 - (func "func" (result i32) + (func $func (export "func") (result i32) ;; Verifies the order of execution is correct - we should return 1, not 2. (array.new $array (return (i32.const 1)) diff --git a/test/lit/exec/delegate-vacuum.wast b/test/lit/exec/delegate-vacuum.wast index c9276056810..084113c2bbe 100644 --- a/test/lit/exec/delegate-vacuum.wast +++ b/test/lit/exec/delegate-vacuum.wast @@ -9,7 +9,7 @@ (tag $tag$0 (param i32)) ;; CHECK: [fuzz-exec] calling export-1 ;; CHECK-NEXT: [exception thrown: tag$0 0] - (func "export-1" + (func $export-1 (export "export-1") (try (do (try @@ -30,7 +30,7 @@ ) ;; CHECK: [fuzz-exec] calling export-2 ;; CHECK-NEXT: [trap unreachable] - (func "export-2" + (func $export-2 (export "export-2") (call $inner) (unreachable) ) diff --git a/test/lit/exec/eh-gc.wast b/test/lit/exec/eh-gc.wast index cac2f6adf0d..f10a27c5765 100644 --- a/test/lit/exec/eh-gc.wast +++ b/test/lit/exec/eh-gc.wast @@ -6,7 +6,7 @@ (tag $tag (param externref)) ;; CHECK: [fuzz-exec] calling catch-null - (func "catch-null" + (func $catch-null (export "catch-null") (try $label$3 (do ;; Throw a null. diff --git a/test/lit/exec/eh-print.wast b/test/lit/exec/eh-print.wast index 8f9520e75a2..f501646313f 100644 --- a/test/lit/exec/eh-print.wast +++ b/test/lit/exec/eh-print.wast @@ -12,7 +12,7 @@ ;; CHECK: [fuzz-exec] calling array ;; CHECK-NEXT: [exception thrown: A [ref (type $array.0 (array (mut i32))) (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0[..])]] - (func "array" (result (ref $A)) + (func $array (export "array") (result (ref $A)) ;; Throw a very large array. We should not print all 12K items in it, as that ;; would be very verbose. Instead we stop after a reasonable amount and ;; print [..] for the rest. @@ -25,7 +25,7 @@ ;; CHECK: [fuzz-exec] calling struct ;; CHECK-NEXT: [exception thrown: B [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [ref (type $struct.0 (struct (field (mut anyref)))) [..]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] - (func "struct" (result (ref $B)) + (func $struct (export "struct") (result (ref $B)) (local $x (ref $B)) ;; As above, but now with a recursive struct. (local.set $x @@ -40,4 +40,3 @@ ) ) ) - diff --git a/test/lit/exec/eh.wast b/test/lit/exec/eh.wast index 779309eb6d5..930e57c202f 100644 --- a/test/lit/exec/eh.wast +++ b/test/lit/exec/eh.wast @@ -7,12 +7,12 @@ ;; CHECK: [fuzz-exec] calling throw ;; CHECK-NEXT: [exception thrown: e-i32 1] - (func "throw" + (func $throw (export "throw") (throw $e-i32 (i32.const 1)) ) ;; CHECK: [fuzz-exec] calling try-catch - (func "try-catch" + (func $try-catch (export "try-catch") (try (do (throw $e-i32 (i32.const 2)) @@ -25,7 +25,7 @@ ;; CHECK: [fuzz-exec] calling catchless-try ;; CHECK-NEXT: [exception thrown: e-i32 3] - (func "catchless-try" + (func $catchless-try (export "catchless-try") (try (do (throw $e-i32 (i32.const 3)) @@ -35,7 +35,7 @@ ;; CHECK: [fuzz-exec] calling try-delegate ;; CHECK-NEXT: [exception thrown: e-i32 4] - (func "try-delegate" + (func $try-delegate (export "try-delegate") (try $l0 (do (try diff --git a/test/lit/exec/gc-cycle-leak.wast b/test/lit/exec/gc-cycle-leak.wast index 75c3293927d..f4f62b53367 100644 --- a/test/lit/exec/gc-cycle-leak.wast +++ b/test/lit/exec/gc-cycle-leak.wast @@ -6,7 +6,7 @@ (type $A (struct (field (mut (ref null $A))))) ;; CHECK: [fuzz-exec] calling test - (func "test" + (func $test (export "test") (local $a (ref $A)) ;; This function makes a self-cycle where the local $a's ref field points to ;; itself. This test checks that we do not error, even in sanitizers, when diff --git a/test/lit/exec/host-limit.wast b/test/lit/exec/host-limit.wast index ee59d655b2f..e64a47d8a3f 100644 --- a/test/lit/exec/host-limit.wast +++ b/test/lit/exec/host-limit.wast @@ -18,10 +18,9 @@ ;; CHECK: [fuzz-exec] calling export ;; CHECK-NEXT: [LoggingExternalInterface logging 42] ;; CHECK-NEXT: ignoring comparison of ExecutionResults! - (func "export" + (func $export (export "export") (call $log (i32.const 42) ) ) ) - diff --git a/test/lit/exec/i31.wast b/test/lit/exec/i31.wast index cd25dffa029..70d220d8c50 100644 --- a/test/lit/exec/i31.wast +++ b/test/lit/exec/i31.wast @@ -5,7 +5,7 @@ (module ;; CHECK: [fuzz-exec] calling null-local ;; CHECK-NEXT: [fuzz-exec] note result: null-local => 1 - (func "null-local" (result i32) + (func $null-local (export "null-local") (result i32) (local $ref (ref null i31)) (ref.is_null (local.get $ref) @@ -14,7 +14,7 @@ ;; CHECK: [fuzz-exec] calling null-immediate ;; CHECK-NEXT: [fuzz-exec] note result: null-immediate => 1 - (func "null-immediate" (result i32) + (func $null-immediate (export "null-immediate") (result i32) (ref.is_null (ref.null i31) ) @@ -22,7 +22,7 @@ ;; CHECK: [fuzz-exec] calling non-null ;; CHECK-NEXT: [fuzz-exec] note result: non-null => 0 - (func "non-null" (result i32) + (func $non-null (export "non-null") (result i32) (ref.is_null (ref.i31 (i32.const 1234) @@ -32,7 +32,7 @@ ;; CHECK: [fuzz-exec] calling nn-u ;; CHECK-NEXT: [fuzz-exec] note result: nn-u => 2147483647 - (func "nn-u" (result i32) + (func $nn-u (export "nn-u") (result i32) (i31.get_u (ref.i31 (i32.const 0xffffffff) @@ -42,7 +42,7 @@ ;; CHECK: [fuzz-exec] calling nn-s ;; CHECK-NEXT: [fuzz-exec] note result: nn-s => -1 - (func "nn-s" (result i32) + (func $nn-s (export "nn-s") (result i32) (i31.get_s (ref.i31 (i32.const 0xffffffff) @@ -52,7 +52,7 @@ ;; CHECK: [fuzz-exec] calling zero-is-not-null ;; CHECK-NEXT: [fuzz-exec] note result: zero-is-not-null => 0 - (func "zero-is-not-null" (result i32) + (func $zero-is-not-null (export "zero-is-not-null") (result i32) (local $ref (ref null i31)) (local.set $ref (ref.i31 @@ -71,7 +71,7 @@ ;; CHECK: [fuzz-exec] calling trap ;; CHECK-NEXT: [trap null ref] - (func "trap" (result i32) + (func $trap (export "trap") (result i32) (i31.get_u (ref.null i31) ) diff --git a/test/lit/exec/intrinsics.wast b/test/lit/exec/intrinsics.wast index d53082a77bd..c8ae2864338 100644 --- a/test/lit/exec/intrinsics.wast +++ b/test/lit/exec/intrinsics.wast @@ -7,7 +7,7 @@ ;; CHECK: [fuzz-exec] calling get-ref ;; CHECK-NEXT: [fuzz-exec] note result: get-ref => 42 - (func "get-ref" (result i32) + (func $get-ref (export "get-ref") (result i32) (call $cwe (i32.const 41) (ref.func $add-one) @@ -21,4 +21,3 @@ ) ) ) - diff --git a/test/lit/exec/memory.grow.wast b/test/lit/exec/memory.grow.wast index 64d88bfc789..426f4b4c021 100644 --- a/test/lit/exec/memory.grow.wast +++ b/test/lit/exec/memory.grow.wast @@ -7,7 +7,7 @@ ;; CHECK: [fuzz-exec] calling grow_twice ;; CHECK-NEXT: [fuzz-exec] note result: grow_twice => 3 - (func "grow_twice" (result i32) + (func $grow_twice (export "grow_twice") (result i32) ;; The nested grow will increase the size from 1 to 3, and return the old ;; size, 1. Then the outer grow will grow by that amount 1, from 3 to 4. (memory.grow @@ -19,7 +19,7 @@ ;; CHECK: [fuzz-exec] calling measure ;; CHECK-NEXT: [fuzz-exec] note result: measure => 4 - (func "measure" (export "measure") (result i32) + (func $measure (export "measure") (result i32) ;; This should return the final size, 4. (memory.size) ) diff --git a/test/lit/exec/negative-zero.wast b/test/lit/exec/negative-zero.wast index 4a1e339cad3..2c45dbdfb9c 100644 --- a/test/lit/exec/negative-zero.wast +++ b/test/lit/exec/negative-zero.wast @@ -5,7 +5,7 @@ (module ;; CHECK: [fuzz-exec] calling min1 ;; CHECK-NEXT: [fuzz-exec] note result: min1 => -0 - (func "min1" (result f64) + (func $min1 (export "min1") (result f64) ;; This should return -0. (f64.min (f64.const 0) @@ -15,7 +15,7 @@ ;; CHECK: [fuzz-exec] calling min2 ;; CHECK-NEXT: [fuzz-exec] note result: min2 => -0 - (func "min2" (result f64) + (func $min2 (export "min2") (result f64) ;; Flipped arms; still -0. (f64.min (f64.const -0) @@ -25,7 +25,7 @@ ;; CHECK: [fuzz-exec] calling min1-f32 ;; CHECK-NEXT: [fuzz-exec] note result: min1-f32 => -0 - (func "min1-f32" (result f32) + (func $min1-f32 (export "min1-f32") (result f32) ;; As above, but f32 and not f64 (f32.min (f32.const 0) @@ -35,7 +35,7 @@ ;; CHECK: [fuzz-exec] calling min2-f32 ;; CHECK-NEXT: [fuzz-exec] note result: min2-f32 => -0 - (func "min2-f32" (result f32) + (func $min2-f32 (export "min2-f32") (result f32) ;; Flipped arms; still -0. (f32.min (f32.const -0) @@ -45,7 +45,7 @@ ;; CHECK: [fuzz-exec] calling max1 ;; CHECK-NEXT: [fuzz-exec] note result: max1 => 0 - (func "max1" (result f64) + (func $max1 (export "max1") (result f64) ;; This should return 0. (f64.max (f64.const 0) @@ -55,7 +55,7 @@ ;; CHECK: [fuzz-exec] calling max2 ;; CHECK-NEXT: [fuzz-exec] note result: max2 => 0 - (func "max2" (result f64) + (func $max2 (export "max2") (result f64) ;; Flipped arms; still 0. (f64.max (f64.const -0) @@ -65,7 +65,7 @@ ;; CHECK: [fuzz-exec] calling max1-f32 ;; CHECK-NEXT: [fuzz-exec] note result: max1-f32 => 0 - (func "max1-f32" (result f32) + (func $max1-f32 (export "max1-f32") (result f32) ;; As above, but f32 and not f64 (f32.max (f32.const 0) @@ -76,7 +76,7 @@ ;; CHECK: [fuzz-exec] calling max2-f32 ;; CHECK-NEXT: [fuzz-exec] note result: max2-f32 => 0 ;; CHECK-NEXT: warning: no passes specified, not doing any work - (func "max2-f32" (result f32) + (func $max2-f32 (export "max2-f32") (result f32) ;; Flipped arms; still 0. (f32.max (f32.const -0) diff --git a/test/lit/exec/no-compare-refs.wast b/test/lit/exec/no-compare-refs.wast index 95afa51dccc..bfa317a53d9 100644 --- a/test/lit/exec/no-compare-refs.wast +++ b/test/lit/exec/no-compare-refs.wast @@ -13,7 +13,7 @@ ;; signature pruning. The fuzzer should not complain about this. ;; CHECK: [fuzz-exec] calling return-ref ;; CHECK-NEXT: [fuzz-exec] note result: return-ref => funcref - (func "return-ref" (result funcref) + (func $return-ref (export "return-ref") (result funcref) (ref.func $no-use-param) ) ) diff --git a/test/lit/exec/non-nullable.wast b/test/lit/exec/non-nullable.wast index d443947c60b..da71d53ebeb 100644 --- a/test/lit/exec/non-nullable.wast +++ b/test/lit/exec/non-nullable.wast @@ -5,7 +5,7 @@ (module ;; CHECK: [fuzz-exec] calling get-ref ;; CHECK-NEXT: [trap fuzzer can only send defaultable parameters to exports] - (func "get-ref" (param $0 (ref any)) + (func $get-ref (export "get-ref") (param $0 (ref any)) (nop) ) ) diff --git a/test/lit/exec/read-nn-null.wast b/test/lit/exec/read-nn-null.wast index d726889695d..beb2c5c7ec9 100644 --- a/test/lit/exec/read-nn-null.wast +++ b/test/lit/exec/read-nn-null.wast @@ -30,6 +30,12 @@ (module (import "fuzzing-support" "log-i32" (func $log (param i32))) + ;; NORMAL: [fuzz-exec] calling foo + ;; NORMAL-NEXT: [LoggingExternalInterface logging 42] + ;; NORMAL-NEXT: [trap unreachable] + ;; TNH: [fuzz-exec] calling foo + ;; TNH-NEXT: [LoggingExternalInterface logging 42] + ;; TNH-NEXT: [trap unreachable] (func $foo (export "foo") (param $i i32) (result funcref) (local $ref (ref func)) (local.set $ref @@ -55,19 +61,11 @@ ) ) ) -;; NORMAL: [fuzz-exec] calling foo -;; NORMAL-NEXT: [LoggingExternalInterface logging 42] -;; NORMAL-NEXT: [trap unreachable] - ;; NORMAL: [fuzz-exec] calling foo ;; NORMAL-NEXT: [LoggingExternalInterface logging 42] ;; NORMAL-NEXT: [trap unreachable] ;; NORMAL-NEXT: [fuzz-exec] comparing foo -;; TNH: [fuzz-exec] calling foo -;; TNH-NEXT: [LoggingExternalInterface logging 42] -;; TNH-NEXT: [trap unreachable] - ;; TNH: [fuzz-exec] calling foo ;; TNH-NEXT: [LoggingExternalInterface logging 42] ;; TNH-NEXT: [trap unreachable] diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index 320fe5de57c..5460abd2ab0 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -7,7 +7,7 @@ ;; CHECK: [fuzz-exec] calling new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] note result: new_wtf16_array => string("ello") - (func "new_wtf16_array" (result stringref) + (func $new_wtf16_array (export "new_wtf16_array") (result stringref) (string.new_wtf16_array (array.new_fixed $array16 5 (i32.const 104) ;; h @@ -23,13 +23,13 @@ ;; CHECK: [fuzz-exec] calling const ;; CHECK-NEXT: [fuzz-exec] note result: const => string("world") - (func "const" (result stringref) + (func $const (export "const") (result stringref) (string.const "world") ) ;; CHECK: [fuzz-exec] calling eq.1 ;; CHECK-NEXT: [fuzz-exec] note result: eq.1 => 0 - (func "eq.1" (result i32) + (func $eq.1 (export "eq.1") (result i32) (string.eq (string.const "hello") (string.const "world") @@ -38,7 +38,7 @@ ;; CHECK: [fuzz-exec] calling eq.2 ;; CHECK-NEXT: [fuzz-exec] note result: eq.2 => 1 - (func "eq.2" (result i32) + (func $eq.2 (export "eq.2") (result i32) (string.eq (string.const "hello") (string.const "hello") @@ -47,7 +47,7 @@ ;; CHECK: [fuzz-exec] calling eq.3 ;; CHECK-NEXT: [fuzz-exec] note result: eq.3 => 0 - (func "eq.3" (result i32) + (func $eq.3 (export "eq.3") (result i32) (string.eq (string.const "hello") (ref.null string) @@ -56,7 +56,7 @@ ;; CHECK: [fuzz-exec] calling eq.4 ;; CHECK-NEXT: [fuzz-exec] note result: eq.4 => 0 - (func "eq.4" (result i32) + (func $eq.4 (export "eq.4") (result i32) (string.eq (ref.null string) (string.const "world") @@ -65,7 +65,7 @@ ;; CHECK: [fuzz-exec] calling eq.5 ;; CHECK-NEXT: [fuzz-exec] note result: eq.5 => 1 - (func "eq.5" (result i32) + (func $eq.5 (export "eq.5") (result i32) (string.eq (ref.null string) (ref.null string) @@ -74,7 +74,7 @@ ;; CHECK: [fuzz-exec] calling compare.1 ;; CHECK-NEXT: [trap null ref] - (func "compare.1" (result i32) + (func $compare.1 (export "compare.1") (result i32) (string.compare (string.const "hello") (ref.null string) @@ -83,7 +83,7 @@ ;; CHECK: [fuzz-exec] calling compare.2 ;; CHECK-NEXT: [trap null ref] - (func "compare.2" (result i32) + (func $compare.2 (export "compare.2") (result i32) (string.compare (ref.null string) (string.const "world") @@ -92,7 +92,7 @@ ;; CHECK: [fuzz-exec] calling compare.3 ;; CHECK-NEXT: [trap null ref] - (func "compare.3" (result i32) + (func $compare.3 (export "compare.3") (result i32) (string.compare (ref.null string) (ref.null string) @@ -101,7 +101,7 @@ ;; CHECK: [fuzz-exec] calling compare.4 ;; CHECK-NEXT: [fuzz-exec] note result: compare.4 => 0 - (func "compare.4" (result i32) + (func $compare.4 (export "compare.4") (result i32) (string.compare (string.const "hello") (string.const "hello") @@ -110,7 +110,7 @@ ;; CHECK: [fuzz-exec] calling compare.5 ;; CHECK-NEXT: [fuzz-exec] note result: compare.5 => -1 - (func "compare.5" (result i32) + (func $compare.5 (export "compare.5") (result i32) (string.compare (string.const "hello") (string.const "hezlo") @@ -119,7 +119,7 @@ ;; CHECK: [fuzz-exec] calling compare.6 ;; CHECK-NEXT: [fuzz-exec] note result: compare.6 => 1 - (func "compare.6" (result i32) + (func $compare.6 (export "compare.6") (result i32) (string.compare (string.const "hezlo") (string.const "hello") @@ -128,7 +128,7 @@ ;; CHECK: [fuzz-exec] calling compare.7 ;; CHECK-NEXT: [fuzz-exec] note result: compare.7 => -1 - (func "compare.7" (result i32) + (func $compare.7 (export "compare.7") (result i32) (string.compare (string.const "he") (string.const "hello") @@ -137,7 +137,7 @@ ;; CHECK: [fuzz-exec] calling compare.8 ;; CHECK-NEXT: [fuzz-exec] note result: compare.8 => 1 - (func "compare.8" (result i32) + (func $compare.8 (export "compare.8") (result i32) (string.compare (string.const "hello") (string.const "he") @@ -146,7 +146,7 @@ ;; CHECK: [fuzz-exec] calling compare.9 ;; CHECK-NEXT: [fuzz-exec] note result: compare.9 => 1 - (func "compare.9" (result i32) + (func $compare.9 (export "compare.9") (result i32) (string.compare (string.const "hf") (string.const "hello") @@ -155,7 +155,7 @@ ;; CHECK: [fuzz-exec] calling compare.10 ;; CHECK-NEXT: [fuzz-exec] note result: compare.10 => -1 - (func "compare.10" (result i32) + (func $compare.10 (export "compare.10") (result i32) (string.compare (string.const "hello") (string.const "hf") diff --git a/test/lit/merge/table_elem.wat b/test/lit/merge/table_elem.wat index c7505d0eec8..8177cd75d79 100644 --- a/test/lit/merge/table_elem.wat +++ b/test/lit/merge/table_elem.wat @@ -29,7 +29,39 @@ ;; CHECK: (elem $b (table $bar) (i32.const 0) func) (elem $b (table $bar) (i32.const 0) func) - (func "keepalive2" + ;; CHECK: (elem $a_2 (table $foo_2) (i32.const 0) func) + + ;; CHECK: (elem $b_2 (table $other) (i32.const 0) func) + + ;; CHECK: (export "keepalive2" (func $keepalive2)) + + ;; CHECK: (export "keepalive2_1" (func $keepalive2_1)) + + ;; CHECK: (func $keepalive2 (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (table.get $foo + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (table.get $bar + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $vec $a + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $vec $b + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $keepalive2 (export "keepalive2") (drop (table.get $foo (i32.const 1) @@ -55,40 +87,7 @@ ) ) ) -;; CHECK: (elem $a_2 (table $foo_2) (i32.const 0) func) - -;; CHECK: (elem $b_2 (table $other) (i32.const 0) func) - -;; CHECK: (export "keepalive2" (func $0)) - -;; CHECK: (export "keepalive2_1" (func $0_1)) - -;; CHECK: (func $0 (type $1) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (table.get $foo -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (table.get $bar -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (array.new_elem $vec $a -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: (i32.const 2) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (array.new_elem $vec $b -;; CHECK-NEXT: (i32.const 3) -;; CHECK-NEXT: (i32.const 4) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $0_1 (type $1) +;; CHECK: (func $keepalive2_1 (type $1) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.get $foo_2 ;; CHECK-NEXT: (i32.const 1) diff --git a/test/lit/merge/table_elem.wat.second b/test/lit/merge/table_elem.wat.second index 7aa960c7f2b..c186e6b16c6 100644 --- a/test/lit/merge/table_elem.wat.second +++ b/test/lit/merge/table_elem.wat.second @@ -9,7 +9,7 @@ (elem $b (table $other) (i32.const 0) func) - (func "keepalive2" + (func $keepalive2 (export "keepalive2") (drop (table.get $foo (i32.const 1) diff --git a/test/lit/passes/O1.wast b/test/lit/passes/O1.wast index 516c9b2ee59..8ffc2930148 100644 --- a/test/lit/passes/O1.wast +++ b/test/lit/passes/O1.wast @@ -9,7 +9,17 @@ ;; CHECK: (memory $0 1 1) (memory $0 1 1) (global $global$0 (mut i32) (i32.const 10)) - (func "foo" (result i32) + ;; CHECK: (export "foo" (func $foo)) + + ;; CHECK: (func $foo (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load align=1 + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $foo (export "foo") (result i32) (i32.load offset=4 align=1 (i32.and (block $label$1 (result i32) @@ -31,13 +41,3 @@ ) -;; CHECK: (export "foo" (func $0)) - -;; CHECK: (func $0 (result i32) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.load align=1 -;; CHECK-NEXT: (i32.const 4) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/O1_skip.wast b/test/lit/passes/O1_skip.wast index d4eef7c843e..2cefecdcf98 100644 --- a/test/lit/passes/O1_skip.wast +++ b/test/lit/passes/O1_skip.wast @@ -14,7 +14,7 @@ ;; CHECK: (import "a" "b" (func $log (param i32 i32))) (import "a" "b" (func $log (param i32 i32))) - (func "foo" (param $p i32) + (func $foo (export "foo") (param $p i32) ;; The locals $x and $y can be coalesced into a single local, but as we do not ;; run that pass, they will not be. Other minor optimizations will occur here, ;; such as using a tee. @@ -44,9 +44,9 @@ ) ) ) -;; CHECK: (export "foo" (func $0)) +;; CHECK: (export "foo" (func $foo)) -;; CHECK: (func $0 (; has Stack IR ;) (param $p i32) +;; CHECK: (func $foo (; has Stack IR ;) (param $p i32) ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (call $log diff --git a/test/lit/passes/O3_Oz.wast b/test/lit/passes/O3_Oz.wast index 4dca886acaa..48345663e65 100644 --- a/test/lit/passes/O3_Oz.wast +++ b/test/lit/passes/O3_Oz.wast @@ -10,7 +10,22 @@ ) ) - (func "export" (param $x i32) (result i32) + ;; CHECK: (type $0 (func (param i32) (result i32))) + + ;; CHECK: (export "export" (func $export)) + + ;; CHECK: (func $export (; has Stack IR ;) (param $0 i32) (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $export (export "export") (param $x i32) (result i32) ;; $inline.me is called twice, so we do not always inline it like called- ;; once functions are. -Oz is too cautious to inline such things that may ;; end up increasing total code size, but we are running -O3 -Oz here and so @@ -28,18 +43,3 @@ ) ) ) -;; CHECK: (type $0 (func (param i32) (result i32))) - -;; CHECK: (export "export" (func $1)) - -;; CHECK: (func $1 (; has Stack IR ;) (param $0 i32) (result i32) -;; CHECK-NEXT: (i32.add -;; CHECK-NEXT: (local.tee $0 -;; CHECK-NEXT: (i32.add -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (i32.const 2) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/O_fast-math.wast b/test/lit/passes/O_fast-math.wast index bff7553a344..722f44a05c4 100644 --- a/test/lit/passes/O_fast-math.wast +++ b/test/lit/passes/O_fast-math.wast @@ -5,73 +5,129 @@ ;; with fast-math we can optimize some of these patterns (module - (func "div" (result f32) + ;; CHECK: (type $0 (func (result f32))) + + ;; CHECK: (type $1 (func (param f32) (result f32))) + + ;; CHECK: (type $2 (func (param f64) (result f64))) + + ;; CHECK: (export "div" (func $div)) + + ;; CHECK: (export "mul1" (func $mul1)) + + ;; CHECK: (export "mul2" (func $mul2)) + + ;; CHECK: (export "add1" (func $mul1)) + + ;; CHECK: (export "add2" (func $mul2)) + + ;; CHECK: (export "add3" (func $mul2)) + + ;; CHECK: (export "add4" (func $mul2)) + + ;; CHECK: (export "sub1" (func $mul1)) + + ;; CHECK: (export "sub2" (func $mul2)) + + ;; CHECK: (export "mul_neg_one1" (func $mul_neg_one1)) + + ;; CHECK: (export "mul_neg_one2" (func $mul_neg_one2)) + + ;; CHECK: (export "abs_sub_zero1" (func $abs_sub_zero1)) + + ;; CHECK: (export "abs_sub_zero2" (func $abs_sub_zero2)) + + ;; CHECK: (func $div (; has Stack IR ;) (result f32) + ;; CHECK-NEXT: (f32.const -nan:0x23017a) + ;; CHECK-NEXT: ) + (func $div (export "div") (result f32) (f32.div (f32.const -nan:0x23017a) (f32.const 1) ) ) - (func "mul1" (result f32) + ;; CHECK: (func $mul1 (; has Stack IR ;) (result f32) + ;; CHECK-NEXT: (f32.const -nan:0x34546d) + ;; CHECK-NEXT: ) + (func $mul1 (export "mul1") (result f32) (f32.mul (f32.const -nan:0x34546d) (f32.const 1) ) ) - (func "mul2" (result f32) + ;; CHECK: (func $mul2 (; has Stack IR ;) (result f32) + ;; CHECK-NEXT: (f32.const nan:0x400000) + ;; CHECK-NEXT: ) + (func $mul2 (export "mul2") (result f32) (f32.mul (f32.const 1) (f32.const -nan:0x34546d) ) ) - (func "add1" (result f32) + (func $add1 (export "add1") (result f32) (f32.add (f32.const -nan:0x34546d) (f32.const -0) ) ) - (func "add2" (result f32) + (func $add2 (export "add2") (result f32) (f32.add (f32.const -0) (f32.const -nan:0x34546d) ) ) - (func "add3" (result f32) + (func $add3 (export "add3") (result f32) (f32.add (f32.const -nan:0x34546d) (f32.const 0) ) ) - (func "add4" (result f32) + (func $add4 (export "add4") (result f32) (f32.add (f32.const 0) (f32.const -nan:0x34546d) ) ) - (func "sub1" (result f32) + (func $sub1 (export "sub1") (result f32) (f32.sub (f32.const -nan:0x34546d) (f32.const 0) ) ) - (func "sub2" (result f32) + (func $sub2 (export "sub2") (result f32) (f32.sub (f32.const -nan:0x34546d) (f32.const -0) ) ) - (func "mul_neg_one1" (param $x f32) (result f32) + ;; CHECK: (func $mul_neg_one1 (; has Stack IR ;) (param $0 f32) (result f32) + ;; CHECK-NEXT: (f32.neg + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $mul_neg_one1 (export "mul_neg_one1") (param $x f32) (result f32) (f32.mul (local.get $x) (f32.const -1) ) ) - (func "mul_neg_one2" (param $x f64) (result f64) + ;; CHECK: (func $mul_neg_one2 (; has Stack IR ;) (param $0 f64) (result f64) + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $mul_neg_one2 (export "mul_neg_one2") (param $x f64) (result f64) (f64.mul (local.get $x) (f64.const -1) ) ) - (func "abs_sub_zero1" (param $x f32) (result f32) + ;; CHECK: (func $abs_sub_zero1 (; has Stack IR ;) (param $0 f32) (result f32) + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $abs_sub_zero1 (export "abs_sub_zero1") (param $x f32) (result f32) ;; abs(0 - x) ==> abs(x) (f32.abs (f32.sub @@ -80,7 +136,12 @@ ) ) ) - (func "abs_sub_zero2" (param $x f64) (result f64) + ;; CHECK: (func $abs_sub_zero2 (; has Stack IR ;) (param $0 f64) (result f64) + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $abs_sub_zero2 (export "abs_sub_zero2") (param $x f64) (result f64) ;; abs(0 - x) ==> abs(x) (f64.abs (f64.sub @@ -90,70 +151,3 @@ ) ) ) -;; CHECK: (type $0 (func (result f32))) - -;; CHECK: (type $1 (func (param f32) (result f32))) - -;; CHECK: (type $2 (func (param f64) (result f64))) - -;; CHECK: (export "div" (func $0)) - -;; CHECK: (export "mul1" (func $1)) - -;; CHECK: (export "mul2" (func $2)) - -;; CHECK: (export "add1" (func $1)) - -;; CHECK: (export "add2" (func $2)) - -;; CHECK: (export "add3" (func $2)) - -;; CHECK: (export "add4" (func $2)) - -;; CHECK: (export "sub1" (func $1)) - -;; CHECK: (export "sub2" (func $2)) - -;; CHECK: (export "mul_neg_one1" (func $9)) - -;; CHECK: (export "mul_neg_one2" (func $10)) - -;; CHECK: (export "abs_sub_zero1" (func $11)) - -;; CHECK: (export "abs_sub_zero2" (func $12)) - -;; CHECK: (func $0 (; has Stack IR ;) (result f32) -;; CHECK-NEXT: (f32.const -nan:0x23017a) -;; CHECK-NEXT: ) - -;; CHECK: (func $1 (; has Stack IR ;) (result f32) -;; CHECK-NEXT: (f32.const -nan:0x34546d) -;; CHECK-NEXT: ) - -;; CHECK: (func $2 (; has Stack IR ;) (result f32) -;; CHECK-NEXT: (f32.const nan:0x400000) -;; CHECK-NEXT: ) - -;; CHECK: (func $9 (; has Stack IR ;) (param $0 f32) (result f32) -;; CHECK-NEXT: (f32.neg -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $10 (; has Stack IR ;) (param $0 f64) (result f64) -;; CHECK-NEXT: (f64.neg -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $11 (; has Stack IR ;) (param $0 f32) (result f32) -;; CHECK-NEXT: (f32.abs -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $12 (; has Stack IR ;) (param $0 f64) (result f64) -;; CHECK-NEXT: (f64.abs -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast index 2f55e401249..51e97456c05 100644 --- a/test/lit/passes/dae-gc-refine-params.wast +++ b/test/lit/passes/dae-gc-refine-params.wast @@ -21,12 +21,12 @@ ;; CHECK: (func $call-various-params-no (type $0) ;; CHECK-NEXT: (call $various-params-no - ;; CHECK-NEXT: (call $get_{}) - ;; CHECK-NEXT: (call $get_{i32}) + ;; CHECK-NEXT: (call $"get_{}") + ;; CHECK-NEXT: (call $"get_{i32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $various-params-no - ;; CHECK-NEXT: (call $get_{i32}) - ;; CHECK-NEXT: (call $get_{f64}) + ;; CHECK-NEXT: (call $"get_{i32}") + ;; CHECK-NEXT: (call $"get_{f64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-various-params-no @@ -59,35 +59,26 @@ (drop (local.get $y)) ) - ;; CHECK: (func $get_{} (type $8) (result (ref null ${})) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) (func $get_{} (result (ref null ${})) (unreachable) ) - ;; CHECK: (func $get_{i32} (type $5) (result (ref null ${i32})) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) (func $get_{i32} (result (ref null ${i32})) (unreachable) ) - ;; CHECK: (func $get_{f64} (type $10) (result (ref null ${f64})) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) (func $get_{f64} (result (ref null ${f64})) (unreachable) ) ;; CHECK: (func $call-various-params-yes (type $0) ;; CHECK-NEXT: (call $various-params-yes - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $various-params-yes - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $get_null_{i32_i64}) + ;; CHECK-NEXT: (call $"get_null_{i32_i64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-various-params-yes @@ -127,12 +118,12 @@ ;; CHECK: (func $call-various-params-set (type $0) ;; CHECK-NEXT: (call $various-params-set - ;; CHECK-NEXT: (call $get_null_{i32}) - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $various-params-set - ;; CHECK-NEXT: (call $get_null_{i32}) - ;; CHECK-NEXT: (call $get_null_{i32_i64}) + ;; CHECK-NEXT: (call $"get_null_{i32}") + ;; CHECK-NEXT: (call $"get_null_{i32_i64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-various-params-set @@ -169,7 +160,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $y - ;; CHECK-NEXT: (call $get_null_{i32_i64}) + ;; CHECK-NEXT: (call $"get_null_{i32_i64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $y) @@ -198,7 +189,7 @@ ;; CHECK: (func $call-various-params-tee (type $0) ;; CHECK-NEXT: (call $various-params-tee - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-various-params-tee @@ -214,7 +205,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref null ${i32})) ;; CHECK-NEXT: (local.tee $x - ;; CHECK-NEXT: (call $get_null_{i32_i64}) + ;; CHECK-NEXT: (call $"get_null_{i32_i64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -237,7 +228,7 @@ ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $get_null_{i32}) + ;; CHECK-NEXT: (call $"get_null_{i32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $various-params-null ;; CHECK-NEXT: (ref.as_non_null @@ -288,10 +279,10 @@ ;; CHECK: (func $call-various-params-middle (type $0) ;; CHECK-NEXT: (call $various-params-middle - ;; CHECK-NEXT: (call $get_null_{i32_i64}) + ;; CHECK-NEXT: (call $"get_null_{i32_i64}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $various-params-middle - ;; CHECK-NEXT: (call $get_null_{i32_f32}) + ;; CHECK-NEXT: (call $"get_null_{i32_f32}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-various-params-middle @@ -399,13 +390,6 @@ (drop (local.get $x)) ) - ;; CHECK: (func $get_null_{i32} (type $5) (result (ref null ${i32})) - ;; CHECK-NEXT: (select (result (ref null ${i32})) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (struct.new_default ${i32}) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) (func $get_null_{i32} (result (ref null ${i32})) ;; Helper function that returns a null value of ${i32}. We use this instead of ;; a direct ref.null because those can be rewritten by LUBFinder. @@ -416,13 +400,6 @@ ) ) - ;; CHECK: (func $get_null_{i32_i64} (type $16) (result (ref null ${i32_i64})) - ;; CHECK-NEXT: (select (result (ref null ${i32_i64})) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (struct.new_default ${i32_i64}) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) (func $get_null_{i32_i64} (result (ref null ${i32_i64})) (select (ref.null none) @@ -431,13 +408,6 @@ ) ) - ;; CHECK: (func $get_null_{i32_f32} (type $17) (result (ref null ${i32_f32})) - ;; CHECK-NEXT: (select (result (ref null ${i32_f32})) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (struct.new_default ${i32_f32}) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) (func $get_null_{i32_f32} (result (ref null ${i32_f32})) (select (ref.null none) diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast index 806683a628b..aa474d7f393 100644 --- a/test/lit/passes/dae-gc-refine-return.wast +++ b/test/lit/passes/dae-gc-refine-return.wast @@ -395,9 +395,9 @@ (unreachable) ) ;; CHECK: (func $tail-caller-call_ref-yes (type $return_{}) (result (ref ${})) - ;; CHECK-NEXT: (local $return_{} (ref null $return_{})) + ;; CHECK-NEXT: (local $"return_{}" (ref null $return_{})) ;; CHECK-NEXT: (return_call_ref $return_{} - ;; CHECK-NEXT: (local.get $return_{}) + ;; CHECK-NEXT: (local.get $"return_{}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $tail-caller-call_ref-yes (result anyref) @@ -407,7 +407,7 @@ ) ;; CHECK: (func $tail-caller-call_ref-no (type $2) (result anyref) ;; CHECK-NEXT: (local $any anyref) - ;; CHECK-NEXT: (local $return_{} (ref null $return_{})) + ;; CHECK-NEXT: (local $"return_{}" (ref null $return_{})) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (return @@ -415,7 +415,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_ref $return_{} - ;; CHECK-NEXT: (local.get $return_{}) + ;; CHECK-NEXT: (local.get $"return_{}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $tail-caller-call_ref-no (result anyref) diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast index dee38f64638..17626c953f8 100644 --- a/test/lit/passes/dae_all-features.wast +++ b/test/lit/passes/dae_all-features.wast @@ -361,21 +361,20 @@ ) ) (module ;; both operations at once: remove params and return value - (func "a" + ;; CHECK: (type $0 (func)) + + ;; CHECK: (export "a" (func $a)) + + ;; CHECK: (func $a (type $0) + ;; CHECK-NEXT: (call $b) + ;; CHECK-NEXT: ) + (func $a (export "a") (drop (call $b (i32.const 1) ) ) ) - ;; CHECK: (type $0 (func)) - - ;; CHECK: (export "a" (func $0)) - - ;; CHECK: (func $0 (type $0) - ;; CHECK-NEXT: (call $b) - ;; CHECK-NEXT: ) - ;; CHECK: (func $b (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (drop @@ -467,7 +466,7 @@ ;; CHECK: (elem declare func $0) - ;; CHECK: (export "export" (func $1)) + ;; CHECK: (export "export" (func $export)) ;; CHECK: (func $0 (type $0) (param $0 funcref) (param $1 i32) (param $2 f64) (result i64) ;; CHECK-NEXT: (nop) @@ -477,15 +476,15 @@ (nop) (unreachable) ) - (func "export" (param $0 f32) (result funcref) + ;; CHECK: (func $export (type $1) (param $0 f32) (result funcref) + ;; CHECK-NEXT: (ref.func $0) + ;; CHECK-NEXT: ) + (func $export (export "export") (param $0 f32) (result funcref) ;; a ref.func should prevent us from changing the type of a function, as it ;; may escape (ref.func $0) ) ) -;; CHECK: (func $1 (type $1) (param $0 f32) (result funcref) -;; CHECK-NEXT: (ref.func $0) -;; CHECK-NEXT: ) (module ;; CHECK: (type $i64 (func (param i64))) (type $i64 (func (param i64))) diff --git a/test/lit/passes/flatten_all-features.wast b/test/lit/passes/flatten_all-features.wast index 5ae10ac1469..3ce8496863e 100644 --- a/test/lit/passes/flatten_all-features.wast +++ b/test/lit/passes/flatten_all-features.wast @@ -3481,7 +3481,7 @@ ;; CHECK: (type $1 (func (result i32))) - ;; CHECK: (export "test" (func $1)) + ;; CHECK: (export "test" (func $test)) ;; CHECK: (func $0 (type $0) (param $0 i64) (param $1 f32) ;; CHECK-NEXT: (nop) @@ -3489,7 +3489,18 @@ (func $0 (param $0 i64) (param $1 f32) (nop) ) - (func "test" (result i32) + ;; CHECK: (func $test (type $1) (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const -111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $0 + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $test (export "test") (result i32) (call $0 (unreachable) ;; the unreachable should be handled properly, and not be ;; reordered with the return @@ -3501,17 +3512,6 @@ ) ;; non-nullable temp vars we add must be handled properly, as non-nullable ;; locals are not allowed -;; CHECK: (func $1 (type $1) (result i32) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -111) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $0 -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) (module (type $none_=>_none (func)) ;; CHECK: (type $0 (func (result funcref))) diff --git a/test/lit/passes/flatten_dfo_O3_enable-threads.wast b/test/lit/passes/flatten_dfo_O3_enable-threads.wast index 7aa7df592d7..55bf54dc911 100644 --- a/test/lit/passes/flatten_dfo_O3_enable-threads.wast +++ b/test/lit/passes/flatten_dfo_O3_enable-threads.wast @@ -16,7 +16,29 @@ ;; CHECK: (memory $0 (shared 1 1)) (memory $0 (shared 1 1)) - (func "one" + ;; CHECK: (export "one" (func $one)) + + ;; CHECK: (export "two" (func $two)) + + ;; CHECK: (export "use-var" (func $use-var)) + + ;; CHECK: (export "bad1" (func $bad1)) + + ;; CHECK: (export "only-dfo" (func $only-dfo)) + + ;; CHECK: (export "dfo-tee-get" (func $dfo-tee-get)) + + ;; CHECK: (func $one (; has Stack IR ;) + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (br_if $label$3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 3060) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $one (export "one") (loop $label$2 (br_if $label$2 (block $label$3 (result i32) @@ -34,7 +56,10 @@ ) (unreachable) ) - (func "two" (param $var$0 i32) (param $var$1 i32) (result i32) + ;; CHECK: (func $two (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $two (export "two") (param $var$0 i32) (param $var$1 i32) (result i32) (nop) (nop) (nop) @@ -81,7 +106,15 @@ (nop) (i32.const 0) ) - (func "use-var" (param $var$0 i64) (param $var$1 i32) (result f64) + ;; CHECK: (func $use-var (; has Stack IR ;) (param $0 i64) (param $1 i32) (result f64) + ;; CHECK-NEXT: (loop $label$8 + ;; CHECK-NEXT: (br_if $label$8 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $use-var (export "use-var") (param $var$0 i64) (param $var$1 i32) (result f64) (local $var$2 i32) (block $label$1 (br_table $label$1 $label$1 $label$1 $label$1 $label$1 $label$1 $label$1 $label$1 $label$1 $label$1 @@ -133,7 +166,13 @@ ) (unreachable) ) - (func "bad1" + ;; CHECK: (func $bad1 (; has Stack IR ;) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const -16384) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $bad1 (export "bad1") (local $var$2 i32) (local $var$4 i32) (block $label$1 @@ -175,7 +214,13 @@ ) ) ) - (func "only-dfo" (param $var$0 f64) (result f64) + ;; CHECK: (func $only-dfo (; has Stack IR ;) (param $0 f64) (result f64) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $label$1 + ;; CHECK-NEXT: (br $label$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $only-dfo (export "only-dfo") (param $var$0 f64) (result f64) (local $var$1 i32) (local $var$2 i32) (loop $label$1 @@ -199,7 +244,10 @@ (br $label$1) ) ) - (func "dfo-tee-get" (result i32) + ;; CHECK: (func $dfo-tee-get (; has Stack IR ;) (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $dfo-tee-get (export "dfo-tee-get") (result i32) (local $0 i32) (if (result i32) (local.tee $0 @@ -217,56 +265,3 @@ ) ) -;; CHECK: (export "one" (func $0)) - -;; CHECK: (export "two" (func $1)) - -;; CHECK: (export "use-var" (func $2)) - -;; CHECK: (export "bad1" (func $3)) - -;; CHECK: (export "only-dfo" (func $4)) - -;; CHECK: (export "dfo-tee-get" (func $5)) - -;; CHECK: (func $0 (; has Stack IR ;) -;; CHECK-NEXT: (block $label$3 -;; CHECK-NEXT: (br_if $label$3 -;; CHECK-NEXT: (i32.load -;; CHECK-NEXT: (i32.const 3060) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) - -;; CHECK: (func $1 (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) - -;; CHECK: (func $2 (; has Stack IR ;) (param $0 i64) (param $1 i32) (result f64) -;; CHECK-NEXT: (loop $label$8 -;; CHECK-NEXT: (br_if $label$8 -;; CHECK-NEXT: (local.get $1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) - -;; CHECK: (func $3 (; has Stack IR ;) -;; CHECK-NEXT: (i32.store -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: (i32.const -16384) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $4 (; has Stack IR ;) (param $0 f64) (result f64) -;; CHECK-NEXT: (local $1 i32) -;; CHECK-NEXT: (loop $label$1 -;; CHECK-NEXT: (br $label$1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $5 (; has Stack IR ;) (result i32) -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/flatten_i64-to-i32-lowering.wast b/test/lit/passes/flatten_i64-to-i32-lowering.wast index ade1d1e58bd..16ebaf8829b 100644 --- a/test/lit/passes/flatten_i64-to-i32-lowering.wast +++ b/test/lit/passes/flatten_i64-to-i32-lowering.wast @@ -472,19 +472,96 @@ ;; CHECK: (global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0)) - ;; CHECK: (export "exp" (func $1)) + ;; CHECK: (export "exp" (func $exp)) - ;; CHECK: (export "unreach" (func $2)) + ;; CHECK: (export "unreach" (func $unreach)) ;; CHECK: (func $call (type $1) (param $0 i32) (param $0$hi i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $call (param i64)) - (func "exp" + ;; CHECK: (func $exp (type $0) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $0$hi i32) + ;; CHECK-NEXT: (local $i64toi32_i32$0 i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (global.get $f$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $f) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $call + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (local.get $0$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (global.set $f + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (i32.const 287454020) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1432778632) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $f$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $exp (export "exp") (call $call (global.get $f)) (global.set $f (i64.const 0x1122334455667788)) ) - (func "unreach" + ;; CHECK: (func $unreach (type $0) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $0$hi i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $1$hi i32) + ;; CHECK-NEXT: (local $i64toi32_i32$0 i32) + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (local.get $0$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (global.set $f + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (local.get $1$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $f$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unreach (export "unreach") (global.set $f (block $label$1 (result i64) (unreachable) @@ -492,84 +569,6 @@ ) ) ) -;; CHECK: (func $1 (type $0) -;; CHECK-NEXT: (local $0 i32) -;; CHECK-NEXT: (local $0$hi i32) -;; CHECK-NEXT: (local $i64toi32_i32$0 i32) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (local.set $0 -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (global.get $f$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.get $f) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.set $0$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $call -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (local.get $0$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (global.set $f -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (i32.const 287454020) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const 1432778632) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $f$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) - -;; CHECK: (func $2 (type $0) -;; CHECK-NEXT: (local $0 i32) -;; CHECK-NEXT: (local $0$hi i32) -;; CHECK-NEXT: (local $1 i32) -;; CHECK-NEXT: (local $1$hi i32) -;; CHECK-NEXT: (local $i64toi32_i32$0 i32) -;; CHECK-NEXT: (block $label$1 -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (local.set $1 -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (local.get $0$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.set $1$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (global.set $f -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (local.get $1$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $f$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) (module ;; CHECK: (type $0 (func (param i32 i32))) @@ -581,57 +580,57 @@ ;; CHECK: (global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0)) - ;; CHECK: (export "exp" (func $1)) + ;; CHECK: (export "exp" (func $exp)) ;; CHECK: (func $call (type $0) (param $0 i32) (param $0$hi i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $call (param i64)) - (func "exp" + ;; CHECK: (func $exp (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $0$hi i32) + ;; CHECK-NEXT: (local $i64toi32_i32$0 i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (global.get $f$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $f) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $call + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (local.get $0$hi) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (global.set $f + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (local.set $i64toi32_i32$0 + ;; CHECK-NEXT: (i32.const 287454020) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1432778632) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $f$hi + ;; CHECK-NEXT: (local.get $i64toi32_i32$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $exp (export "exp") (call $call (global.get $f)) (global.set $f (i64.const 0x1122334455667788)) ) ) -;; CHECK: (func $1 (type $1) -;; CHECK-NEXT: (local $0 i32) -;; CHECK-NEXT: (local $0$hi i32) -;; CHECK-NEXT: (local $i64toi32_i32$0 i32) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (local.set $0 -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (global.get $f$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.get $f) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.set $0$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $call -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (local.get $0$hi) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (global.set $f -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (local.set $i64toi32_i32$0 -;; CHECK-NEXT: (i32.const 287454020) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const 1432778632) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $f$hi -;; CHECK-NEXT: (local.get $i64toi32_i32$0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) (module (type $i64_f64_i32_=>_none (func (param i64 f64 i32))) ;; CHECK: (type $0 (func)) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast index db92b688d39..011ea86e9e5 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast @@ -5,7 +5,30 @@ (module (memory 1) - (func "if-select" + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (result f64))) + + ;; CHECK: (type $2 (func (param i32 f64 f64) (result i32))) + + ;; CHECK: (type $3 (func (param i64))) + + ;; CHECK: (type $4 (func (param f64) (result i32))) + + ;; CHECK: (export "if-select" (func $if-select)) + + ;; CHECK: (export "unreachable-body-update-zext" (func $unreachable-body-update-zext)) + + ;; CHECK: (export "ssa-const" (func $ssa-const)) + + ;; CHECK: (export "if-nothing" (func $if-nothing)) + + ;; CHECK: (export "only-dfo" (func $only-dfo)) + + ;; CHECK: (func $if-select (; has Stack IR ;) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $if-select (export "if-select") (local $var$0 i32) (nop) (drop @@ -20,7 +43,10 @@ ) ) ) - (func "unreachable-body-update-zext" (result f64) + ;; CHECK: (func $unreachable-body-update-zext (; has Stack IR ;) (result f64) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $unreachable-body-update-zext (export "unreachable-body-update-zext") (result f64) (if (i32.eqz (i32.const 0) @@ -29,7 +55,10 @@ ) (f64.const -9223372036854775808) ) - (func "ssa-const" (param $var$0 i32) (param $var$1 f64) (param $var$2 f64) (result i32) + ;; CHECK: (func $ssa-const (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $ssa-const (export "ssa-const") (param $var$0 i32) (param $var$1 f64) (param $var$2 f64) (result i32) (block $label$1 (result i32) (block $label$2 (if @@ -59,7 +88,10 @@ ) ) ) - (func "if-nothing" (param $var$0 i64) + ;; CHECK: (func $if-nothing (; has Stack IR ;) (param $0 i64) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $if-nothing (export "if-nothing") (param $var$0 i64) (local $var$1 i32) (local $var$2 i32) (block $label$1 @@ -83,7 +115,24 @@ (unreachable) ) ) - (func "only-dfo" (param $var$0 f64) (result i32) + ;; CHECK: (func $only-dfo (; has Stack IR ;) (param $0 f64) (result i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $label$1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -2766) + ;; CHECK-NEXT: ) + (func $only-dfo (export "only-dfo") (param $var$0 f64) (result i32) (local $var$1 i32) (local $var$2 i32) (local $var$3 i32) @@ -116,56 +165,3 @@ ) ) -;; CHECK: (type $0 (func)) - -;; CHECK: (type $1 (func (result f64))) - -;; CHECK: (type $2 (func (param i32 f64 f64) (result i32))) - -;; CHECK: (type $3 (func (param i64))) - -;; CHECK: (type $4 (func (param f64) (result i32))) - -;; CHECK: (export "if-select" (func $0)) - -;; CHECK: (export "unreachable-body-update-zext" (func $1)) - -;; CHECK: (export "ssa-const" (func $2)) - -;; CHECK: (export "if-nothing" (func $3)) - -;; CHECK: (export "only-dfo" (func $4)) - -;; CHECK: (func $0 (; has Stack IR ;) -;; CHECK-NEXT: (nop) -;; CHECK-NEXT: ) - -;; CHECK: (func $1 (; has Stack IR ;) (result f64) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) - -;; CHECK: (func $2 (; has Stack IR ;) (param $0 i32) (param $1 f64) (param $2 f64) (result i32) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) - -;; CHECK: (func $3 (; has Stack IR ;) (param $0 i64) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) - -;; CHECK: (func $4 (; has Stack IR ;) (param $0 f64) (result i32) -;; CHECK-NEXT: (local $1 i32) -;; CHECK-NEXT: (loop $label$1 -;; CHECK-NEXT: (if -;; CHECK-NEXT: (i32.eqz -;; CHECK-NEXT: (local.get $1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (local.set $1 -;; CHECK-NEXT: (i32.const -2147483648) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (br $label$1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const -2766) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast index 2b17886b75b..0bcc36de280 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast @@ -33,7 +33,7 @@ ;; CHECK: (memory $0 (shared 1 1)) (memory $0 (shared 1 1)) ;; Figure 1a from the Souper paper https://arxiv.org/pdf/1711.04422.pdf - ;; CHECK: (export "replaced-print-internal" (func $55)) + ;; CHECK: (export "replaced-print-internal" (func $replaced-print-internal)) ;; CHECK: (func $figure-1a (param $a i64) (param $x i64) (param $y i64) (result i32) ;; CHECK-NEXT: (local $i i32) @@ -3827,48 +3827,7 @@ ) ) ) - (func "replaced-print-internal" (param $var$0 i32) - (local $var$1 i32) - (local $var$2 i32) - (local $var$3 i32) - (if - (local.tee $var$0 - (i32.add - (local.get $var$0) - (i32.const -7) - ) - ) - (block $label$2 - (block $label$3 - (local.set $var$1 - (local.get $var$0) - ) - (br_if $label$3 - (local.tee $var$3 - (i32.const 12) - ) - ) - (unreachable) - ) - (br_if $label$2 - (i32.eqz - (local.get $var$1) - ) - ) - (if - (i32.ne - (i32.load - (i32.const 0) - ) - (local.get $var$0) - ) - (unreachable) - ) - (unreachable) - ) - ) - ) - ;; CHECK: (func $55 (param $var$0 i32) + ;; CHECK: (func $replaced-print-internal (param $var$0 i32) ;; CHECK-NEXT: (local $var$1 i32) ;; CHECK-NEXT: (local $var$2 i32) ;; CHECK-NEXT: (local $var$3 i32) @@ -3944,7 +3903,47 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - + (func $replaced-print-internal (export "replaced-print-internal") (param $var$0 i32) + (local $var$1 i32) + (local $var$2 i32) + (local $var$3 i32) + (if + (local.tee $var$0 + (i32.add + (local.get $var$0) + (i32.const -7) + ) + ) + (block $label$2 + (block $label$3 + (local.set $var$1 + (local.get $var$0) + ) + (br_if $label$3 + (local.tee $var$3 + (i32.const 12) + ) + ) + (unreachable) + ) + (br_if $label$2 + (i32.eqz + (local.get $var$1) + ) + ) + (if + (i32.ne + (i32.load + (i32.const 0) + ) + (local.get $var$0) + ) + (unreachable) + ) + (unreachable) + ) + ) + ) ;; CHECK: (func $multiple-uses-to-non-expression (param $x i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: (local $2 i32) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast index e53bd44b48b..61430d653c0 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast @@ -33,7 +33,7 @@ ;; CHECK: (memory $0 (shared 1 1)) (memory $0 (shared 1 1)) ;; Figure 1a from the Souper paper https://arxiv.org/pdf/1711.04422.pdf - ;; CHECK: (export "replaced-print-internal" (func $56)) + ;; CHECK: (export "replaced-print-internal" (func $replaced-print-internal)) ;; CHECK: (func $figure-1a (param $a i64) (param $x i64) (param $y i64) (result i32) ;; CHECK-NEXT: (local $i i32) @@ -3895,48 +3895,7 @@ ) ) ) - (func "replaced-print-internal" (param $var$0 i32) - (local $var$1 i32) - (local $var$2 i32) - (local $var$3 i32) - (if - (local.tee $var$0 - (i32.add - (local.get $var$0) - (i32.const -7) - ) - ) - (block $label$2 - (block $label$3 - (local.set $var$1 - (local.get $var$0) - ) - (br_if $label$3 - (local.tee $var$3 - (i32.const 12) - ) - ) - (unreachable) - ) - (br_if $label$2 - (i32.eqz - (local.get $var$1) - ) - ) - (if - (i32.ne - (i32.load - (i32.const 0) - ) - (local.get $var$0) - ) - (unreachable) - ) - (unreachable) - ) - ) - ) - ;; CHECK: (func $56 (param $var$0 i32) + ;; CHECK: (func $replaced-print-internal (param $var$0 i32) ;; CHECK-NEXT: (local $var$1 i32) ;; CHECK-NEXT: (local $var$2 i32) ;; CHECK-NEXT: (local $var$3 i32) @@ -4012,7 +3971,47 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - + (func $replaced-print-internal (export "replaced-print-internal") (param $var$0 i32) + (local $var$1 i32) + (local $var$2 i32) + (local $var$3 i32) + (if + (local.tee $var$0 + (i32.add + (local.get $var$0) + (i32.const -7) + ) + ) + (block $label$2 + (block $label$3 + (local.set $var$1 + (local.get $var$0) + ) + (br_if $label$3 + (local.tee $var$3 + (i32.const 12) + ) + ) + (unreachable) + ) + (br_if $label$2 + (i32.eqz + (local.get $var$1) + ) + ) + (if + (i32.ne + (i32.load + (i32.const 0) + ) + (local.get $var$0) + ) + (unreachable) + ) + (unreachable) + ) + ) + ) ;; CHECK: (func $multiple-uses-to-non-expression (param $x i32) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: (local $2 i32) diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 07bd3fa4584..ec4cc38dfec 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -807,14 +807,14 @@ ;; CHECK: (type $4 (func (param (ref null ${mut:i8})))) - ;; CHECK: (func $unreachable-set (type $4) (param ${mut:i8} (ref null ${mut:i8})) + ;; CHECK: (func $unreachable-set (type $4) (param $"{mut:i8}" (ref null ${mut:i8})) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (block (result (ref null ${mut:i8})) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $helper-i32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get ${mut:i8}) + ;; CHECK-NEXT: (local.get $"{mut:i8}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -831,13 +831,13 @@ ) ) - ;; CHECK: (func $unreachable-set-2 (type $4) (param ${mut:i8} (ref null ${mut:i8})) + ;; CHECK: (func $unreachable-set-2 (type $4) (param $"{mut:i8}" (ref null ${mut:i8})) ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get ${mut:i8}) + ;; CHECK-NEXT: (local.get $"{mut:i8}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br $block) @@ -858,13 +858,13 @@ ) ) - ;; CHECK: (func $unreachable-set-2b (type $4) (param ${mut:i8} (ref null ${mut:i8})) + ;; CHECK: (func $unreachable-set-2b (type $4) (param $"{mut:i8}" (ref null ${mut:i8})) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get ${mut:i8}) + ;; CHECK-NEXT: (local.get $"{mut:i8}") ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (unreachable) diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index efa9ece608d..385433189db 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -732,7 +732,22 @@ (memory $B 1 1) (memory $C-unused 1 1) - (func "func" + ;; CHECK: (export "func" (func $func)) + + ;; CHECK: (func $func (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.load64_splat $A + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (v128.load16_lane $B 0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func (export "func") (drop (v128.load64_splat $A (i32.const 0) @@ -747,21 +762,6 @@ ) ) -;; CHECK: (export "func" (func $0)) - -;; CHECK: (func $0 (type $0) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (v128.load64_splat $A -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (v128.load16_lane $B 0 -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) (module ;; When we export a function that calls another, we can export the called ;; function, skipping the one in the middle. The exports of $middle and diff --git a/test/lit/passes/stack-check-memory64.wast b/test/lit/passes/stack-check-memory64.wast index fc0db8d20fc..201910f36b0 100644 --- a/test/lit/passes/stack-check-memory64.wast +++ b/test/lit/passes/stack-check-memory64.wast @@ -11,48 +11,47 @@ ;; CHECK: (global $sp (mut i64) (i64.const 0)) (global $sp (mut i64) (i64.const 0)) - (func "use_stack" (result i64) - (global.set $sp (i64.const 42)) - (global.get $sp) - ) -) -;; CHECK: (global $__stack_base (mut i64) (i64.const 0)) - -;; CHECK: (global $__stack_limit (mut i64) (i64.const 0)) + ;; CHECK: (global $__stack_base (mut i64) (i64.const 0)) -;; CHECK: (memory $0 i64 0 65536) + ;; CHECK: (global $__stack_limit (mut i64) (i64.const 0)) -;; CHECK: (data $0 (i64.const 0) "") + ;; CHECK: (memory $0 i64 0 65536) -;; CHECK: (export "use_stack" (func $0)) + ;; CHECK: (data $0 (i64.const 0) "") -;; CHECK: (export "__set_stack_limits" (func $__set_stack_limits)) + ;; CHECK: (export "use_stack" (func $use_stack)) -;; CHECK: (func $0 (result i64) -;; CHECK-NEXT: (local $0 i64) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (if -;; CHECK-NEXT: (i32.or -;; CHECK-NEXT: (i64.gt_u -;; CHECK-NEXT: (local.tee $0 -;; CHECK-NEXT: (i64.const 42) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.get $__stack_base) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i64.lt_u -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (global.get $__stack_limit) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $sp -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.get $sp) -;; CHECK-NEXT: ) + ;; CHECK: (export "__set_stack_limits" (func $__set_stack_limits)) + ;; CHECK: (func $use_stack (result i64) + ;; CHECK-NEXT: (local $0 i64) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i64.gt_u + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i64.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $__stack_base) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.lt_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (global.get $__stack_limit) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $sp + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $sp) + ;; CHECK-NEXT: ) + (func $use_stack (export "use_stack") (result i64) + (global.set $sp (i64.const 42)) + (global.get $sp) + ) +) ;; CHECK: (func $__set_stack_limits (param $0 i64) (param $1 i64) ;; CHECK-NEXT: (global.set $__stack_base ;; CHECK-NEXT: (local.get $0) diff --git a/test/lit/passes/vacuum_all-features.wast b/test/lit/passes/vacuum_all-features.wast index 9b06624cf7e..b228d13eeb4 100644 --- a/test/lit/passes/vacuum_all-features.wast +++ b/test/lit/passes/vacuum_all-features.wast @@ -1040,7 +1040,7 @@ (global $global$1 (mut i32) (i32.const 0)) ;; CHECK: (memory $0 1 1) - ;; CHECK: (export "compress" (func $3)) + ;; CHECK: (export "compress" (func $compress)) ;; CHECK: (func $_deflate (type $0) (param $0 i32) (result i32) ;; CHECK-NEXT: (call $_deflate @@ -1066,7 +1066,100 @@ (func $_deflateEnd (param i32) (result i32) (call $_deflateEnd (local.get $0)) ) - (func "compress" (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $compress (type $1) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (global.get $global$1) + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 100000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=32 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=36 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=40 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $_deflateInit2_ + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (call $_deflate + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.load offset=20 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (call $_deflateEnd + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $_deflateEnd + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $compress (export "compress") (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local.set $3 (global.get $global$1) @@ -1165,99 +1258,6 @@ ) ) -;; CHECK: (func $3 (type $1) (param $0 i32) (param $1 i32) (param $2 i32) -;; CHECK-NEXT: (local $3 i32) -;; CHECK-NEXT: (local.set $3 -;; CHECK-NEXT: (global.get $global$1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $global$1 -;; CHECK-NEXT: (i32.sub -;; CHECK-NEXT: (global.get $global$1) -;; CHECK-NEXT: (i32.const -64) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (local.get $2) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=4 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (i32.const 100000) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=12 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=16 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (i32.load -;; CHECK-NEXT: (local.get $1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=32 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=36 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.store offset=40 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (if -;; CHECK-NEXT: (call $_deflateInit2_ -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block -;; CHECK-NEXT: (global.set $global$1 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (return) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (if (result i32) -;; CHECK-NEXT: (i32.eq -;; CHECK-NEXT: (local.tee $0 -;; CHECK-NEXT: (call $_deflate -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const 1) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (i32.store -;; CHECK-NEXT: (local.get $1) -;; CHECK-NEXT: (i32.load offset=20 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.set $0 -;; CHECK-NEXT: (call $_deflateEnd -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $global$1 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (block (result i32) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (call $_deflateEnd -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $global$1 -;; CHECK-NEXT: (local.get $3) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) (module (type $A (struct (field (mut i32)))) ;; CHECK: (type $0 (func)) diff --git a/test/lit/validation/intrinsics.wast b/test/lit/validation/intrinsics.wast index 6437b2217c1..f734a749ec7 100644 --- a/test/lit/validation/intrinsics.wast +++ b/test/lit/validation/intrinsics.wast @@ -7,7 +7,7 @@ (module (import "binaryen-intrinsics" "call.without.effects" (func $cwe (param i32 funcref) (result i32))) - (func "get-ref" (result i32) + (func $get-ref (export "get-ref") (result i32) ;; This call-without-effects is done to a $func, but $func has the wrong ;; signature - it lacks the i32 parameter. (call $cwe @@ -20,4 +20,3 @@ (i32.const 1) ) ) - diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 4368a1cb2f2..af2fbffc5f5 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -335,14 +335,13 @@ ;; CHECK: (elem $passive-2 anyref (struct.new_default $s0) (struct.new_default $s0)) (elem $passive-2 anyref (item struct.new $s0) (struct.new $s0)) - (elem $declare declare func 0 1 2 3) + ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set) + (elem declare func 0 1 2 3) (elem $declare-2 declare funcref (item ref.func 0) (ref.func 1) (item (ref.func 2))) ;; tags (tag) - ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set) - ;; CHECK: (tag $1) ;; CHECK: (tag $empty) diff --git a/test/passes/O2_precompute-propagate_print-stack-ir.txt b/test/passes/O2_precompute-propagate_print-stack-ir.txt index 82b8601c331..b0789141a81 100644 --- a/test/passes/O2_precompute-propagate_print-stack-ir.txt +++ b/test/passes/O2_precompute-propagate_print-stack-ir.txt @@ -1,7 +1,7 @@ (module (type $0 (func (param i32 i32 i32 i64) (result i64))) - (export "func" (func $0)) - (func $0 (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i64) (result i64) + (export "func" (func $func)) + (func $func (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i64) (result i64) (local $4 i32) (local.set $3 (i64.const 2147483647) @@ -12,8 +12,8 @@ ) (module (type $0 (func (param i32 i32 i32 i64) (result i64))) - (export "func" (func $0)) - (func $0 (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i64) (result i64) + (export "func" (func $func)) + (func $func (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i64) (result i64) (local $4 i32) (local.set $3 (i64.const 2147483647) diff --git a/test/passes/O2_precompute-propagate_print-stack-ir.wast b/test/passes/O2_precompute-propagate_print-stack-ir.wast index 96a7d8797a5..0a1b6807e0d 100644 --- a/test/passes/O2_precompute-propagate_print-stack-ir.wast +++ b/test/passes/O2_precompute-propagate_print-stack-ir.wast @@ -1,5 +1,5 @@ (module - (func "func" (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) (param $var$3 i64) (result i64) + (func $func (export "func") (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) (param $var$3 i64) (result i64) (local $var$4 i32) (block $label$1 (local.set $var$3 @@ -15,4 +15,3 @@ (local.get $var$3) ) ) - diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index 439515e0d71..2f14281609d 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -63,25 +63,25 @@ (type $extendedstruct (sub $struct (struct (field (mut i32)) (field f64)))) (type $int_func (func (result i32))) (import "fuzzing-support" "log-i32" (func $log (type $3) (param i32))) - (export "structs" (func $0)) - (export "arrays" (func $1)) - (export "br_on_cast" (func $2)) - (export "br_on_failed_cast-1" (func $3)) - (export "br_on_failed_cast-2" (func $4)) - (export "cast-null-anyref-to-gc" (func $5)) - (export "br-on_non_null" (func $7)) - (export "br-on_non_null-2" (func $8)) - (export "ref-as-func-of-func" (func $7)) - (export "cast-on-func" (func $11)) - (export "array-alloc-failure" (func $7)) - (export "init-array-packed" (func $13)) - (export "array-copy" (func $15)) - (export "array.new_fixed" (func $16)) - (export "array.new_fixed-packed" (func $17)) - (export "static-casts" (func $18)) - (export "static-br_on_cast" (func $2)) - (export "static-br_on_cast_fail" (func $20)) - (func $0 (type $void_func) (; has Stack IR ;) + (export "structs" (func $structs)) + (export "arrays" (func $arrays)) + (export "br_on_cast" (func $br_on_cast)) + (export "br_on_failed_cast-1" (func $br_on_failed_cast-1)) + (export "br_on_failed_cast-2" (func $br_on_failed_cast-2)) + (export "cast-null-anyref-to-gc" (func $cast-null-anyref-to-gc)) + (export "br-on_non_null" (func $br-on_non_null)) + (export "br-on_non_null-2" (func $br-on_non_null-2)) + (export "ref-as-func-of-func" (func $br-on_non_null)) + (export "cast-on-func" (func $cast-on-func)) + (export "array-alloc-failure" (func $br-on_non_null)) + (export "init-array-packed" (func $init-array-packed)) + (export "array-copy" (func $array-copy)) + (export "array.new_fixed" (func $array.new_fixed)) + (export "array.new_fixed-packed" (func $array.new_fixed-packed)) + (export "static-casts" (func $static-casts)) + (export "static-br_on_cast" (func $br_on_cast)) + (export "static-br_on_cast_fail" (func $static-br_on_cast_fail)) + (func $structs (type $void_func) (; has Stack IR ;) (local $0 i32) (call $log (i32.const 0) @@ -98,7 +98,7 @@ (i32.const 100) ) ) - (func $1 (type $void_func) (; has Stack IR ;) + (func $arrays (type $void_func) (; has Stack IR ;) (local $0 (ref $bytes)) (call $log (array.len @@ -140,12 +140,12 @@ ) ) ) - (func $2 (type $void_func) (; has Stack IR ;) + (func $br_on_cast (type $void_func) (; has Stack IR ;) (call $log (i32.const 3) ) ) - (func $3 (type $void_func) (; has Stack IR ;) + (func $br_on_failed_cast-1 (type $void_func) (; has Stack IR ;) (local $0 (ref $struct)) (local.set $0 (struct.new_default $struct) @@ -167,7 +167,7 @@ ) ) ) - (func $4 (type $void_func) (; has Stack IR ;) + (func $br_on_failed_cast-2 (type $void_func) (; has Stack IR ;) (call $log (i32.const 1) ) @@ -175,15 +175,15 @@ (i32.const 999) ) ) - (func $5 (type $void_func) (; has Stack IR ;) + (func $cast-null-anyref-to-gc (type $void_func) (; has Stack IR ;) (call $log (i32.const 0) ) ) - (func $7 (type $void_func) (; has Stack IR ;) + (func $br-on_non_null (type $void_func) (; has Stack IR ;) (nop) ) - (func $8 (type $void_func) (; has Stack IR ;) + (func $br-on_non_null-2 (type $void_func) (; has Stack IR ;) (drop (block (call $log @@ -193,7 +193,7 @@ ) ) ) - (func $11 (type $void_func) (; has Stack IR ;) + (func $cast-on-func (type $void_func) (; has Stack IR ;) (call $log (i32.const 0) ) @@ -205,7 +205,7 @@ ) (unreachable) ) - (func $13 (type $int_func) (; has Stack IR ;) (result i32) + (func $init-array-packed (type $int_func) (; has Stack IR ;) (result i32) (array.get_u $bytes (array.new $bytes (i32.const -43) @@ -214,7 +214,7 @@ (i32.const 10) ) ) - (func $15 (type $void_func) (; has Stack IR ;) + (func $array-copy (type $void_func) (; has Stack IR ;) (local $0 (ref $bytes)) (local $1 (ref $bytes)) (array.set $bytes @@ -269,7 +269,7 @@ ) ) ) - (func $16 (type $void_func) (; has Stack IR ;) + (func $array.new_fixed (type $void_func) (; has Stack IR ;) (local $0 (ref $bytes)) (call $log (array.len @@ -294,7 +294,7 @@ ) ) ) - (func $17 (type $void_func) (; has Stack IR ;) + (func $array.new_fixed-packed (type $void_func) (; has Stack IR ;) (call $log (array.get_u $bytes (array.new_fixed $bytes 1 @@ -304,7 +304,7 @@ ) ) ) - (func $18 (type $void_func) (; has Stack IR ;) + (func $static-casts (type $void_func) (; has Stack IR ;) (call $log (i32.const 1) ) @@ -324,7 +324,7 @@ (i32.const 1) ) ) - (func $20 (type $void_func) (; has Stack IR ;) + (func $static-br_on_cast_fail (type $void_func) (; has Stack IR ;) (call $log (i32.const -2) ) @@ -391,8 +391,8 @@ ignoring comparison of ExecutionResults! [host limit allocation failure] (module (type $0 (func (result i32))) - (export "foo" (func $0)) - (func $0 (type $0) (; has Stack IR ;) (result i32) + (export "foo" (func $foo)) + (func $foo (type $0) (; has Stack IR ;) (result i32) (i32.const 0) ) ) diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 4c38c315dff..83cee56e866 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -8,7 +8,7 @@ (import "fuzzing-support" "log-i32" (func $log (param i32))) - (func "structs" + (func $structs (export "structs") (local $x (ref null $struct)) (local $y (ref null $struct)) (local.set $x @@ -42,7 +42,7 @@ (struct.get $struct 0 (local.get $y)) ) ) - (func "arrays" + (func $arrays (export "arrays") (local $x (ref null $bytes)) (local.set $x (array.new $bytes @@ -72,7 +72,7 @@ (array.get_s $bytes (local.get $x) (i32.const 20)) ) ) - (func "br_on_cast" + (func $br_on_cast (export "br_on_cast") (local $any anyref) ;; create a simple $struct, store it in an anyref (local.set $any @@ -101,7 +101,7 @@ ) (call $log (i32.const 3)) ;; we should get here ) - (func "br_on_failed_cast-1" + (func $br_on_failed_cast-1 (export "br_on_failed_cast-1") (local $any anyref) ;; create a simple $struct, store it in an anyref (local.set $any @@ -122,7 +122,7 @@ ) ) ) - (func "br_on_failed_cast-2" + (func $br_on_failed_cast-2 (export "br_on_failed_cast-2") (local $any anyref) ;; create an $extendedstruct, store it in an anyref (local.set $any @@ -143,7 +143,7 @@ ) ) ) - (func "cast-null-anyref-to-gc" + (func $cast-null-anyref-to-gc (export "cast-null-anyref-to-gc") ;; a null anyref is a literal which is not even of GC data, as it's not an ;; array or a struct, so our casting code should not assume it is. it is ok ;; to try to cast it, and the result should be 0. @@ -156,7 +156,7 @@ (func $get_struct (result structref) (struct.new_default $struct) ) - (func "br-on_non_null" + (func $br-on_non_null (export "br-on_non_null") (drop (block $non-null (result (ref any)) (br_on_non_null $non-null (ref.i31 (i32.const 0))) @@ -167,7 +167,7 @@ ) ) ) - (func "br-on_non_null-2" + (func $br-on_non_null-2 (export "br-on_non_null-2") (drop (block $non-null (result (ref any)) (br_on_non_null $non-null (ref.null any)) @@ -177,17 +177,17 @@ ) ) ) - (func "ref-as-func-of-func" + (func $ref-as-func-of-func (export "ref-as-func-of-func") (drop (ref.cast (ref func) - (ref.func $0) + (ref.func $structs) ) ) ) (func $a-void-func (call $log (i32.const 1337)) ) - (func "cast-on-func" + (func $cast-on-func (export "cast-on-func") (call $log (i32.const 0)) ;; a valid cast (call_ref $void_func @@ -201,14 +201,14 @@ ;; will never be reached (call $log (i32.const 2)) ) - (func "array-alloc-failure" + (func $array-alloc-failure (export "array-alloc-failure") (drop (array.new_default $bytes (i32.const -1) ;; un-allocatable size (4GB * sizeof(Literal)) ) ) ) - (func "init-array-packed" (result i32) + (func $init-array-packed (export "init-array-packed") (result i32) (local $x (ref null $bytes)) (local.set $x (array.new $bytes @@ -225,7 +225,7 @@ (func $call-target (param $0 eqref) (nop) ) - (func "array-copy" + (func $array-copy (export "array-copy") (local $x (ref null $bytes)) (local $y (ref null $bytes)) ;; Create an array of 10's, of size 100. @@ -271,7 +271,7 @@ (array.get_u $bytes (local.get $x) (i32.const 12)) ) ) - (func "array.new_fixed" + (func $array.new_fixed (export "array.new_fixed") (local $x (ref null $bytes)) (local.set $x (array.new_fixed $bytes 2 @@ -292,7 +292,7 @@ (array.get_u $bytes (local.get $x) (i32.const 1)) ) ) - (func "array.new_fixed-packed" + (func $array.new_fixed-packed (export "array.new_fixed-packed") (local $x (ref null $bytes)) (local.set $x (array.new_fixed $bytes 1 @@ -304,7 +304,7 @@ (array.get_u $bytes (local.get $x) (i32.const 0)) ) ) - (func "static-casts" + (func $static-casts (export "static-casts") ;; Casting null returns null. (call $log (ref.is_null (ref.cast (ref null $struct) (ref.null $struct)) @@ -341,7 +341,7 @@ ) ) ) - (func "static-br_on_cast" + (func $static-br_on_cast (export "static-br_on_cast") (local $any anyref) ;; create a simple $struct, store it in an anyref (local.set $any @@ -370,7 +370,7 @@ ) (call $log (i32.const 3)) ;; we should get here ) - (func "static-br_on_cast_fail" + (func $static-br_on_cast_fail (export "static-br_on_cast_fail") (local $any anyref) ;; create a simple $struct, store it in an anyref (local.set $any @@ -394,7 +394,7 @@ ) (module (type $[mut:i8] (array (mut i8))) - (func "foo" (result i32) + (func $foo (export "foo") (result i32) ;; before opts this will trap on failing to allocate -1 >>> 0 bytes. after ;; opts the unused value is removed so there is no trap, and a value is ;; returned, which should not confuse the fuzzer. diff --git a/test/passes/duplicate-function-elimination_all-features.txt b/test/passes/duplicate-function-elimination_all-features.txt index b5b363d42f4..6867002bf0b 100644 --- a/test/passes/duplicate-function-elimination_all-features.txt +++ b/test/passes/duplicate-function-elimination_all-features.txt @@ -22,11 +22,11 @@ (module (type $func (func (result i32))) (global $global$0 (ref $func) (ref.func $foo)) - (export "export" (func $2)) + (export "export" (func $export)) (func $foo (type $func) (result i32) (unreachable) ) - (func $2 (type $func) (result i32) + (func $export (type $func) (result i32) (call_ref $func (global.get $global$0) ) diff --git a/test/passes/duplicate-function-elimination_all-features.wast b/test/passes/duplicate-function-elimination_all-features.wast index df8d26b6f2d..2dccd051f58 100644 --- a/test/passes/duplicate-function-elimination_all-features.wast +++ b/test/passes/duplicate-function-elimination_all-features.wast @@ -33,7 +33,7 @@ (func $bar (result i32) (unreachable) ) - (func "export" (result i32) + (func $export (export "export") (result i32) (call_ref $func (global.get $global$0) ) diff --git a/test/passes/duplicate-import-elimination.txt b/test/passes/duplicate-import-elimination.txt index f54f152c671..4ea4c164433 100644 --- a/test/passes/duplicate-import-elimination.txt +++ b/test/passes/duplicate-import-elimination.txt @@ -5,9 +5,9 @@ (import "env" "waka" (func $wrong (param i32))) (table $0 2 2 funcref) (elem $0 (i32.const 0) $foo $foo) - (export "baz" (func $0)) + (export "baz" (func $baz)) (start $foo) - (func $0 + (func $baz (call $foo) (call $foo) (call $wrong diff --git a/test/passes/duplicate-import-elimination.wast b/test/passes/duplicate-import-elimination.wast index cd0c9dbf70e..a6f9846745e 100644 --- a/test/passes/duplicate-import-elimination.wast +++ b/test/passes/duplicate-import-elimination.wast @@ -5,10 +5,9 @@ (table 2 2 funcref) (elem (i32.const 0) $foo $bar) (start $bar) - (func "baz" + (func $baz (export "baz") (call $foo) (call $bar) (call $wrong (i32.const 1)) ) ) - diff --git a/test/passes/fuzz-exec_O.txt b/test/passes/fuzz-exec_O.txt index 74f92041b79..7bdf8d252d1 100644 --- a/test/passes/fuzz-exec_O.txt +++ b/test/passes/fuzz-exec_O.txt @@ -50,16 +50,16 @@ [fuzz-exec] note result: sub2 => nan:0x400000 (module (type $0 (func (result f32))) - (export "div" (func $0)) - (export "mul1" (func $0)) - (export "mul2" (func $0)) - (export "add1" (func $0)) - (export "add2" (func $0)) - (export "add3" (func $0)) - (export "add4" (func $0)) - (export "sub1" (func $0)) - (export "sub2" (func $0)) - (func $0 (; has Stack IR ;) (result f32) + (export "div" (func $div)) + (export "mul1" (func $div)) + (export "mul2" (func $div)) + (export "add1" (func $div)) + (export "add2" (func $div)) + (export "add3" (func $div)) + (export "add4" (func $div)) + (export "sub1" (func $div)) + (export "sub2" (func $div)) + (func $div (; has Stack IR ;) (result f32) (f32.const nan:0x400000) ) ) diff --git a/test/passes/fuzz-exec_O.wast b/test/passes/fuzz-exec_O.wast index b34dc2e8f7a..1fd917df213 100644 --- a/test/passes/fuzz-exec_O.wast +++ b/test/passes/fuzz-exec_O.wast @@ -21,55 +21,55 @@ ) ) (module - (func "div" (result f32) + (func $div (export "div") (result f32) (f32.div (f32.const -nan:0x23017a) (f32.const 1) ) ) - (func "mul1" (result f32) + (func $mul1 (export "mul1") (result f32) (f32.mul (f32.const -nan:0x34546d) (f32.const 1) ) ) - (func "mul2" (result f32) + (func $mul2 (export "mul2") (result f32) (f32.mul (f32.const 1) (f32.const -nan:0x34546d) ) ) - (func "add1" (result f32) + (func $add1 (export "add1") (result f32) (f32.add (f32.const -nan:0x34546d) (f32.const -0) ) ) - (func "add2" (result f32) + (func $add2 (export "add2") (result f32) (f32.add (f32.const -0) (f32.const -nan:0x34546d) ) ) - (func "add3" (result f32) + (func $add3 (export "add3") (result f32) (f32.add (f32.const -nan:0x34546d) (f32.const 0) ) ) - (func "add4" (result f32) + (func $add4 (export "add4") (result f32) (f32.add (f32.const 0) (f32.const -nan:0x34546d) ) ) - (func "sub1" (result f32) + (func $sub1 (export "sub1") (result f32) (f32.sub (f32.const -nan:0x34546d) (f32.const 0) ) ) - (func "sub2" (result f32) + (func $sub2 (export "sub2") (result f32) (f32.sub (f32.const -nan:0x34546d) (f32.const -0) diff --git a/test/passes/fuzz-exec_all-features.txt b/test/passes/fuzz-exec_all-features.txt index 43733571333..6a0ee8585c4 100644 --- a/test/passes/fuzz-exec_all-features.txt +++ b/test/passes/fuzz-exec_all-features.txt @@ -76,34 +76,34 @@ (type $3 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $1) (param i32))) (memory $0 (shared 1 1)) - (export "unaligned_load" (func $0)) - (export "unaligned_load_offset" (func $1)) - (export "aligned_for_size" (func $2)) - (export "unaligned_notify" (func $3)) - (export "wrap_cmpxchg" (func $4)) - (export "oob_notify" (func $5)) - (func $0 (type $0) (result i32) + (export "unaligned_load" (func $unaligned_load)) + (export "unaligned_load_offset" (func $unaligned_load_offset)) + (export "aligned_for_size" (func $aligned_for_size)) + (export "unaligned_notify" (func $unaligned_notify)) + (export "wrap_cmpxchg" (func $wrap_cmpxchg)) + (export "oob_notify" (func $oob_notify)) + (func $unaligned_load (type $0) (result i32) (i32.atomic.load (i32.const 1) ) ) - (func $1 (type $0) (result i32) + (func $unaligned_load_offset (type $0) (result i32) (i32.atomic.load offset=1 (i32.const 0) ) ) - (func $2 (type $0) (result i32) + (func $aligned_for_size (type $0) (result i32) (i32.atomic.load16_u offset=2 (i32.const 0) ) ) - (func $3 (type $0) (result i32) + (func $unaligned_notify (type $0) (result i32) (memory.atomic.notify (i32.const 1) (i32.const 1) ) ) - (func $4 (type $2) (param $0 i32) (param $1 i32) + (func $wrap_cmpxchg (type $2) (param $0 i32) (param $1 i32) (drop (i32.atomic.rmw8.cmpxchg_u (i32.const 0) @@ -117,7 +117,7 @@ ) ) ) - (func $5 (type $3) + (func $oob_notify (type $3) (drop (memory.atomic.notify offset=22 (i32.const -104) @@ -150,8 +150,8 @@ (type $0 (func (result i32))) (memory $0 (shared 1 1)) (data $0 (i32.const 0) "\ff\ff") - (export "unsigned_2_bytes" (func $0)) - (func $0 (type $0) (result i32) + (export "unsigned_2_bytes" (func $unsigned_2_bytes)) + (func $unsigned_2_bytes (type $0) (result i32) (i32.atomic.rmw16.xor_u (i32.const 0) (i32.const 0) @@ -168,8 +168,8 @@ (type $1 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $0) (param i32))) (memory $0 (shared 1 1)) - (export "rmw-reads-modifies-and-writes" (func $0)) - (func $0 (type $1) + (export "rmw-reads-modifies-and-writes" (func $rmw-reads-modifies-and-writes)) + (func $rmw-reads-modifies-and-writes (type $1) (drop (i64.atomic.rmw16.and_u offset=4 (i32.const 0) @@ -193,8 +193,8 @@ (type $1 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $0) (param i32))) (memory $0 (shared 1 1)) - (export "rmw-reads-modifies-and-writes-asymmetrical" (func $0)) - (func $0 (type $1) + (export "rmw-reads-modifies-and-writes-asymmetrical" (func $rmw-reads-modifies-and-writes-asymmetrical)) + (func $rmw-reads-modifies-and-writes-asymmetrical (type $1) (drop (i32.atomic.rmw8.sub_u (i32.const 3) diff --git a/test/passes/fuzz-exec_all-features.wast b/test/passes/fuzz-exec_all-features.wast index 960990a33fd..2c9d95d16c9 100644 --- a/test/passes/fuzz-exec_all-features.wast +++ b/test/passes/fuzz-exec_all-features.wast @@ -33,30 +33,30 @@ (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) (memory $0 (shared 1 1)) - (func "unaligned_load" (result i32) + (func $unaligned_load (export "unaligned_load") (result i32) (i32.atomic.load (i32.const 1) ;; unaligned ptr (i32.const 1) ) ) - (func "unaligned_load_offset" (result i32) + (func $unaligned_load_offset (export "unaligned_load_offset") (result i32) (i32.atomic.load offset=1 ;; unaligned with offset (i32.const 0) (i32.const 1) ) ) - (func "aligned_for_size" (result i32) + (func $aligned_for_size (export "aligned_for_size") (result i32) (i32.atomic.load16_u offset=2 ;; just 2 bytes loaded, so size is ok (i32.const 0) ) ) - (func "unaligned_notify" (result i32) + (func $unaligned_notify (export "unaligned_notify") (result i32) (memory.atomic.notify (i32.const 1) ;; unaligned (i32.const 1) ) ) - (func "wrap_cmpxchg" (param $0 i32) (param $1 i32) + (func $wrap_cmpxchg (export "wrap_cmpxchg") (param $0 i32) (param $1 i32) (drop (i32.atomic.rmw8.cmpxchg_u (i32.const 0) @@ -68,7 +68,7 @@ (i32.load (i32.const 0)) ) ) - (func "oob_notify" + (func $oob_notify (export "oob_notify") (drop (memory.atomic.notify offset=22 (i32.const -104) ;; illegal address @@ -80,7 +80,7 @@ (module (memory $0 (shared 1 1)) (data (i32.const 0) "\ff\ff") - (func "unsigned_2_bytes" (result i32) + (func $unsigned_2_bytes (export "unsigned_2_bytes") (result i32) (i32.atomic.rmw16.xor_u ;; should be unsigned (i32.const 0) (i32.const 0) @@ -90,7 +90,7 @@ (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) (memory $0 (shared 1 1)) - (func "rmw-reads-modifies-and-writes" + (func $rmw-reads-modifies-and-writes (export "rmw-reads-modifies-and-writes") (drop (i64.atomic.rmw16.and_u offset=4 (i32.const 0) @@ -107,7 +107,7 @@ (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) (memory $0 (shared 1 1)) - (func "rmw-reads-modifies-and-writes-asymmetrical" + (func $rmw-reads-modifies-and-writes-asymmetrical (export "rmw-reads-modifies-and-writes-asymmetrical") (drop (i32.atomic.rmw8.sub_u (i32.const 3) diff --git a/test/passes/optimize-instructions_fuzz-exec.txt b/test/passes/optimize-instructions_fuzz-exec.txt index de4aaa9bcbc..4b552c0606d 100644 --- a/test/passes/optimize-instructions_fuzz-exec.txt +++ b/test/passes/optimize-instructions_fuzz-exec.txt @@ -32,11 +32,11 @@ (type $2 (func (param f64))) (import "fuzzing-support" "log-f32" (func $logf32 (param f32))) (import "fuzzing-support" "log-f64" (func $logf64 (param f64))) - (export "test32" (func $0)) - (export "test64" (func $1)) - (export "just-one-nan" (func $2)) - (export "ignore" (func $3)) - (func $0 + (export "test32" (func $test32)) + (export "test64" (func $test64)) + (export "just-one-nan" (func $just-one-nan)) + (export "ignore" (func $ignore)) + (func $test32 (call $logf32 (f32.const nan:0x400000) ) @@ -69,7 +69,7 @@ (f32.const nan:0x400000) ) ) - (func $1 + (func $test64 (call $logf64 (f64.const nan:0x8000000000000) ) @@ -102,7 +102,7 @@ (f64.const nan:0x8000000000000) ) ) - (func $2 + (func $just-one-nan (call $logf32 (f32.const nan:0x400000) ) @@ -131,7 +131,7 @@ ) ) ) - (func $3 + (func $ignore (call $logf32 (f32.div (f32.const -0) @@ -206,10 +206,10 @@ (type $2 (func (param i32) (result i32))) (type $3 (func (result i32))) (import "fuzzing-support" "log-i32" (func $log (param i32))) - (export "foo" (func $1)) - (export "do-shift" (func $3)) - (export "call-compare-maybe-signed-eq" (func $5)) - (export "call-compare-maybe-signed-ne" (func $7)) + (export "foo" (func $foo)) + (export "do-shift" (func $do-shift)) + (export "call-compare-maybe-signed-eq" (func $call-compare-maybe-signed-eq)) + (export "call-compare-maybe-signed-ne" (func $call-compare-maybe-signed-ne)) (func $signed-comparison-to-unsigned (call $log (block (result i32) @@ -236,7 +236,7 @@ ) ) ) - (func $1 (param $0 i32) + (func $foo (param $0 i32) (call $log (i32.le_s (i32.sub @@ -271,7 +271,7 @@ ) ) ) - (func $3 + (func $do-shift (call $shift (i32.const 65419) ) @@ -282,7 +282,7 @@ ) (i32.const 0) ) - (func $5 (result i32) + (func $call-compare-maybe-signed-eq (result i32) (call $compare-maybe-signed-eq (i32.const 128) ) @@ -293,7 +293,7 @@ ) (i32.const 1) ) - (func $7 (result i32) + (func $call-compare-maybe-signed-ne (result i32) (call $compare-maybe-signed-ne (i32.const 128) ) diff --git a/test/passes/optimize-instructions_fuzz-exec.wast b/test/passes/optimize-instructions_fuzz-exec.wast index 87b6eb5947b..f047e3ac2b8 100644 --- a/test/passes/optimize-instructions_fuzz-exec.wast +++ b/test/passes/optimize-instructions_fuzz-exec.wast @@ -1,7 +1,7 @@ (module (import "fuzzing-support" "log-f32" (func $logf32 (param f32))) (import "fuzzing-support" "log-f64" (func $logf64 (param f64))) - (func "test32" + (func $test32 (export "test32") (call $logf32 (f32.add (f32.const -nan:0xffff82) @@ -59,7 +59,7 @@ ) ) ) - (func "test64" + (func $test64 (export "test64") (call $logf64 (f64.add (f64.const -nan:0xfffffffffff82) @@ -117,7 +117,7 @@ ) ) ) - (func "just-one-nan" + (func $just-one-nan (export "just-one-nan") (call $logf32 (f32.add (f32.const 0) @@ -167,7 +167,7 @@ ) ) ) - (func "ignore" + (func $ignore (export "ignore") ;; none of these are nan inputs, so the interpreter must not change the sign (call $logf32 (f32.div @@ -246,7 +246,7 @@ ) ) ) - (func "foo" (param $0 i32) + (func $foo (export "foo") (param $0 i32) ;; 8 - 0x80000000 < 0 ;; ;; is not the same as @@ -307,7 +307,7 @@ ) ) ) - (func "do-shift" + (func $do-shift (export "do-shift") (call $shift (i32.const 65419) ) @@ -326,7 +326,7 @@ (i32.const 128) ) ) - (func "call-compare-maybe-signed-eq" (result i32) + (func $call-compare-maybe-signed-eq (export "call-compare-maybe-signed-eq") (result i32) (call $compare-maybe-signed-eq (i32.const 128) ) @@ -344,7 +344,7 @@ (i32.const 128) ) ) - (func "call-compare-maybe-signed-ne" (result i32) + (func $call-compare-maybe-signed-ne (export "call-compare-maybe-signed-ne") (result i32) (call $compare-maybe-signed-ne (i32.const 128) ) diff --git a/test/passes/roundtrip.txt b/test/passes/roundtrip.txt index 85d07977d41..84e95488787 100644 --- a/test/passes/roundtrip.txt +++ b/test/passes/roundtrip.txt @@ -1,7 +1,7 @@ (module (type $0 (func)) - (export "foo" (func $0)) - (func $0 + (export "foo" (func $foo)) + (func $foo (unreachable) ) ) diff --git a/test/passes/roundtrip.wast b/test/passes/roundtrip.wast index 7d1eb174bbf..aec07657fe7 100644 --- a/test/passes/roundtrip.wast +++ b/test/passes/roundtrip.wast @@ -1,5 +1,5 @@ (module - (func "foo" + (func $foo (export "foo") ;; binaryen skips unreachable code while reading the binary format (unreachable) (nop) diff --git a/test/passes/simplify-globals_all-features_fuzz-exec.txt b/test/passes/simplify-globals_all-features_fuzz-exec.txt index 5c3bf0a157b..fbbcc30c491 100644 --- a/test/passes/simplify-globals_all-features_fuzz-exec.txt +++ b/test/passes/simplify-globals_all-features_fuzz-exec.txt @@ -5,11 +5,11 @@ (type $1 (func (result funcref))) (global $global$0 (mut funcref) (ref.null nofunc)) (elem declare func $0) - (export "export" (func $1)) + (export "export" (func $export)) (func $0 (type $0) (param $0 f32) (param $1 i31ref) (param $2 i64) (param $3 f64) (param $4 funcref) (nop) ) - (func $1 (type $1) (result funcref) + (func $export (type $1) (result funcref) (global.set $global$0 (ref.func $0) ) diff --git a/test/passes/simplify-globals_all-features_fuzz-exec.wast b/test/passes/simplify-globals_all-features_fuzz-exec.wast index ff2200ea98e..59a12a71ef6 100644 --- a/test/passes/simplify-globals_all-features_fuzz-exec.wast +++ b/test/passes/simplify-globals_all-features_fuzz-exec.wast @@ -3,7 +3,7 @@ (func $0 (param $0 f32) (param $1 i31ref) (param $2 i64) (param $3 f64) (param $4 funcref) (nop) ) - (func "export" (result funcref) + (func $export (export "export") (result funcref) ;; this set's value will be applied to the get right after it. we should carry ;; over the specific typed function reference type properly while doing so. (global.set $global$0 diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt index f6726a37781..5e5478ddf34 100644 --- a/test/passes/simplify-locals_all-features.txt +++ b/test/passes/simplify-locals_all-features.txt @@ -1886,8 +1886,8 @@ (type $0 (func (result i32))) (memory $0 (shared 1 1)) (data $0 "data") - (export "foo" (func $0)) - (func $0 (type $0) (result i32) + (export "foo" (func $foo)) + (func $foo (type $0) (result i32) (local $0 i32) (local.set $0 (i32.rem_u @@ -1901,8 +1901,8 @@ ) (module (type $0 (func (param eqref i31ref) (result i32))) - (export "test" (func $0)) - (func $0 (type $0) (param $0 eqref) (param $1 i31ref) (result i32) + (export "test" (func $test)) + (func $test (type $0) (param $0 eqref) (param $1 i31ref) (result i32) (local $2 eqref) (local $3 i31ref) (local.set $2 diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast index ff70a27744c..a2868b45dd9 100644 --- a/test/passes/simplify-locals_all-features.wast +++ b/test/passes/simplify-locals_all-features.wast @@ -1675,7 +1675,7 @@ (module (memory $0 (shared 1 1)) (data "data") - (func "foo" (result i32) + (func $foo (export "foo") (result i32) (local $0 i32) (block (result i32) (local.set $0 @@ -1693,7 +1693,7 @@ ;; it is no longer equivalent ;; (see https://github.com/WebAssembly/binaryen/issues/3266) (module - (func "test" (param $0 eqref) (param $1 (ref null i31)) (result i32) + (func $test (export "test") (param $0 eqref) (param $1 (ref null i31)) (result i32) (local $2 eqref) (local $3 (ref null i31)) (local.set $2 diff --git a/test/passes/stack-check_enable-mutable-globals.txt b/test/passes/stack-check_enable-mutable-globals.txt index 8b4ac19cd2a..a2d7f374de9 100644 --- a/test/passes/stack-check_enable-mutable-globals.txt +++ b/test/passes/stack-check_enable-mutable-globals.txt @@ -4,9 +4,9 @@ (import "env" "__stack_pointer" (global $sp (mut i32))) (global $__stack_base (mut i32) (i32.const 0)) (global $__stack_limit (mut i32) (i32.const 0)) - (export "use_stack" (func $0)) + (export "use_stack" (func $use_stack)) (export "__set_stack_limits" (func $__set_stack_limits)) - (func $0 (result i32) + (func $use_stack (result i32) (local $0 i32) (block (if diff --git a/test/passes/stack-check_enable-mutable-globals.wast b/test/passes/stack-check_enable-mutable-globals.wast index c3583cd2c9f..4ca78c67b95 100644 --- a/test/passes/stack-check_enable-mutable-globals.wast +++ b/test/passes/stack-check_enable-mutable-globals.wast @@ -1,6 +1,6 @@ (module (import "env" "__stack_pointer" (global $sp (mut i32))) - (func "use_stack" (result i32) + (func $use_stack (export "use_stack") (result i32) (global.set $sp (i32.const 42)) (global.get $sp) ) diff --git a/test/reduce/atomics-and-bulk-memory.wast b/test/reduce/atomics-and-bulk-memory.wast index c43914bd836..83d90e6dea6 100644 --- a/test/reduce/atomics-and-bulk-memory.wast +++ b/test/reduce/atomics-and-bulk-memory.wast @@ -2,7 +2,7 @@ (memory 1 1) ;; this can be removed destructively (data "some-data") - (func "foo" (result i32) + (func $foo (export "foo") (result i32) ;; this can be removed destructively (memory.init 0 (i32.const 3) diff --git a/test/unit/input/asyncify-coroutine.wat b/test/unit/input/asyncify-coroutine.wat index ace97c6e681..1d46c1269b8 100644 --- a/test/unit/input/asyncify-coroutine.wat +++ b/test/unit/input/asyncify-coroutine.wat @@ -5,7 +5,7 @@ (import "env" "yield" (func $yield (param i32))) (export "memory" (memory 0)) ;; simple linear progression in a loop - (func "linear" (result i32) + (func $linear (export "linear") (result i32) (local $x i32) (loop $l (call $yield (local.get $x)) @@ -16,7 +16,7 @@ ) ) ;; exponential in a loop - (func "exponential" (result i32) + (func $exponential (export "exponential") (result i32) (local $x i32) (local.set $x (i32.const 1) @@ -30,7 +30,7 @@ ) ) ;; just some weird numbers, no loop - (func "weird" (result i32) + (func $weird (export "weird") (result i32) (call $yield (i32.const 42)) (call $yield (i32.const 1337)) (call $yield (i32.const 0)) @@ -41,4 +41,3 @@ (unreachable) ) ) - diff --git a/test/unit/input/asyncify-sleep.wat b/test/unit/input/asyncify-sleep.wat index 91fb5a327b1..6d54f5c075f 100644 --- a/test/unit/input/asyncify-sleep.wat +++ b/test/unit/input/asyncify-sleep.wat @@ -8,17 +8,17 @@ (global $temp (mut i32) (i32.const 0)) (table 10 funcref) (elem (i32.const 5) $tablefunc) - (func "minimal" (result i32) + (func $minimal (export "minimal") (result i32) (call $sleep) (i32.const 21) ) - (func "repeat" (result i32) + (func $repeat (export "repeat") (result i32) ;; sleep twice, then return 42 (call $sleep) (call $sleep) (i32.const 42) ) - (func "local" (result i32) + (func $local (export "local") (result i32) (local $x i32) (local.set $x (i32.load (i32.const 0))) ;; a zero that the optimizer won't see (local.set $x @@ -27,7 +27,7 @@ (call $sleep) (local.get $x) ) - (func "local2" (result i32) + (func $local2 (export "local2") (result i32) (local $x i32) (local.set $x (i32.load (i32.const 0))) ;; a zero that the optimizer won't see (local.set $x @@ -39,7 +39,7 @@ ) (local.get $x) ) - (func "params" (param $x i32) (param $y i32) (result i32) + (func $params (export "params") (param $x i32) (param $y i32) (result i32) (local.set $x (i32.add (local.get $x) (i32.const 17)) ;; add 10 ) @@ -65,7 +65,7 @@ ) ) ) - (func "deeper" (param $x i32) (result i32) + (func $deeper (export "deeper") (param $x i32) (result i32) (call $pre) (call $inner (local.get $x)) (call $post) @@ -92,7 +92,7 @@ ) ) ) - (func "factorial-loop" (param $x i32) (result i32) + (func $factorial-loop (export "factorial-loop") (param $x i32) (result i32) (local $i i32) (local $ret i32) (local.set $ret (i32.const 1)) @@ -121,14 +121,14 @@ (br $l) ) ) - (func "end_tunnel" (param $x i32) (result i32) + (func $end_tunnel (export "end_tunnel") (param $x i32) (result i32) (local.set $x (i32.add (local.get $x) (i32.const 22)) ) (call $sleep) (i32.add (local.get $x) (i32.const 5)) ) - (func "do_tunnel" (param $x i32) (result i32) + (func $do_tunnel (export "do_tunnel") (param $x i32) (result i32) (local.set $x (i32.add (local.get $x) (i32.const 11)) ) @@ -145,7 +145,7 @@ (call $sleep) (i32.add (local.get $y) (i32.const 30)) ) - (func "call_indirect" (param $x i32) (param $y i32) (result i32) + (func $call_indirect (export "call_indirect") (param $x i32) (param $y i32) (result i32) (local.set $x (i32.add (local.get $x) (i32.const 1)) ) @@ -162,7 +162,7 @@ (call $sleep) (i32.add (local.get $y) (i32.const 300)) ;; total is 10+30+90+300=430 + y's original value ) - (func "if_else" (param $x i32) (param $y i32) (result i32) + (func $if_else (export "if_else") (param $x i32) (param $y i32) (result i32) (if (i32.eq (local.get $x) (i32.const 1)) (local.set $y (i32.add (local.get $y) (i32.const 10)) @@ -197,4 +197,3 @@ (local.get $y) ) ) - diff --git a/test/unit/input/asyncify-stackOverflow.wat b/test/unit/input/asyncify-stackOverflow.wat index a36a06b40c3..b838f23605d 100644 --- a/test/unit/input/asyncify-stackOverflow.wat +++ b/test/unit/input/asyncify-stackOverflow.wat @@ -2,7 +2,7 @@ (memory 1 2) (import "env" "sleep" (func $sleep)) (export "memory" (memory 0)) - (func "many_locals" (param $x i32) (result i32) + (func $many_locals (export "many_locals") (param $x i32) (result i32) (local $y i32) (local $z i32) (local.set $y @@ -19,4 +19,3 @@ ) ) ) - diff --git a/test/unit/input/stack_ir.wat b/test/unit/input/stack_ir.wat index 0d5d0dfc385..6969052c905 100644 --- a/test/unit/input/stack_ir.wat +++ b/test/unit/input/stack_ir.wat @@ -1,6 +1,6 @@ (module (import "env" "bar" (func $bar (param i32) (result i32))) - (func "foo1" (result i32) + (func $foo1 (export "foo1") (result i32) (local $x i32) (local.set $x (call $bar (i32.const 0))) (drop @@ -9,4 +9,3 @@ (local.get $x) ;; local2stack can help here ) ) - diff --git a/test/wasm2js/atomics_32.2asm.js b/test/wasm2js/atomics_32.2asm.js index 1fdd8916e5c..a97bf17ed26 100644 --- a/test/wasm2js/atomics_32.2asm.js +++ b/test/wasm2js/atomics_32.2asm.js @@ -110,7 +110,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function test() { var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0; Atomics.compareExchange(HEAP8, 1024, 1, 2) | 0; Atomics.compareExchange(HEAP16, 1024 >> 1, 1, 2) | 0; @@ -147,7 +147,7 @@ function asmFunc(imports) { } return { - "test": $0 + "test": test }; } diff --git a/test/wasm2js/atomics_32.2asm.js.opt b/test/wasm2js/atomics_32.2asm.js.opt index 0d7ab96f61d..deb8ce56186 100644 --- a/test/wasm2js/atomics_32.2asm.js.opt +++ b/test/wasm2js/atomics_32.2asm.js.opt @@ -110,7 +110,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function test() { Atomics.compareExchange(HEAP8, 1024, 1, 2) | 0; Atomics.compareExchange(HEAP16, 512, 1, 2) | 0; Atomics.compareExchange(HEAP32, 256, 1, 2) | 0; @@ -143,7 +143,7 @@ function asmFunc(imports) { } return { - "test": $0 + "test": test }; } diff --git a/test/wasm2js/atomics_32.wast b/test/wasm2js/atomics_32.wast index a4e19052d03..eeec9337631 100644 --- a/test/wasm2js/atomics_32.wast +++ b/test/wasm2js/atomics_32.wast @@ -2,7 +2,7 @@ (memory (shared 256 256)) (data "hello,") (data "world!") - (func "test" + (func $test (export "test") (local $x i32) (local $y i64) (local.set $x (i32.atomic.rmw8.cmpxchg_u (i32.const 1024) (i32.const 1) (i32.const 2))) diff --git a/test/wasm2js/br_table_hoisting.2asm.js b/test/wasm2js/br_table_hoisting.2asm.js index c814955aa28..73652c3bce8 100644 --- a/test/wasm2js/br_table_hoisting.2asm.js +++ b/test/wasm2js/br_table_hoisting.2asm.js @@ -15,7 +15,7 @@ function asmFunc(imports) { zed($0 | 0); } - function $1(x) { + function foo1(x) { x = x | 0; a : { b : { @@ -44,7 +44,7 @@ function asmFunc(imports) { zed(-10 | 0); } - function $2(x) { + function foo2(x) { x = x | 0; a : { b : { @@ -81,7 +81,7 @@ function asmFunc(imports) { zed(-10 | 0); } - function $3(x) { + function foo3(x) { x = x | 0; a : { b : { @@ -121,7 +121,7 @@ function asmFunc(imports) { zed(-10 | 0); } - function $4(x) { + function foo4(x) { x = x | 0; a : { b : { @@ -167,10 +167,10 @@ function asmFunc(imports) { } return { - "foo1": $1, - "foo2": $2, - "foo3": $3, - "foo4": $4 + "foo1": foo1, + "foo2": foo2, + "foo3": foo3, + "foo4": foo4 }; } diff --git a/test/wasm2js/br_table_hoisting.2asm.js.opt b/test/wasm2js/br_table_hoisting.2asm.js.opt index 767b126ab93..c4d825421f0 100644 --- a/test/wasm2js/br_table_hoisting.2asm.js.opt +++ b/test/wasm2js/br_table_hoisting.2asm.js.opt @@ -14,7 +14,7 @@ function asmFunc(imports) { zed($0); } - function $1($0) { + function foo1($0) { $0 = $0 | 0; a : { b : { @@ -42,7 +42,7 @@ function asmFunc(imports) { zed(-10); } - function $2($0) { + function foo2($0) { $0 = $0 | 0; a : { b : { @@ -77,7 +77,7 @@ function asmFunc(imports) { zed(-10); } - function $3($0) { + function foo3($0) { $0 = $0 | 0; a : { b : { @@ -115,7 +115,7 @@ function asmFunc(imports) { zed(-10); } - function $4($0) { + function foo4($0) { $0 = $0 | 0; a : { b : { @@ -157,10 +157,10 @@ function asmFunc(imports) { } return { - "foo1": $1, - "foo2": $2, - "foo3": $3, - "foo4": $4 + "foo1": foo1, + "foo2": foo2, + "foo3": foo3, + "foo4": foo4 }; } diff --git a/test/wasm2js/br_table_hoisting.wast b/test/wasm2js/br_table_hoisting.wast index 95afab72894..c72abc61e69 100644 --- a/test/wasm2js/br_table_hoisting.wast +++ b/test/wasm2js/br_table_hoisting.wast @@ -2,7 +2,7 @@ (func $zed (param i32) (call $zed (local.get 0)) ) - (func "foo1" (param $x i32) + (func $foo1 (export "foo1") (param $x i32) (block $a (block $b (block $c @@ -29,7 +29,7 @@ (call $zed (i32.const -9)) (call $zed (i32.const -10)) ) - (func "foo2" (param $x i32) + (func $foo2 (export "foo2") (param $x i32) (block $a (block $b (block $c @@ -56,7 +56,7 @@ (call $zed (i32.const -9)) (call $zed (i32.const -10)) ) - (func "foo3" (param $x i32) + (func $foo3 (export "foo3") (param $x i32) (block $a (block $b (block $c @@ -83,7 +83,7 @@ (call $zed (i32.const -9)) (call $zed (i32.const -10)) ) - (func "foo4" (param $x i32) + (func $foo4 (export "foo4") (param $x i32) (block $a (block $b (block $c @@ -112,4 +112,3 @@ (call $zed (i32.const -10)) ) ) - diff --git a/test/wasm2js/br_table_to_loop.2asm.js b/test/wasm2js/br_table_to_loop.2asm.js index a0844d9360f..939e60bf62b 100644 --- a/test/wasm2js/br_table_to_loop.2asm.js +++ b/test/wasm2js/br_table_to_loop.2asm.js @@ -10,7 +10,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function exp1() { block : { loop : while (1) switch (1 | 0) { case 1: @@ -21,7 +21,7 @@ function asmFunc(imports) { } } - function $1() { + function exp2() { block : { loop : while (1) switch (1 | 0) { case 1: @@ -33,8 +33,8 @@ function asmFunc(imports) { } return { - "exp1": $0, - "exp2": $1 + "exp1": exp1, + "exp2": exp2 }; } diff --git a/test/wasm2js/br_table_to_loop.2asm.js.opt b/test/wasm2js/br_table_to_loop.2asm.js.opt index 4c9f9731140..7215e26761e 100644 --- a/test/wasm2js/br_table_to_loop.2asm.js.opt +++ b/test/wasm2js/br_table_to_loop.2asm.js.opt @@ -10,17 +10,17 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function exp1() { while (1) continue; } - function $1() { + function exp2() { } return { - "exp1": $0, - "exp2": $1 + "exp1": exp1, + "exp2": exp2 }; } diff --git a/test/wasm2js/br_table_to_loop.wast b/test/wasm2js/br_table_to_loop.wast index a74d5ffe091..add8f3eeb67 100644 --- a/test/wasm2js/br_table_to_loop.wast +++ b/test/wasm2js/br_table_to_loop.wast @@ -1,5 +1,5 @@ (module - (func "exp1" + (func $exp1 (export "exp1") (block $block ;; An infinite loop. When optimizing, wasm2js enables ignore-implicit-traps ;; and so it can simplify this. @@ -8,7 +8,7 @@ ) ) ) - (func "exp2" + (func $exp2 (export "exp2") (block $block ;; A loop that never executes. This can be optimized into a nop. (loop $loop diff --git a/test/wasm2js/deterministic.2asm.js b/test/wasm2js/deterministic.2asm.js index fff96b5a4c8..33cb04a846e 100644 --- a/test/wasm2js/deterministic.2asm.js +++ b/test/wasm2js/deterministic.2asm.js @@ -25,7 +25,7 @@ function asmFunc(imports) { var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; var global$0 = -44; - function $0() { + function foo() { if ((global$0 >>> 0) / ((HEAP32[0 >> 2] | 0) >>> 0) | 0) { wasm2js_trap() } @@ -38,7 +38,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/deterministic.2asm.js.opt b/test/wasm2js/deterministic.2asm.js.opt index a05554b1ab3..12ebdd8599d 100644 --- a/test/wasm2js/deterministic.2asm.js.opt +++ b/test/wasm2js/deterministic.2asm.js.opt @@ -24,7 +24,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function foo() { if (4294967252 / HEAPU32[0] | 0) { wasm2js_trap() } @@ -37,7 +37,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/deterministic.wast b/test/wasm2js/deterministic.wast index d1f39ba0646..67caefbad9c 100644 --- a/test/wasm2js/deterministic.wast +++ b/test/wasm2js/deterministic.wast @@ -1,7 +1,7 @@ (module (global $global$0 (mut i32) (i32.const -44)) (import "env" "memory" (memory $0 1 1)) - (func "foo" (result i32) + (func $foo (export "foo") (result i32) (if (i32.div_u (global.get $global$0) diff --git a/test/wasm2js/dot_import.2asm.js b/test/wasm2js/dot_import.2asm.js index a35eabe9544..ddbec432bce 100644 --- a/test/wasm2js/dot_import.2asm.js +++ b/test/wasm2js/dot_import.2asm.js @@ -13,12 +13,12 @@ function asmFunc(imports) { var Math_sqrt = Math.sqrt; var mod_ule = imports["mod.ule"]; var base = mod_ule["ba.se"]; - function $0() { + function exported() { base(); } return { - "exported": $0 + "exported": exported }; } diff --git a/test/wasm2js/dot_import.2asm.js.opt b/test/wasm2js/dot_import.2asm.js.opt index a35eabe9544..ddbec432bce 100644 --- a/test/wasm2js/dot_import.2asm.js.opt +++ b/test/wasm2js/dot_import.2asm.js.opt @@ -13,12 +13,12 @@ function asmFunc(imports) { var Math_sqrt = Math.sqrt; var mod_ule = imports["mod.ule"]; var base = mod_ule["ba.se"]; - function $0() { + function exported() { base(); } return { - "exported": $0 + "exported": exported }; } diff --git a/test/wasm2js/dot_import.wast b/test/wasm2js/dot_import.wast index 46c843fdedb..4da6478ee97 100644 --- a/test/wasm2js/dot_import.wast +++ b/test/wasm2js/dot_import.wast @@ -1,6 +1,6 @@ (module (import "mod.ule" "ba.se" (func $base)) - (func "exported" + (func $exported (export "exported") (call $base) ) ) diff --git a/test/wasm2js/global_i64.2asm.js b/test/wasm2js/global_i64.2asm.js index 37c8b15facc..cccd5de1cc3 100644 --- a/test/wasm2js/global_i64.2asm.js +++ b/test/wasm2js/global_i64.2asm.js @@ -17,7 +17,7 @@ function asmFunc(imports) { $0$hi = $0$hi | 0; } - function $1() { + function exp() { var i64toi32_i32$0 = 0; i64toi32_i32$0 = f$hi; call(f | 0, i64toi32_i32$0 | 0); @@ -27,7 +27,7 @@ function asmFunc(imports) { } return { - "exp": $1 + "exp": exp }; } diff --git a/test/wasm2js/global_i64.2asm.js.opt b/test/wasm2js/global_i64.2asm.js.opt index e28ae72930b..f6cc9d9111a 100644 --- a/test/wasm2js/global_i64.2asm.js.opt +++ b/test/wasm2js/global_i64.2asm.js.opt @@ -10,12 +10,12 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $1() { + function exp() { } return { - "exp": $1 + "exp": exp }; } diff --git a/test/wasm2js/global_i64.wast b/test/wasm2js/global_i64.wast index 6ed163d79e7..71a125bf6e2 100644 --- a/test/wasm2js/global_i64.wast +++ b/test/wasm2js/global_i64.wast @@ -1,7 +1,7 @@ (module (global $f (mut i64) (i64.const 0x12345678ABCDEFAF)) (func $call (param i64)) - (func "exp" + (func $exp (export "exp") (call $call (global.get $f)) (global.set $f (i64.const 0x1122334455667788)) ) diff --git a/test/wasm2js/indirect-select.2asm.js b/test/wasm2js/indirect-select.2asm.js index a515e15560e..b1725927481 100644 --- a/test/wasm2js/indirect-select.2asm.js +++ b/test/wasm2js/indirect-select.2asm.js @@ -13,19 +13,19 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0(x) { + function foo_true(x) { x = x | 0; return FUNCTION_TABLE[(x ? 1 : 0) | 0]() | 0 | 0; } - function $1(x) { + function foo_false(x) { x = x | 0; return FUNCTION_TABLE[(x ? 0 : 1) | 0]() | 0 | 0; } return { - "foo_true": $0, - "foo_false": $1 + "foo_true": foo_true, + "foo_false": foo_false }; } diff --git a/test/wasm2js/indirect-select.2asm.js.opt b/test/wasm2js/indirect-select.2asm.js.opt index 9b79e3a636f..2d1792a53d9 100644 --- a/test/wasm2js/indirect-select.2asm.js.opt +++ b/test/wasm2js/indirect-select.2asm.js.opt @@ -13,19 +13,19 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0($0_1) { - $0_1 = $0_1 | 0; - return FUNCTION_TABLE[!!$0_1 | 0]() | 0; + function foo_true($0) { + $0 = $0 | 0; + return FUNCTION_TABLE[!!$0 | 0]() | 0; } - function $1($0_1) { - $0_1 = $0_1 | 0; - return FUNCTION_TABLE[!$0_1 | 0]() | 0; + function foo_false($0) { + $0 = $0 | 0; + return FUNCTION_TABLE[!$0 | 0]() | 0; } return { - "foo_true": $0, - "foo_false": $1 + "foo_true": foo_true, + "foo_false": foo_false }; } diff --git a/test/wasm2js/indirect-select.wast b/test/wasm2js/indirect-select.wast index fc6f4c4706e..a493ec14cfd 100644 --- a/test/wasm2js/indirect-select.wast +++ b/test/wasm2js/indirect-select.wast @@ -1,7 +1,7 @@ (module (type $none_=>_i32 (func (result i32))) (import "env" "table" (table $timport 6 funcref)) - (func "foo-true" (param $x i32) (result i32) + (func $foo-true (export "foo-true") (param $x i32) (result i32) (call_indirect (type $none_=>_i32) (select (i32.const 1) @@ -10,7 +10,7 @@ ) ) ) - (func "foo-false" (param $x i32) (result i32) + (func $foo-false (export "foo-false") (param $x i32) (result i32) (call_indirect (type $none_=>_i32) (select (i32.const 0) diff --git a/test/wasm2js/minified-memory.2asm.js b/test/wasm2js/minified-memory.2asm.js index 3e7b29b8916..1d3e8c942f8 100644 --- a/test/wasm2js/minified-memory.2asm.js +++ b/test/wasm2js/minified-memory.2asm.js @@ -22,7 +22,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function foo() { return HEAP32[0 >> 2] | 0 | 0; } @@ -53,7 +53,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/minified-memory.2asm.js.opt b/test/wasm2js/minified-memory.2asm.js.opt index 9c5f51f889d..6d1dfa47d7f 100644 --- a/test/wasm2js/minified-memory.2asm.js.opt +++ b/test/wasm2js/minified-memory.2asm.js.opt @@ -22,7 +22,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { + function foo() { return HEAP32[0]; } @@ -53,7 +53,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/minified-memory.wast b/test/wasm2js/minified-memory.wast index 0fc1e301825..fb3725aaa69 100644 --- a/test/wasm2js/minified-memory.wast +++ b/test/wasm2js/minified-memory.wast @@ -1,6 +1,6 @@ (module (import "env" "a" (memory $0 1)) - (func "foo" (result i32) + (func $foo (export "foo") (result i32) (i32.load (i32.const 0)) ) ) diff --git a/test/wasm2js/reinterpret_scratch.2asm.js b/test/wasm2js/reinterpret_scratch.2asm.js index ef53077336a..547206072a9 100644 --- a/test/wasm2js/reinterpret_scratch.2asm.js +++ b/test/wasm2js/reinterpret_scratch.2asm.js @@ -38,11 +38,11 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { - var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $0_1 = Math_fround(0); + function foo() { + var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $0 = Math_fround(0); wasm2js_scratch_store_f64(+(305419896.0)); i64toi32_i32$0 = wasm2js_scratch_load_i32(1 | 0) | 0; - i64toi32_i32$1 = (wasm2js_scratch_store_f32($0_1), wasm2js_scratch_load_i32(2)); + i64toi32_i32$1 = (wasm2js_scratch_store_f32($0), wasm2js_scratch_load_i32(2)); HEAP32[i64toi32_i32$1 >> 2] = wasm2js_scratch_load_i32(0 | 0) | 0; HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; return HEAP32[0 >> 2] | 0 | 0; @@ -54,7 +54,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/reinterpret_scratch.2asm.js.opt b/test/wasm2js/reinterpret_scratch.2asm.js.opt index d1e01844200..bc077cdce1f 100644 --- a/test/wasm2js/reinterpret_scratch.2asm.js.opt +++ b/test/wasm2js/reinterpret_scratch.2asm.js.opt @@ -34,12 +34,12 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; - function $0() { - var $0_1 = 0; + function foo() { + var $0 = 0; wasm2js_scratch_store_f64(305419896.0); - $0_1 = wasm2js_scratch_load_i32(1) | 0; + $0 = wasm2js_scratch_load_i32(1) | 0; HEAP32[0] = wasm2js_scratch_load_i32(0); - HEAP32[1] = $0_1; + HEAP32[1] = $0; return HEAP32[0]; } @@ -49,7 +49,7 @@ function asmFunc(imports) { } return { - "foo": $0 + "foo": foo }; } diff --git a/test/wasm2js/reinterpret_scratch.wast b/test/wasm2js/reinterpret_scratch.wast index bfaf6838050..4741a69406c 100644 --- a/test/wasm2js/reinterpret_scratch.wast +++ b/test/wasm2js/reinterpret_scratch.wast @@ -1,6 +1,6 @@ (module (memory $0 1 1) - (func "foo" (result i32) + (func $foo (export "foo") (result i32) (local $0 f32) (i64.store align=4 (i32.reinterpret_f32 ;; i32 0 diff --git a/test/wasm2js/sign_ext.2asm.js b/test/wasm2js/sign_ext.2asm.js index 4ce98c880d1..220b2753da5 100644 --- a/test/wasm2js/sign_ext.2asm.js +++ b/test/wasm2js/sign_ext.2asm.js @@ -14,17 +14,17 @@ function asmFunc(imports) { var env = imports.env; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; - function $0(x) { + function test8(x) { x = x | 0; return x << 24 >> 24 | 0; } - function $1(x) { + function test16(x) { x = x | 0; return x << 16 >> 16 | 0; } - function $2(x, x$hi) { + function test8_i64(x, x$hi) { x = x | 0; x$hi = x$hi | 0; var i64toi32_i32$2 = 0, i64toi32_i32$1 = 0; @@ -34,7 +34,7 @@ function asmFunc(imports) { return i64toi32_i32$2 | 0; } - function $3(x, x$hi) { + function test16_i64(x, x$hi) { x = x | 0; x$hi = x$hi | 0; var i64toi32_i32$2 = 0, i64toi32_i32$1 = 0; @@ -44,7 +44,7 @@ function asmFunc(imports) { return i64toi32_i32$2 | 0; } - function $4(x, x$hi) { + function test32_i64(x, x$hi) { x = x | 0; x$hi = x$hi | 0; var i64toi32_i32$2 = 0, i64toi32_i32$1 = 0; @@ -54,15 +54,15 @@ function asmFunc(imports) { return i64toi32_i32$2 | 0; } - function legalstub$2($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4_1 = 0, $4$hi = 0, $7$hi = 0, $2_1 = 0, $2$hi = 0; + function legalstub$test8_i64($0, $1) { + $0 = $0 | 0; + $1 = $1 | 0; + var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4 = 0, $4$hi = 0, $7$hi = 0, $2 = 0, $2$hi = 0; i64toi32_i32$0 = 0; - $4_1 = $0_1; + $4 = $0; $4$hi = i64toi32_i32$0; i64toi32_i32$0 = 0; - i64toi32_i32$2 = $1_1; + i64toi32_i32$2 = $1; i64toi32_i32$1 = 0; i64toi32_i32$3 = 32; i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; @@ -75,13 +75,13 @@ function asmFunc(imports) { } $7$hi = i64toi32_i32$1; i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4_1; + i64toi32_i32$0 = $4; i64toi32_i32$2 = $7$hi; i64toi32_i32$3 = $12; i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - i64toi32_i32$2 = $2(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; + i64toi32_i32$2 = test8_i64(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - $2_1 = i64toi32_i32$2; + $2 = i64toi32_i32$2; $2$hi = i64toi32_i32$0; i64toi32_i32$1 = i64toi32_i32$2; i64toi32_i32$2 = 0; @@ -96,18 +96,18 @@ function asmFunc(imports) { } setTempRet0($13 | 0); i64toi32_i32$2 = $2$hi; - return $2_1 | 0; + return $2 | 0; } - function legalstub$3($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4_1 = 0, $4$hi = 0, $7$hi = 0, $2_1 = 0, $2$hi = 0; + function legalstub$test16_i64($0, $1) { + $0 = $0 | 0; + $1 = $1 | 0; + var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4 = 0, $4$hi = 0, $7$hi = 0, $2 = 0, $2$hi = 0; i64toi32_i32$0 = 0; - $4_1 = $0_1; + $4 = $0; $4$hi = i64toi32_i32$0; i64toi32_i32$0 = 0; - i64toi32_i32$2 = $1_1; + i64toi32_i32$2 = $1; i64toi32_i32$1 = 0; i64toi32_i32$3 = 32; i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; @@ -120,13 +120,13 @@ function asmFunc(imports) { } $7$hi = i64toi32_i32$1; i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4_1; + i64toi32_i32$0 = $4; i64toi32_i32$2 = $7$hi; i64toi32_i32$3 = $12; i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - i64toi32_i32$2 = $3(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; + i64toi32_i32$2 = test16_i64(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - $2_1 = i64toi32_i32$2; + $2 = i64toi32_i32$2; $2$hi = i64toi32_i32$0; i64toi32_i32$1 = i64toi32_i32$2; i64toi32_i32$2 = 0; @@ -141,18 +141,18 @@ function asmFunc(imports) { } setTempRet0($13 | 0); i64toi32_i32$2 = $2$hi; - return $2_1 | 0; + return $2 | 0; } - function legalstub$4($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4_1 = 0, $4$hi = 0, $7$hi = 0, $2_1 = 0, $2$hi = 0; + function legalstub$test32_i64($0, $1) { + $0 = $0 | 0; + $1 = $1 | 0; + var i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $4 = 0, $4$hi = 0, $7$hi = 0, $2 = 0, $2$hi = 0; i64toi32_i32$0 = 0; - $4_1 = $0_1; + $4 = $0; $4$hi = i64toi32_i32$0; i64toi32_i32$0 = 0; - i64toi32_i32$2 = $1_1; + i64toi32_i32$2 = $1; i64toi32_i32$1 = 0; i64toi32_i32$3 = 32; i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; @@ -165,13 +165,13 @@ function asmFunc(imports) { } $7$hi = i64toi32_i32$1; i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4_1; + i64toi32_i32$0 = $4; i64toi32_i32$2 = $7$hi; i64toi32_i32$3 = $12; i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - i64toi32_i32$2 = $4(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; + i64toi32_i32$2 = test32_i64(i64toi32_i32$0 | i64toi32_i32$3 | 0 | 0, i64toi32_i32$2 | 0) | 0; i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - $2_1 = i64toi32_i32$2; + $2 = i64toi32_i32$2; $2$hi = i64toi32_i32$0; i64toi32_i32$1 = i64toi32_i32$2; i64toi32_i32$2 = 0; @@ -186,15 +186,15 @@ function asmFunc(imports) { } setTempRet0($13 | 0); i64toi32_i32$2 = $2$hi; - return $2_1 | 0; + return $2 | 0; } return { - "test8": $0, - "test16": $1, - "test8_i64": legalstub$2, - "test16_i64": legalstub$3, - "test32_i64": legalstub$4 + "test8": test8, + "test16": test16, + "test8_i64": legalstub$test8_i64, + "test16_i64": legalstub$test16_i64, + "test32_i64": legalstub$test32_i64 }; } diff --git a/test/wasm2js/sign_ext.2asm.js.opt b/test/wasm2js/sign_ext.2asm.js.opt index 41f79ecc58a..650b1c320b6 100644 --- a/test/wasm2js/sign_ext.2asm.js.opt +++ b/test/wasm2js/sign_ext.2asm.js.opt @@ -14,42 +14,42 @@ function asmFunc(imports) { var env = imports.env; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; - function $0($0_1) { - $0_1 = $0_1 | 0; - return $0_1 << 24 >> 24; + function test8($0) { + $0 = $0 | 0; + return $0 << 24 >> 24; } - function $1($0_1) { - $0_1 = $0_1 | 0; - return $0_1 << 16 >> 16; + function test16($0) { + $0 = $0 | 0; + return $0 << 16 >> 16; } - function legalstub$2($0_1, $1_1) { - $0_1 = $0_1 << 24 >> 24; - i64toi32_i32$HIGH_BITS = $0_1 >> 31; + function legalstub$test8_i64($0, $1) { + $0 = $0 << 24 >> 24; + i64toi32_i32$HIGH_BITS = $0 >> 31; setTempRet0(i64toi32_i32$HIGH_BITS | 0); - return $0_1; + return $0; } - function legalstub$3($0_1, $1_1) { - $0_1 = $0_1 << 16 >> 16; - i64toi32_i32$HIGH_BITS = $0_1 >> 31; + function legalstub$test16_i64($0, $1) { + $0 = $0 << 16 >> 16; + i64toi32_i32$HIGH_BITS = $0 >> 31; setTempRet0(i64toi32_i32$HIGH_BITS | 0); - return $0_1; + return $0; } - function legalstub$4($0_1, $1_1) { - i64toi32_i32$HIGH_BITS = $0_1 >> 31; + function legalstub$test32_i64($0, $1) { + i64toi32_i32$HIGH_BITS = $0 >> 31; setTempRet0(i64toi32_i32$HIGH_BITS | 0); - return $0_1; + return $0; } return { - "test8": $0, - "test16": $1, - "test8_i64": legalstub$2, - "test16_i64": legalstub$3, - "test32_i64": legalstub$4 + "test8": test8, + "test16": test16, + "test8_i64": legalstub$test8_i64, + "test16_i64": legalstub$test16_i64, + "test32_i64": legalstub$test32_i64 }; } diff --git a/test/wasm2js/sign_ext.wast b/test/wasm2js/sign_ext.wast index 825502a3f35..6a3f91515f5 100644 --- a/test/wasm2js/sign_ext.wast +++ b/test/wasm2js/sign_ext.wast @@ -1,17 +1,17 @@ (module - (func "test8" (param $x i32) (result i32) + (func $test8 (export "test8") (param $x i32) (result i32) (i32.extend8_s (local.get $x)) ) - (func "test16" (param $x i32) (result i32) + (func $test16 (export "test16") (param $x i32) (result i32) (i32.extend16_s (local.get $x)) ) - (func "test8_i64" (param $x i64) (result i64) + (func $test8_i64 (export "test8_i64") (param $x i64) (result i64) (i64.extend8_s (local.get $x)) ) - (func "test16_i64" (param $x i64) (result i64) + (func $test16_i64 (export "test16_i64") (param $x i64) (result i64) (i64.extend16_s (local.get $x)) ) - (func "test32_i64" (param $x i64) (result i64) + (func $test32_i64 (export "test32_i64") (param $x i64) (result i64) (i64.extend32_s (local.get $x)) ) ) From 98cef80eabe2171bb3076767d68b25a85d268c12 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 20 Dec 2023 17:38:40 -0800 Subject: [PATCH 016/553] Unify method pairs with and without Type param (#6184) As suggested in https://github.com/WebAssembly/binaryen/pull/6181#discussion_r1427188670, using `std::optional`, this unifies two different versions of `make***`, for block-like structures (`block`, `if`, `loop`, `try`, and `try_table`) with and without a type parameter. This also allows unifying of `finalize` methods, with and without a type. This also sets `breakability` argument of `Block::finalize` to `Unknown` so we can only have one `Block::finalize` that handles all cases. This also adds an optional `std::optional type` parameter to `blockifyWithName`, and `makeSequence` functions in `wasm-builder.h`. blockify was not included because it has a variadic parameter. --- src/wasm-builder.h | 134 +++++++++++------------------------ src/wasm.h | 63 ++++++++-------- src/wasm/wasm.cpp | 121 +++++++++++++++---------------- test/example/stack-utils.cpp | 2 +- 4 files changed, 125 insertions(+), 195 deletions(-) diff --git a/src/wasm-builder.h b/src/wasm-builder.h index fdb489c33ac..dd5b498be8f 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -20,6 +20,7 @@ #include "ir/manipulation.h" #include "parsing.h" #include "wasm.h" +#include namespace wasm { @@ -189,15 +190,7 @@ class Builder { bool>; template = true> - Block* makeBlock(const T& items) { - auto* ret = wasm.allocator.alloc(); - ret->list.set(items); - ret->finalize(); - return ret; - } - - template = true> - Block* makeBlock(const T& items, Type type) { + Block* makeBlock(const T& items, std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->list.set(items); ret->finalize(type); @@ -205,38 +198,29 @@ class Builder { } template = true> - Block* makeBlock(Name name, const T& items, Type type) { + Block* makeBlock(Name name, + const T& items, + std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->name = name; ret->list.set(items); ret->finalize(type); return ret; } - Block* makeBlock(std::initializer_list&& items) { - return makeBlock(items); - } - Block* makeBlock(std::initializer_list&& items, Type type) { + Block* makeBlock(std::initializer_list&& items, + std::optional type = std::nullopt) { return makeBlock(items, type); } - Block* - makeBlock(Name name, std::initializer_list&& items, Type type) { + Block* makeBlock(Name name, + std::initializer_list&& items, + std::optional type = std::nullopt) { return makeBlock(name, items, type); } If* makeIf(Expression* condition, Expression* ifTrue, - Expression* ifFalse = nullptr) { - auto* ret = wasm.allocator.alloc(); - ret->condition = condition; - ret->ifTrue = ifTrue; - ret->ifFalse = ifFalse; - ret->finalize(); - return ret; - } - If* makeIf(Expression* condition, - Expression* ifTrue, - Expression* ifFalse, - Type type) { + Expression* ifFalse = nullptr, + std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->condition = condition; ret->ifTrue = ifTrue; @@ -244,14 +228,9 @@ class Builder { ret->finalize(type); return ret; } - Loop* makeLoop(Name name, Expression* body) { - auto* ret = wasm.allocator.alloc(); - ret->name = name; - ret->body = body; - ret->finalize(); - return ret; - } - Loop* makeLoop(Name name, Expression* body, Type type) { + Loop* makeLoop(Name name, + Expression* body, + std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->name = name; ret->body = body; @@ -792,77 +771,47 @@ class Builder { const std::vector& catchTags, const std::vector& catchBodies, Name delegateTarget, - Type type, - bool hasType) { // differentiate whether a type was passed in + std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->name = name; ret->body = body; ret->catchTags.set(catchTags); ret->catchBodies.set(catchBodies); - if (hasType) { - ret->finalize(type); - } else { - ret->finalize(); - } + ret->finalize(type); return ret; } public: - Try* makeTry(Expression* body, - const std::vector& catchTags, - const std::vector& catchBodies) { - return makeTry( - Name(), body, catchTags, catchBodies, Name(), Type::none, false); - } + // TODO delete? Try* makeTry(Expression* body, const std::vector& catchTags, const std::vector& catchBodies, - Type type) { - return makeTry(Name(), body, catchTags, catchBodies, Name(), type, true); - } - Try* makeTry(Name name, - Expression* body, - const std::vector& catchTags, - const std::vector& catchBodies) { - return makeTry( - name, body, catchTags, catchBodies, Name(), Type::none, false); + std::optional type = std::nullopt) { + return makeTry(Name(), body, catchTags, catchBodies, Name(), type); } Try* makeTry(Name name, Expression* body, const std::vector& catchTags, const std::vector& catchBodies, - Type type) { - return makeTry(name, body, catchTags, catchBodies, Name(), type, true); - } - Try* makeTry(Expression* body, Name delegateTarget) { - return makeTry(Name(), body, {}, {}, delegateTarget, Type::none, false); - } - Try* makeTry(Expression* body, Name delegateTarget, Type type) { - return makeTry(Name(), body, {}, {}, delegateTarget, type, true); + std::optional type = std::nullopt) { + return makeTry(name, body, catchTags, catchBodies, Name(), type); } - Try* makeTry(Name name, Expression* body, Name delegateTarget) { - return makeTry(name, body, {}, {}, delegateTarget, Type::none, false); - } - Try* makeTry(Name name, Expression* body, Name delegateTarget, Type type) { - return makeTry(name, body, {}, {}, delegateTarget, type, true); + Try* makeTry(Expression* body, + Name delegateTarget, + std::optional type = std::nullopt) { + return makeTry(Name(), body, {}, {}, delegateTarget, type); } - TryTable* makeTryTable(Expression* body, - const std::vector& catchTags, - const std::vector& catchDests, - const std::vector& catchRefs) { - auto* ret = wasm.allocator.alloc(); - ret->body = body; - ret->catchTags.set(catchTags); - ret->catchDests.set(catchDests); - ret->catchRefs.set(catchRefs); - ret->finalize(&wasm); - return ret; + Try* makeTry(Name name, + Expression* body, + Name delegateTarget, + std::optional type = std::nullopt) { + return makeTry(name, body, {}, {}, delegateTarget, type); } TryTable* makeTryTable(Expression* body, const std::vector& catchTags, const std::vector& catchDests, const std::vector& catchRefs, - Type type) { + std::optional type = std::nullopt) { auto* ret = wasm.allocator.alloc(); ret->body = body; ret->catchTags.set(catchTags); @@ -1359,8 +1308,10 @@ class Builder { // ensure a node is a block, if it isn't already, and optionally append to the // block this variant sets a name for the block, so it will not reuse a block // already named - Block* - blockifyWithName(Expression* any, Name name, Expression* append = nullptr) { + Block* blockifyWithName(Expression* any, + Name name, + Expression* append = nullptr, + std::optional type = std::nullopt) { Block* block = nullptr; if (any) { block = any->dynCast(); @@ -1371,21 +1322,16 @@ class Builder { block->name = name; if (append) { block->list.push_back(append); - block->finalize(); + block->finalize(type); } return block; } // a helper for the common pattern of a sequence of two expressions. Similar // to blockify, but does *not* reuse a block if the first is one. - Block* makeSequence(Expression* left, Expression* right) { - auto* block = makeBlock(left); - block->list.push_back(right); - block->finalize(); - return block; - } - - Block* makeSequence(Expression* left, Expression* right, Type type) { + Block* makeSequence(Expression* left, + Expression* right, + std::optional type = std::nullopt) { auto* block = makeBlock(left); block->list.push_back(right); block->finalize(type); diff --git a/src/wasm.h b/src/wasm.h index 576a0d0f19d..8d1587d4223 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -828,23 +828,21 @@ class Block : public SpecificExpression { Name name; ExpressionList list; - // set the type purely based on its contents. this scans the block, so it is - // not fast. - void finalize(); - - // 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 (which may require scanning the block) - void finalize(Type type_); - enum Breakability { Unknown, HasBreak, NoBreak }; - // set the type given you know its type, and you know if there is a break to - // this block. this avoids the need to scan the contents of the block in the - // case that it might be unreachable, so it is recommended if you already know - // the type and breakability anyhow. - void finalize(Type type_, Breakability breakability); + // If type_ is not given, set the type purely based on its contents. this + // scans the block, so it is not fast. + // If type_ is given, 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 (which may require scanning the block) + // + // If breakability is given, you know if there is a break to this block. this + // avoids the need to scan the contents of the block in the case that it might + // be unreachable, so it is recommended if you already know the type and + // breakability anyhow. + void finalize(std::optional type_ = std::nullopt, + Breakability breakability = Unknown); }; class If : public SpecificExpression { @@ -856,14 +854,12 @@ class If : public SpecificExpression { Expression* ifTrue; Expression* ifFalse; - // 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. - void finalize(Type type_); - - // set the type purely based on its contents. - void finalize(); + // If type_ is not given, set the type purely based on its contents. + // If type_ is given, 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. + void finalize(std::optional type_ = std::nullopt); }; class Loop : public SpecificExpression { @@ -874,14 +870,12 @@ class Loop : public SpecificExpression { Name name; Expression* body; - // 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. - void finalize(Type type_); - - // set the type purely based on its contents. - void finalize(); + // If type_ is not given, set the type purely based on its contents. + // If type_ is given, 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. + void finalize(std::optional type_ = std::nullopt); }; class Break : public SpecificExpression { @@ -1472,8 +1466,7 @@ class Try : public SpecificExpression { } bool isCatch() const { return !catchBodies.empty(); } bool isDelegate() const { return delegateTarget.is(); } - void finalize(); - void finalize(Type type_); + void finalize(std::optional type_ = std::nullopt); }; // 'try_table' from the new EH proposal @@ -1497,8 +1490,8 @@ class TryTable : public SpecificExpression { // When 'Module*' parameter is given, we cache catch tags' types into // 'sentTypes' array, so that the types can be accessed in other analyses // without accessing the module. - void finalize(Module* wasm = nullptr); - void finalize(Type type_, Module* wasm = nullptr); + void finalize(std::optional type_ = std::nullopt, + Module* wasm = nullptr); // Caches tags' types in the catch clauses in order not to query the module // every time we query the sent types diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 6589ca06984..ad44acda47e 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -141,9 +141,7 @@ Literals getLiteralsFromConstExpression(Expression* curr) { // a block is unreachable if one of its elements is unreachable, // and there are no branches to it -static void -handleUnreachable(Block* block, - Block::Breakability breakability = Block::Unknown) { +static void handleUnreachable(Block* block, Block::Breakability breakability) { if (block->type == Type::unreachable) { return; // nothing to do } @@ -174,13 +172,21 @@ handleUnreachable(Block* block, } } -void Block::finalize() { +void Block::finalize(std::optional type_, Breakability breakability) { + if (type_) { + type = *type_; + if (type == Type::none && list.size() > 0) { + handleUnreachable(this, breakability); + } + return; + } + if (list.size() == 0) { type = Type::none; return; } - // The default type is what is at the end. Next we need to see if breaks and/ - // or unreachability change that. + // The default type is what is at the end. Next we need to see if breaks + // and/ or unreachability change that. type = list.back()->type; if (!name.is()) { // Nothing branches here, so this is easy. @@ -193,10 +199,7 @@ void Block::finalize() { Expression* temp = this; seeker.walk(temp); if (seeker.found) { - // Calculate the supertype of the branch types and the flowed-out type. If - // there is no supertype among the available types, assume the current type - // is already correct. TODO: calculate proper LUBs to compute a new correct - // type in this situation. + // Calculate the LUB of the branch types and the flowed-out type. seeker.types.insert(type); type = Type::getLeastUpperBound(seeker.types); } else { @@ -205,30 +208,17 @@ void Block::finalize() { } } -void Block::finalize(Type type_) { - type = type_; - if (type == Type::none && list.size() > 0) { - handleUnreachable(this); - } -} - -void Block::finalize(Type type_, Breakability breakability) { - type = type_; - if (type == Type::none && list.size() > 0) { - handleUnreachable(this, breakability); - } -} - -void If::finalize(Type type_) { - type = type_; - if (type == Type::none && (condition->type == Type::unreachable || - (ifFalse && ifTrue->type == Type::unreachable && - ifFalse->type == Type::unreachable))) { - type = Type::unreachable; +void If::finalize(std::optional type_) { + if (type_) { + type = *type_; + if (type == Type::none && (condition->type == Type::unreachable || + (ifFalse && ifTrue->type == Type::unreachable && + ifFalse->type == Type::unreachable))) { + type = Type::unreachable; + } + return; } -} -void If::finalize() { type = ifFalse ? Type::getLeastUpperBound(ifTrue->type, ifFalse->type) : Type::none; // if the arms return a value, leave it even if the condition @@ -244,15 +234,17 @@ void If::finalize() { } } -void Loop::finalize(Type type_) { - type = type_; - if (type == Type::none && body->type == Type::unreachable) { - type = Type::unreachable; +void Loop::finalize(std::optional type_) { + if (type_) { + type = *type_; + if (type == Type::none && body->type == Type::unreachable) { + type = Type::unreachable; + } + } else { + type = body->type; } } -void Loop::finalize() { type = body->type; } - void Break::finalize() { if (condition) { if (condition->type == Type::unreachable) { @@ -874,25 +866,25 @@ void TableCopy::finalize() { } } -void Try::finalize() { - // If none of the component bodies' type is a supertype of the others, assume - // the current type is already correct. TODO: Calculate a proper LUB. - std::unordered_set types{body->type}; - types.reserve(catchBodies.size()); - for (auto catchBody : catchBodies) { - types.insert(catchBody->type); - } - type = Type::getLeastUpperBound(types); -} +void Try::finalize(std::optional type_) { + if (type_) { + type = *type_; + bool allUnreachable = body->type == Type::unreachable; + for (auto catchBody : catchBodies) { + allUnreachable &= catchBody->type == Type::unreachable; + } + if (type == Type::none && allUnreachable) { + type = Type::unreachable; + } -void Try::finalize(Type type_) { - type = type_; - bool allUnreachable = body->type == Type::unreachable; - for (auto catchBody : catchBodies) { - allUnreachable &= catchBody->type == Type::unreachable; - } - if (type == Type::none && allUnreachable) { - type = Type::unreachable; + } else { + // Calculate the LUB of catch bodies' types. + std::unordered_set types{body->type}; + types.reserve(catchBodies.size()); + for (auto catchBody : catchBodies) { + types.insert(catchBody->type); + } + type = Type::getLeastUpperBound(types); } } @@ -928,15 +920,14 @@ static void populateTryTableSentTypes(TryTable* curr, Module* wasm) { } } -void TryTable::finalize(Module* wasm) { - type = body->type; - populateTryTableSentTypes(this, wasm); -} - -void TryTable::finalize(Type type_, Module* wasm) { - type = type_; - if (type == Type::none && body->type == Type::unreachable) { - type = Type::unreachable; +void TryTable::finalize(std::optional type_, Module* wasm) { + if (type_) { + type = *type_; + if (type == Type::none && body->type == Type::unreachable) { + type = Type::unreachable; + } + } else { + type = body->type; } populateTryTableSentTypes(this, wasm); } diff --git a/test/example/stack-utils.cpp b/test/example/stack-utils.cpp index f8824e5cb70..e393e13e362 100644 --- a/test/example/stack-utils.cpp +++ b/test/example/stack-utils.cpp @@ -24,7 +24,7 @@ void test_remove_nops() { builder.makeNop(), builder.makeNop(), }, - {Type::i32, Type::i64}); + Type{Type::i32, Type::i64}); std::cout << *block << '\n'; StackUtils::removeNops(block); std::cout << *block << '\n'; From 95ed4f3f0bf0a463cee88a63c5becde4d28692ff Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 2 Jan 2024 12:08:33 -0800 Subject: [PATCH 017/553] Match names more precisely in update_lit_checks.py (#6190) Previously the lit test update script interpreted module names as the names of import items and export names as the names of export items, but it is more precise to use the actual identifiers of the imported or exported items as the names instead. Update update_lit_checks.py to use a more correct regex to match names and to correctly use the identifiers of import and export items as their names. In some cases this can improve the readability of test output. --- scripts/update_lit_checks.py | 20 ++++--- test/lit/basic/empty_imported_table.wast | 9 ++-- test/lit/basic/export-import.wast | 19 ++++--- test/lit/basic/hello_world.wat | 3 +- test/lit/basic/imported_memory.wast | 11 ++-- test/lit/basic/imported_memory_growth.wast | 11 ++-- test/lit/basic/memory-import.wast | 3 +- test/lit/basic/memory-import64.wast | 3 +- test/lit/basic/min.wast | 3 +- test/lit/basic/multi-memories-basics.wast | 11 ++-- test/lit/basic/multi-table.wast | 7 +-- test/lit/basic/mutable-global.wast | 3 +- test/lit/basic/newsyntax.wast | 25 +++++---- test/lit/basic/polymorphic_stack.wast | 33 ++++++------ test/lit/basic/reference-types.wast | 10 ++-- test/lit/basic/table-import.wast | 9 ++-- test/lit/basic/tags.wast | 37 ++++++------- test/lit/basic/unit.wat | 24 +++++---- .../ctor-eval/ctor_after_serialization.wat | 28 +++++----- test/lit/ctor-eval/extern.wast | 45 ++++++++-------- test/lit/ctor-eval/table.wat | 11 ++-- test/lit/ctor-eval/v128.wast | 3 +- .../generate-dyncalls_all-features.wast | 3 +- test/lit/passes/gufa.wast | 23 ++++---- .../inlining-optimizing_optimize-level=3.wast | 52 +++++++++--------- test/lit/passes/jspi-args.wast | 8 +-- test/lit/passes/jspi-table.wast | 3 +- test/lit/passes/jspi.wast | 32 ++++++----- ...egalize-js-interface-exported-helpers.wast | 9 ++-- .../legalize-js-interface-minimally.wast | 6 ++- .../legalize-js-interface_all-features.wast | 21 +++++--- ...egalize-js-interface-export-originals.wast | 4 +- .../remove-unused-module-elements-refs.wast | 40 ++++++++------ ...e-unused-module-elements_all-features.wast | 53 ++++++++++++------- .../lit/wasm-split/jspi-secondary-export.wast | 43 +++++++-------- test/lit/wasm-split/jspi.wast | 4 +- .../multi-memory-lowering-export.wast | 15 +++--- .../multi-memory-lowering-import.wast | 11 ++-- test/lit/wat-kitchen-sink.wast | 15 +++--- 39 files changed, 392 insertions(+), 278 deletions(-) diff --git a/scripts/update_lit_checks.py b/scripts/update_lit_checks.py index 79af92ab986..345ff39d0c6 100755 --- a/scripts/update_lit_checks.py +++ b/scripts/update_lit_checks.py @@ -37,12 +37,15 @@ CHECK_PREFIX_RE = re.compile(r'.*--check-prefix[= ](\S+).*') MODULE_RE = re.compile(r'^\(module.*$', re.MULTILINE) -ALL_ITEMS = '|'.join(['type', 'import', 'global', 'memory', 'data', 'table', - 'elem', 'tag', 'export', 'start', 'func']) +DECL_ITEMS = '|'.join(['type', 'global', 'memory', 'data', 'table', + 'elem', 'tag', 'start', 'func']) +IMPORT_ITEM = r'import\s*"[^"]*"\s*"[^"]*"\s*\((?:' + DECL_ITEMS + ')' +EXPORT_ITEM = r'export\s*"[^"]*"\s*\((?:' + DECL_ITEMS + ')' +ALL_ITEMS = DECL_ITEMS + '|' + IMPORT_ITEM + '|' + EXPORT_ITEM # Regular names as well as the "declare" in (elem declare ... to get declarative # segments included in the output. -ITEM_NAME = r'\$[^\s()]*|"[^\s()]*"|declare' +ITEM_NAME = r'\$[^\s()]*|\$"[^"]*"|declare' # FIXME: This does not handle nested string contents. For example, # (data (i32.const 10) "hello(") @@ -55,6 +58,11 @@ FUZZ_EXEC_FUNC = re.compile(r'^\[fuzz-exec\] calling (?P\S*)$') +def indentKindName(match): + # Return the indent, kind, and name from an ITEM_RE match + return (match[1], match[2].split()[0], match[3]) + + def warn(msg): print(f'warning: {msg}', file=sys.stderr) @@ -141,7 +149,7 @@ def parse_output_modules(text): for module in split_modules(text): items = [] for match in ITEM_RE.finditer(module): - kind, name = match[2], match[3] + _, kind, name = indentKindName(match) end = find_end(module, match.end(1)) lines = module[match.start():end].split('\n') items.append(((kind, name), lines)) @@ -247,7 +255,7 @@ def update_test(args, test, lines, tmp): for line in lines: match = ITEM_RE.match(line) if match: - kind, name = match[2], match[3] + _, kind, name = indentKindName(match) named_items.append((kind, name)) script = script_name @@ -286,7 +294,7 @@ def pad(line): output_lines.append(line) continue - indent, kind, name = match.groups() + indent, kind, name = indentKindName(match) for prefix, items in output.items(): # If the output for this prefix contains an item with this diff --git a/test/lit/basic/empty_imported_table.wast b/test/lit/basic/empty_imported_table.wast index 1a874dc0835..5cc6d178ca0 100644 --- a/test/lit/basic/empty_imported_table.wast +++ b/test/lit/basic/empty_imported_table.wast @@ -10,12 +10,15 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module - ;; CHECK-TEXT: (import "env" "table" (table $timport$0 0 0 funcref)) - ;; CHECK-BIN: (import "env" "table" (table $timport$0 0 0 funcref)) - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 0 0 funcref)) (import "env" "table" (table 0 0 funcref)) + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 0 0 funcref)) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 0 0 funcref)) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 0 0 funcref)) + ;; CHECK-BIN-NODEBUG: (memory $0 0) (memory $0 0) ) diff --git a/test/lit/basic/export-import.wast b/test/lit/basic/export-import.wast index 853e1d93a7b..717681138b4 100644 --- a/test/lit/basic/export-import.wast +++ b/test/lit/basic/export-import.wast @@ -14,21 +14,26 @@ ;; CHECK-BIN: (type $v (func)) (type $v (func)) ;; CHECK-TEXT: (import "env" "test2" (global $test2 i32)) - ;; CHECK-BIN: (import "env" "test2" (global $test2 i32)) - ;; CHECK-BIN-NODEBUG: (type $0 (func)) - ;; CHECK-BIN-NODEBUG: (import "env" "test2" (global $gimport$0 i32)) - (import "env" "test1" (func $test1)) ;; CHECK-TEXT: (import "env" "test1" (func $test1 (type $v))) + ;; CHECK-BIN: (import "env" "test2" (global $test2 i32)) + ;; CHECK-BIN: (import "env" "test1" (func $test1 (type $v))) - ;; CHECK-BIN-NODEBUG: (import "env" "test1" (func $fimport$0 (type $0))) + (import "env" "test1" (func $test1)) (import "env" "test2" (global $test2 i32)) ;; CHECK-TEXT: (export "test1" (func $test1)) ;; CHECK-BIN: (export "test1" (func $test1)) - ;; CHECK-BIN-NODEBUG: (export "test1" (func $fimport$0)) (export "test1" (func $test1)) ;; CHECK-TEXT: (export "test2" (global $test2)) ;; CHECK-BIN: (export "test2" (global $test2)) - ;; CHECK-BIN-NODEBUG: (export "test2" (global $gimport$0)) (export "test2" (global $test2)) ) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (import "env" "test2" (global $gimport$0 i32)) + +;; CHECK-BIN-NODEBUG: (import "env" "test1" (func $fimport$0 (type $0))) + +;; CHECK-BIN-NODEBUG: (export "test1" (func $fimport$0)) + +;; CHECK-BIN-NODEBUG: (export "test2" (global $gimport$0)) diff --git a/test/lit/basic/hello_world.wat b/test/lit/basic/hello_world.wat index 5ddb3012845..1ba2f901285 100644 --- a/test/lit/basic/hello_world.wat +++ b/test/lit/basic/hello_world.wat @@ -21,7 +21,6 @@ (memory $0 256 256) ;; CHECK-TEXT: (export "add" (func $add)) ;; CHECK-BIN: (export "add" (func $add)) - ;; CHECK-BIN-NODEBUG: (export "add" (func $0)) (export "add" (func $add)) ;; CHECK-TEXT: (func $add (type $i32_i32_=>_i32) (param $x i32) (param $y i32) (result i32) ;; CHECK-TEXT-NEXT: (i32.add @@ -42,6 +41,8 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (export "add" (func $0)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (param $1 i32) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (i32.add ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) diff --git a/test/lit/basic/imported_memory.wast b/test/lit/basic/imported_memory.wast index 52eccce7f07..1fa9aaa3840 100644 --- a/test/lit/basic/imported_memory.wast +++ b/test/lit/basic/imported_memory.wast @@ -12,10 +12,13 @@ (module ;; CHECK-TEXT: (import "env" "memory" (memory $0 256 256)) ;; CHECK-BIN: (import "env" "memory" (memory $0 256 256)) - ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256 256)) (import "env" "memory" (memory $0 256 256)) - ;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 256 funcref)) - ;; CHECK-BIN: (import "env" "table" (table $timport$0 256 256 funcref)) - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 256 funcref)) (import "env" "table" (table 256 256 funcref)) ) +;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 256 funcref)) + +;; CHECK-BIN: (import "env" "table" (table $timport$0 256 256 funcref)) + +;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256 256)) + +;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 256 funcref)) diff --git a/test/lit/basic/imported_memory_growth.wast b/test/lit/basic/imported_memory_growth.wast index d1d62c2d985..aa5d02d4760 100644 --- a/test/lit/basic/imported_memory_growth.wast +++ b/test/lit/basic/imported_memory_growth.wast @@ -12,10 +12,13 @@ (module ;; CHECK-TEXT: (import "env" "memory" (memory $0 256)) ;; CHECK-BIN: (import "env" "memory" (memory $0 256)) - ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256)) (import "env" "memory" (memory $0 256)) - ;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 funcref)) - ;; CHECK-BIN: (import "env" "table" (table $timport$0 256 funcref)) - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 funcref)) (import "env" "table" (table 256 funcref)) ) +;; CHECK-TEXT: (import "env" "table" (table $timport$0 256 funcref)) + +;; CHECK-BIN: (import "env" "table" (table $timport$0 256 funcref)) + +;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 256)) + +;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 256 funcref)) diff --git a/test/lit/basic/memory-import.wast b/test/lit/basic/memory-import.wast index fb6a3d62317..ce761653ddd 100644 --- a/test/lit/basic/memory-import.wast +++ b/test/lit/basic/memory-import.wast @@ -16,7 +16,6 @@ (type $0 (func (result i32))) ;; CHECK-TEXT: (import "env" "memory" (memory $0 1 1)) ;; CHECK-BIN: (import "env" "memory" (memory $0 1 1)) - ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) (import "env" "memory" (memory $0 1 1)) ;; CHECK-TEXT: (func $foo (type $0) (result i32) @@ -35,6 +34,8 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (i32.load offset=13 ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 37) diff --git a/test/lit/basic/memory-import64.wast b/test/lit/basic/memory-import64.wast index 7794d6b5fd5..38362d6b2d1 100644 --- a/test/lit/basic/memory-import64.wast +++ b/test/lit/basic/memory-import64.wast @@ -16,7 +16,6 @@ (type $0 (func (result i32))) ;; CHECK-TEXT: (import "env" "memory" (memory $0 i64 1 1)) ;; CHECK-BIN: (import "env" "memory" (memory $0 i64 1 1)) - ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 i64 1 1)) (import "env" "memory" (memory $0 i64 1 1)) ;; CHECK-TEXT: (func $foo (type $0) (result i32) @@ -35,6 +34,8 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 i64 1 1)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (i32.load offset=13 ;; CHECK-BIN-NODEBUG-NEXT: (i64.const 37) diff --git a/test/lit/basic/min.wast b/test/lit/basic/min.wast index 74898f59fe5..44928cd832f 100644 --- a/test/lit/basic/min.wast +++ b/test/lit/basic/min.wast @@ -32,7 +32,6 @@ (memory $0 256 256) ;; CHECK-TEXT: (export "floats" (func $floats)) ;; CHECK-BIN: (export "floats" (func $floats)) - ;; CHECK-BIN-NODEBUG: (export "floats" (func $0)) (export "floats" (func $floats)) ;; CHECK-TEXT: (func $floats (type $0) (param $f f32) (result f32) @@ -183,6 +182,8 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (export "floats" (func $0)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 f32) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (local $1 f32) ;; CHECK-BIN-NODEBUG-NEXT: (f32.add diff --git a/test/lit/basic/multi-memories-basics.wast b/test/lit/basic/multi-memories-basics.wast index c9e4d6c7ed8..3f023079d78 100644 --- a/test/lit/basic/multi-memories-basics.wast +++ b/test/lit/basic/multi-memories-basics.wast @@ -18,11 +18,6 @@ (type $none_=>_i32 (func (result i32))) ;; CHECK-TEXT: (import "env" "memory" (memory $importedMemory 1 1)) ;; CHECK-BIN: (import "env" "memory" (memory $importedMemory 1 1)) - ;; CHECK-BIN-NODEBUG: (type $0 (func)) - - ;; CHECK-BIN-NODEBUG: (type $1 (func (result i32))) - - ;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) (import "env" "memory" (memory $importedMemory 1 1)) ;; CHECK-TEXT: (memory $memory1 1 500) ;; CHECK-BIN: (memory $memory1 1 500) @@ -367,6 +362,12 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (type $1 (func (result i32))) + +;; CHECK-BIN-NODEBUG: (import "env" "memory" (memory $mimport$0 1 1)) + ;; CHECK-BIN-NODEBUG: (memory $0 1 500) ;; CHECK-BIN-NODEBUG: (memory $1 1 800) diff --git a/test/lit/basic/multi-table.wast b/test/lit/basic/multi-table.wast index d5c7b10aa83..b856f8494c5 100644 --- a/test/lit/basic/multi-table.wast +++ b/test/lit/basic/multi-table.wast @@ -25,9 +25,6 @@ ;; CHECK-BIN: (global $g2 i32 (i32.const 0)) (global $g2 i32 (i32.const 0)) - ;; CHECK-BIN-NODEBUG: (type $0 (func)) - - ;; CHECK-BIN-NODEBUG: (import "a" "b" (table $timport$0 1 10 funcref)) (import "a" "b" (table $t1 1 10 funcref)) ;; CHECK-TEXT: (table $t2 3 3 funcref) ;; CHECK-BIN: (table $t2 3 3 funcref) @@ -116,6 +113,10 @@ ;; CHECK-BIN-NEXT: ) (func $h) ) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (import "a" "b" (table $timport$0 1 10 funcref)) + ;; CHECK-BIN-NODEBUG: (global $global$0 (ref null $0) (ref.func $0)) ;; CHECK-BIN-NODEBUG: (global $global$1 i32 (i32.const 0)) diff --git a/test/lit/basic/mutable-global.wast b/test/lit/basic/mutable-global.wast index 154a40a191f..fff5d8d5b60 100644 --- a/test/lit/basic/mutable-global.wast +++ b/test/lit/basic/mutable-global.wast @@ -16,7 +16,6 @@ (type $0 (func)) ;; CHECK-TEXT: (import "env" "global-mut" (global $global-mut (mut i32))) ;; CHECK-BIN: (import "env" "global-mut" (global $global-mut (mut i32))) - ;; CHECK-BIN-NODEBUG: (import "env" "global-mut" (global $gimport$0 (mut i32))) (import "env" "global-mut" (global $global-mut (mut i32))) ;; CHECK-TEXT: (func $foo (type $0) @@ -44,6 +43,8 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (import "env" "global-mut" (global $gimport$0 (mut i32))) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (global.set $gimport$0 ;; CHECK-BIN-NODEBUG-NEXT: (i32.add diff --git a/test/lit/basic/newsyntax.wast b/test/lit/basic/newsyntax.wast index 204bed3ab08..33d805c3122 100644 --- a/test/lit/basic/newsyntax.wast +++ b/test/lit/basic/newsyntax.wast @@ -10,22 +10,13 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module + (import "env" "table" (table 9 9 funcref)) + ;; CHECK-TEXT: (type $0 (func)) ;; CHECK-TEXT: (type $1 (func (param i32 f64) (result i32))) ;; CHECK-TEXT: (import "env" "table" (table $timport$0 9 9 funcref)) - ;; CHECK-BIN: (type $0 (func)) - - ;; CHECK-BIN: (type $1 (func (param i32 f64) (result i32))) - - ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) - ;; CHECK-BIN-NODEBUG: (type $0 (func)) - - ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f64) (result i32))) - - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) - (import "env" "table" (table 9 9 funcref)) ;; CHECK-TEXT: (export "call_indirect" (func $call_indirect)) @@ -41,6 +32,12 @@ ;; CHECK-TEXT-NEXT: (i32.const 1) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func)) + + ;; CHECK-BIN: (type $1 (func (param i32 f64) (result i32))) + + ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN: (export "call_indirect" (func $call_indirect)) ;; CHECK-BIN: (func $call_indirect (type $0) @@ -62,6 +59,12 @@ (call_indirect (i32.const 1)) ) ) +;; CHECK-BIN-NODEBUG: (type $0 (func)) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f64) (result i32))) + +;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN-NODEBUG: (export "call_indirect" (func $0)) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) diff --git a/test/lit/basic/polymorphic_stack.wast b/test/lit/basic/polymorphic_stack.wast index f91847817e6..d51117e16f9 100644 --- a/test/lit/basic/polymorphic_stack.wast +++ b/test/lit/basic/polymorphic_stack.wast @@ -17,26 +17,13 @@ ;; CHECK-BIN: (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) + (import "env" "table" (table 9 9 funcref)) + ;; CHECK-TEXT: (type $2 (func)) ;; CHECK-TEXT: (type $3 (func (param i32))) ;; CHECK-TEXT: (import "env" "table" (table $timport$0 9 9 funcref)) - ;; CHECK-BIN: (type $2 (func)) - - ;; CHECK-BIN: (type $3 (func (param i32))) - - ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) - ;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) - - ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result i32))) - - ;; CHECK-BIN-NODEBUG: (type $2 (func)) - - ;; CHECK-BIN-NODEBUG: (type $3 (func (param i32))) - - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) - (import "env" "table" (table 9 9 funcref)) ;; CHECK-TEXT: (func $break-and-binary (type $0) (result i32) ;; CHECK-TEXT-NEXT: (block $x (result i32) @@ -53,6 +40,12 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $2 (func)) + + ;; CHECK-BIN: (type $3 (func (param i32))) + + ;; CHECK-BIN: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN: (func $break-and-binary (type $0) (result i32) ;; CHECK-BIN-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NEXT: (unreachable) @@ -371,6 +364,16 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (type $0 (func (result i32))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result i32))) + +;; CHECK-BIN-NODEBUG: (type $2 (func)) + +;; CHECK-BIN-NODEBUG: (type $3 (func (param i32))) + +;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 9 9 funcref)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast index 9a3a5c663c9..2b502d78939 100644 --- a/test/lit/basic/reference-types.wast +++ b/test/lit/basic/reference-types.wast @@ -174,11 +174,7 @@ (import "env" "import_func" (func $import_func (param eqref) (result funcref))) (import "env" "import_global" (global $import_global eqref)) - ;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) - - ;; CHECK-BIN-NODEBUG: (export "export_func" (func $fimport$0)) (export "export_func" (func $import_func (param eqref) (result funcref))) - ;; CHECK-BIN-NODEBUG: (export "export_global" (global $gimport$0)) (export "export_global" (global $import_global)) ;; Test global initializer expressions @@ -1846,6 +1842,12 @@ ;; CHECK-BIN-NEXT: ) (func $ref-taken-but-not-in-table) ) +;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) + +;; CHECK-BIN-NODEBUG: (export "export_func" (func $fimport$0)) + +;; CHECK-BIN-NODEBUG: (export "export_global" (global $gimport$0)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $4) (param $0 eqref) ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/table-import.wast b/test/lit/basic/table-import.wast index 347da5634ff..79e6f6eeb79 100644 --- a/test/lit/basic/table-import.wast +++ b/test/lit/basic/table-import.wast @@ -14,13 +14,16 @@ ;; CHECK-BIN: (type $0 (func)) ;; CHECK-BIN-NODEBUG: (type $0 (func)) (type $0 (func)) - ;; CHECK-TEXT: (import "env" "table" (table $timport$0 1 1 funcref)) - ;; CHECK-BIN: (import "env" "table" (table $timport$0 1 1 funcref)) - ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 1 1 funcref)) (import "env" "table" (table 1 1 funcref)) (elem (i32.const 0) $foo) + ;; CHECK-TEXT: (import "env" "table" (table $timport$0 1 1 funcref)) + ;; CHECK-TEXT: (memory $0 0) + ;; CHECK-BIN: (import "env" "table" (table $timport$0 1 1 funcref)) + ;; CHECK-BIN: (memory $0 0) + ;; CHECK-BIN-NODEBUG: (import "env" "table" (table $timport$0 1 1 funcref)) + ;; CHECK-BIN-NODEBUG: (memory $0 0) (memory $0 0) diff --git a/test/lit/basic/tags.wast b/test/lit/basic/tags.wast index e6c5d2ccc50..5fbc0b81106 100644 --- a/test/lit/basic/tags.wast +++ b/test/lit/basic/tags.wast @@ -56,13 +56,6 @@ (tag $e-export (export "ex0") (param i32)) (tag $e-import (import "env" "im0") (param i32)) - ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32 f32))) - - ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) - - ;; CHECK-BIN-NODEBUG: (type $2 (func)) - - ;; CHECK-BIN-NODEBUG: (import "env" "im0" (tag $eimport$0 (param i32))) (import "env" "im1" (tag (param i32 f32))) ;; CHECK-TEXT: (export "ex0" (tag $e-export)) @@ -70,22 +63,30 @@ ;; CHECK-BIN: (export "ex0" (tag $e-export)) ;; CHECK-BIN: (export "ex1" (tag $e)) - ;; CHECK-BIN-NODEBUG: (import "env" "im1" (tag $eimport$1 (param i32 f32))) + (export "ex1" (tag $e)) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (param i32 f32))) - ;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32))) - ;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i32 f32)) +;; CHECK-BIN-NODEBUG: (type $2 (func)) - ;; CHECK-BIN-NODEBUG: (tag $tag$2) +;; CHECK-BIN-NODEBUG: (import "env" "im0" (tag $eimport$0 (param i32))) - ;; CHECK-BIN-NODEBUG: (tag $tag$3 (param i32 f32)) +;; CHECK-BIN-NODEBUG: (import "env" "im1" (tag $eimport$1 (param i32 f32))) - ;; CHECK-BIN-NODEBUG: (tag $tag$4 (param i32 f32)) +;; CHECK-BIN-NODEBUG: (tag $tag$0 (param i32)) - ;; CHECK-BIN-NODEBUG: (tag $tag$5 (param i32)) +;; CHECK-BIN-NODEBUG: (tag $tag$1 (param i32 f32)) - ;; CHECK-BIN-NODEBUG: (export "ex0" (tag $tag$5)) +;; CHECK-BIN-NODEBUG: (tag $tag$2) - ;; CHECK-BIN-NODEBUG: (export "ex1" (tag $tag$1)) - (export "ex1" (tag $e)) -) +;; CHECK-BIN-NODEBUG: (tag $tag$3 (param i32 f32)) + +;; CHECK-BIN-NODEBUG: (tag $tag$4 (param i32 f32)) + +;; CHECK-BIN-NODEBUG: (tag $tag$5 (param i32)) + +;; CHECK-BIN-NODEBUG: (export "ex0" (tag $tag$5)) + +;; CHECK-BIN-NODEBUG: (export "ex1" (tag $tag$1)) diff --git a/test/lit/basic/unit.wat b/test/lit/basic/unit.wat index 8392a226948..4fc36b3b7ea 100644 --- a/test/lit/basic/unit.wat +++ b/test/lit/basic/unit.wat @@ -64,20 +64,23 @@ (type $9 (func (param i32 i64))) ;; CHECK-TEXT: (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi (type $FUNCSIG$v))) ;; CHECK-BIN: (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi (type $FUNCSIG$v))) - ;; CHECK-BIN-NODEBUG: (import "env" "_emscripten_asm_const_vi" (func $fimport$0 (type $1))) (import "env" "_emscripten_asm_const_vi" (func $_emscripten_asm_const_vi)) ;; CHECK-TEXT: (import "asm2wasm" "f64-to-int" (func $f64-to-int (type $FUNCSIG$id) (param f64) (result i32))) ;; CHECK-BIN: (import "asm2wasm" "f64-to-int" (func $f64-to-int (type $FUNCSIG$id) (param f64) (result i32))) - ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-to-int" (func $fimport$1 (type $5) (param f64) (result i32))) (import "asm2wasm" "f64-to-int" (func $f64-to-int (param f64) (result i32))) ;; CHECK-TEXT: (import "asm2wasm" "f64-rem" (func $f64-rem (type $FUNCSIG$ddd) (param f64 f64) (result f64))) ;; CHECK-BIN: (import "asm2wasm" "f64-rem" (func $f64-rem (type $FUNCSIG$ddd) (param f64 f64) (result f64))) - ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-rem" (func $fimport$2 (type $4) (param f64 f64) (result f64))) (import "asm2wasm" "f64-rem" (func $f64-rem (param f64 f64) (result f64))) (table 10 funcref) (elem (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) ;; CHECK-TEXT: (memory $0 4096 4096) ;; CHECK-BIN: (memory $0 4096 4096) + ;; CHECK-BIN-NODEBUG: (import "env" "_emscripten_asm_const_vi" (func $fimport$0 (type $1))) + + ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-to-int" (func $fimport$1 (type $5) (param f64) (result i32))) + + ;; CHECK-BIN-NODEBUG: (import "asm2wasm" "f64-rem" (func $fimport$2 (type $4) (param f64 f64) (result f64))) + ;; CHECK-BIN-NODEBUG: (memory $0 4096 4096) (memory $0 4096 4096) (data (i32.const 1026) "\14\00") @@ -95,13 +98,6 @@ ;; CHECK-BIN: (elem $0 (i32.const 0) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) ;; CHECK-BIN: (export "big_negative" (func $big_negative)) - ;; CHECK-BIN-NODEBUG: (data $0 (i32.const 1026) "\14\00") - - ;; CHECK-BIN-NODEBUG: (table $0 10 funcref) - - ;; CHECK-BIN-NODEBUG: (elem $0 (i32.const 0) $17 $0 $17 $17 $18 $18 $1 $18 $17 $15) - - ;; CHECK-BIN-NODEBUG: (export "big_negative" (func $0)) (export "big_negative" (func $big_negative)) ;; CHECK-TEXT: (func $big_negative (type $FUNCSIG$v) ;; CHECK-TEXT-NEXT: (local $temp f64) @@ -1743,6 +1739,14 @@ ) ) ) +;; CHECK-BIN-NODEBUG: (data $0 (i32.const 1026) "\14\00") + +;; CHECK-BIN-NODEBUG: (table $0 10 funcref) + +;; CHECK-BIN-NODEBUG: (elem $0 (i32.const 0) $17 $0 $17 $17 $18 $18 $1 $18 $17 $15) + +;; CHECK-BIN-NODEBUG: (export "big_negative" (func $0)) + ;; CHECK-BIN-NODEBUG: (func $0 (type $1) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 f64) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 diff --git a/test/lit/ctor-eval/ctor_after_serialization.wat b/test/lit/ctor-eval/ctor_after_serialization.wat index 45e811804fa..df37f7e8bb6 100644 --- a/test/lit/ctor-eval/ctor_after_serialization.wat +++ b/test/lit/ctor-eval/ctor_after_serialization.wat @@ -10,15 +10,7 @@ ;; CHECK: (type $A (struct )) (type $A (struct)) - ;; CHECK: (type $1 (func (result (ref any)))) - - ;; CHECK: (type $2 (func)) - - ;; CHECK: (global $ctor-eval$global (ref $A) (struct.new_default $A)) - - ;; CHECK: (export "new" (func $new_2)) (export "new" (func $new)) - ;; CHECK: (export "nop" (func $nop_3)) (export "nop" (func $nop)) (func $new (result (ref any)) @@ -30,6 +22,16 @@ ) ) +;; CHECK: (type $1 (func (result (ref any)))) + +;; CHECK: (type $2 (func)) + +;; CHECK: (global $ctor-eval$global (ref $A) (struct.new_default $A)) + +;; CHECK: (export "new" (func $new_2)) + +;; CHECK: (export "nop" (func $nop_3)) + ;; CHECK: (func $new_2 (type $1) (result (ref any)) ;; CHECK-NEXT: (global.get $ctor-eval$global) ;; CHECK-NEXT: ) @@ -53,11 +55,7 @@ (struct.new_default $A) ) - ;; CHECK: (global $ctor-eval$global_1 (ref $A) (struct.new_default $A)) - - ;; CHECK: (export "new" (func $new_2)) (export "new" (func $new)) - ;; CHECK: (export "nop" (func $nop_3)) (export "nop" (func $nop)) (func $new (result (ref any)) @@ -69,6 +67,12 @@ (global.get $ctor-eval$global) ) ) +;; CHECK: (global $ctor-eval$global_1 (ref $A) (struct.new_default $A)) + +;; CHECK: (export "new" (func $new_2)) + +;; CHECK: (export "nop" (func $nop_3)) + ;; CHECK: (func $new_2 (type $1) (result (ref any)) ;; CHECK-NEXT: (global.get $ctor-eval$global_1) ;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/extern.wast b/test/lit/ctor-eval/extern.wast index 5bb5c8cbc53..9a8779abfea 100644 --- a/test/lit/ctor-eval/extern.wast +++ b/test/lit/ctor-eval/extern.wast @@ -8,29 +8,8 @@ ;; CHECK: (type $struct (struct (field externref))) (type $struct (struct (field externref))) - ;; CHECK: (type $2 (func (result externref))) - - ;; CHECK: (type $3 (func (result anyref))) - - ;; CHECK: (global $ctor-eval$global (ref $array) (array.new_fixed $array 3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: )) - - ;; CHECK: (global $ctor-eval$global_1 (ref $struct) (struct.new $struct - ;; CHECK-NEXT: (extern.externalize - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: )) - - ;; CHECK: (export "test1" (func $test1_3)) (export "test1" (func $test1)) - ;; CHECK: (export "test2" (func $test2_4)) (export "test2" (func $test2)) - ;; CHECK: (export "test3" (func $test3_5)) (export "test3" (func $test3)) (func $test1 (result externref) @@ -70,6 +49,30 @@ ) ) +;; CHECK: (type $2 (func (result externref))) + +;; CHECK: (type $3 (func (result anyref))) + +;; CHECK: (global $ctor-eval$global (ref $array) (array.new_fixed $array 3 +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: (i32.const 2) +;; CHECK-NEXT: (i32.const 3) +;; CHECK-NEXT: )) + +;; CHECK: (global $ctor-eval$global_1 (ref $struct) (struct.new $struct +;; CHECK-NEXT: (extern.externalize +;; CHECK-NEXT: (ref.i31 +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: )) + +;; CHECK: (export "test1" (func $test1_3)) + +;; CHECK: (export "test2" (func $test2_4)) + +;; CHECK: (export "test3" (func $test3_5)) + ;; CHECK: (func $test1_3 (type $2) (result externref) ;; CHECK-NEXT: (extern.externalize ;; CHECK-NEXT: (ref.i31 diff --git a/test/lit/ctor-eval/table.wat b/test/lit/ctor-eval/table.wat index 73534f59b0d..0954faeea7d 100644 --- a/test/lit/ctor-eval/table.wat +++ b/test/lit/ctor-eval/table.wat @@ -10,11 +10,6 @@ (elem (i32.const 0) $nop) - ;; CHECK: (elem $0 (i32.const 0) $nop) - - ;; CHECK: (elem declare func $trap) - - ;; CHECK: (export "run" (func $run_3)) (export "run" (func $run)) (func $run (type $none_=>_none) @@ -35,6 +30,12 @@ ) ) + ;; CHECK: (elem $0 (i32.const 0) $nop) + + ;; CHECK: (elem declare func $trap) + + ;; CHECK: (export "run" (func $run_3)) + ;; CHECK: (func $nop (type $none_=>_none) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) diff --git a/test/lit/ctor-eval/v128.wast b/test/lit/ctor-eval/v128.wast index 03a7bb9d851..009ef57f25c 100644 --- a/test/lit/ctor-eval/v128.wast +++ b/test/lit/ctor-eval/v128.wast @@ -9,10 +9,11 @@ ;; CHECK: (memory $0 (shared 16 17)) (memory $0 (shared 16 17)) + (export "v128" (func $v128)) ;; CHECK: (data $0 (i32.const 23) "\e0\ff\c0N\8e\00\00\fe\01\00\12\81\85\fd\ff\90") ;; CHECK: (export "v128" (func $v128_2)) - (export "v128" (func $v128)) + ;; CHECK: (export "keepalive" (func $keepalive)) (export "keepalive" (func $keepalive)) diff --git a/test/lit/passes/generate-dyncalls_all-features.wast b/test/lit/passes/generate-dyncalls_all-features.wast index 34c387b0844..99611727b2a 100644 --- a/test/lit/passes/generate-dyncalls_all-features.wast +++ b/test/lit/passes/generate-dyncalls_all-features.wast @@ -73,8 +73,9 @@ ;; CHECK: (type $3 (func (param i32 i32))) ;; CHECK: (import "env" "table" (table $timport$0 1 1 funcref)) - (import "env" "invoke_vii" (func $invoke_vii (param i32 i32 i32))) + ;; CHECK: (import "env" "invoke_vii" (func $invoke_vii (type $0) (param i32 i32 i32))) + (import "env" "invoke_vii" (func $invoke_vii (param i32 i32 i32))) (import "env" "table" (table 1 1 funcref)) (elem (i32.const 0) $f) ;; CHECK: (elem $0 (i32.const 0) $f) diff --git a/test/lit/passes/gufa.wast b/test/lit/passes/gufa.wast index 58166cd4651..b97e620ab62 100644 --- a/test/lit/passes/gufa.wast +++ b/test/lit/passes/gufa.wast @@ -583,6 +583,8 @@ (ref.func $reffed) ) + (export "table" (table 0)) + ;; CHECK: (type $1 (func)) ;; CHECK: (table $0 10 funcref) @@ -590,7 +592,6 @@ ;; CHECK: (elem $0 (i32.const 0) $reffed) ;; CHECK: (export "table" (table $0)) - (export "table" (table 0)) ;; CHECK: (func $reffed (type $i) (param $x i32) ;; CHECK-NEXT: (drop @@ -924,6 +925,12 @@ ;; CHECK: (type $A (func (param i32))) (type $A (func (param i32))) + (import "binaryen-intrinsics" "call.without.effects" + (func $call-without-effects (param i32 funcref))) + + (import "other" "import" + (func $other-import (param funcref))) + ;; CHECK: (type $1 (func (param i32 funcref))) ;; CHECK: (type $2 (func (param funcref))) @@ -931,12 +938,8 @@ ;; CHECK: (type $3 (func)) ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param i32 funcref))) - (import "binaryen-intrinsics" "call.without.effects" - (func $call-without-effects (param i32 funcref))) ;; CHECK: (import "other" "import" (func $other-import (type $2) (param funcref))) - (import "other" "import" - (func $other-import (param funcref))) ;; CHECK: (elem declare func $target-drop $target-keep) @@ -994,6 +997,12 @@ ;; CHECK: (type $A (func (param i32))) (type $A (func (param i32))) + (import "binaryen-intrinsics" "call.without.effects" + (func $call-without-effects (param i32 funcref))) + + (import "other" "import" + (func $other-import (param funcref))) + ;; CHECK: (type $1 (func (param i32 funcref))) ;; CHECK: (type $2 (func (param funcref))) @@ -1001,12 +1010,8 @@ ;; CHECK: (type $3 (func (param (ref null $A)))) ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param i32 funcref))) - (import "binaryen-intrinsics" "call.without.effects" - (func $call-without-effects (param i32 funcref))) ;; CHECK: (import "other" "import" (func $other-import (type $2) (param funcref))) - (import "other" "import" - (func $other-import (param funcref))) ;; CHECK: (elem declare func $target-keep $target-keep-2) diff --git a/test/lit/passes/inlining-optimizing_optimize-level=3.wast b/test/lit/passes/inlining-optimizing_optimize-level=3.wast index dfdbed53376..a0e320bd640 100644 --- a/test/lit/passes/inlining-optimizing_optimize-level=3.wast +++ b/test/lit/passes/inlining-optimizing_optimize-level=3.wast @@ -33,54 +33,58 @@ ;; CHECK: (type $11 (func (param i32 i32 i32 i32 i32))) ;; CHECK: (import "env" "memory" (memory $0 256 256)) - (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + ;; CHECK: (import "env" "table" (table $timport$0 18 18 funcref)) - (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + ;; CHECK: (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) - (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) ;; CHECK: (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) - (import "env" "abort" (func $abort)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) ;; CHECK: (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) - (import "env" "nullFunc_ii" (func $nullFunc_ii (param i32))) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) ;; CHECK: (import "env" "memoryBase" (global $memoryBase i32)) - (import "env" "nullFunc_iiii" (func $nullFunc_iiii (param i32))) + ;; CHECK: (import "env" "tableBase" (global $tableBase i32)) - (import "env" "nullFunc_vi" (func $nullFunc_vi (param i32))) + ;; CHECK: (import "env" "abort" (func $abort)) - (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) + (import "env" "abort" (func $abort)) ;; CHECK: (import "env" "nullFunc_ii" (func $nullFunc_ii (param i32))) - (import "env" "___lock" (func $___lock (param i32))) + (import "env" "nullFunc_ii" (func $nullFunc_ii (param i32))) ;; CHECK: (import "env" "nullFunc_iiii" (func $nullFunc_iiii (param i32))) - (import "env" "_pthread_self" (func $_pthread_self (result i32))) + (import "env" "nullFunc_iiii" (func $nullFunc_iiii (param i32))) ;; CHECK: (import "env" "nullFunc_vi" (func $nullFunc_vi (param i32))) - (import "env" "_abort" (func $_abort)) + (import "env" "nullFunc_vi" (func $nullFunc_vi (param i32))) ;; CHECK: (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) - (import "env" "___syscall6" (func $___syscall6 (param i32 i32) (result i32))) + (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) ;; CHECK: (import "env" "___lock" (func $___lock (param i32))) - (import "env" "_sbrk" (func $_sbrk (param i32) (result i32))) + (import "env" "___lock" (func $___lock (param i32))) ;; CHECK: (import "env" "_pthread_self" (func $_pthread_self (result i32))) - (import "env" "_time" (func $_time (param i32) (result i32))) + (import "env" "_pthread_self" (func $_pthread_self (result i32))) ;; CHECK: (import "env" "_abort" (func $_abort)) - (import "env" "_emscripten_memcpy_big" (func $_emscripten_memcpy_big (param i32 i32 i32) (result i32))) + (import "env" "_abort" (func $_abort)) ;; CHECK: (import "env" "___syscall6" (func $___syscall6 (param i32 i32) (result i32))) - (import "env" "___syscall54" (func $___syscall54 (param i32 i32) (result i32))) + (import "env" "___syscall6" (func $___syscall6 (param i32 i32) (result i32))) ;; CHECK: (import "env" "_sbrk" (func $_sbrk (param i32) (result i32))) - (import "env" "___unlock" (func $___unlock (param i32))) + (import "env" "_sbrk" (func $_sbrk (param i32) (result i32))) ;; CHECK: (import "env" "_time" (func $_time (param i32) (result i32))) - (import "env" "___syscall140" (func $___syscall140 (param i32 i32) (result i32))) + (import "env" "_time" (func $_time (param i32) (result i32))) ;; CHECK: (import "env" "_emscripten_memcpy_big" (func $_emscripten_memcpy_big (param i32 i32 i32) (result i32))) - (import "env" "_pthread_cleanup_push" (func $_pthread_cleanup_push (param i32 i32))) + (import "env" "_emscripten_memcpy_big" (func $_emscripten_memcpy_big (param i32 i32 i32) (result i32))) ;; CHECK: (import "env" "___syscall54" (func $___syscall54 (param i32 i32) (result i32))) - (import "env" "_sysconf" (func $_sysconf (param i32) (result i32))) + (import "env" "___syscall54" (func $___syscall54 (param i32 i32) (result i32))) ;; CHECK: (import "env" "___unlock" (func $___unlock (param i32))) - (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) + (import "env" "___unlock" (func $___unlock (param i32))) ;; CHECK: (import "env" "___syscall140" (func $___syscall140 (param i32 i32) (result i32))) - (import "env" "memory" (memory $0 256 256)) + (import "env" "___syscall140" (func $___syscall140 (param i32 i32) (result i32))) ;; CHECK: (import "env" "_pthread_cleanup_push" (func $_pthread_cleanup_push (param i32 i32))) - (import "env" "table" (table 18 18 funcref)) + (import "env" "_pthread_cleanup_push" (func $_pthread_cleanup_push (param i32 i32))) ;; CHECK: (import "env" "_sysconf" (func $_sysconf (param i32) (result i32))) - (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "_sysconf" (func $_sysconf (param i32) (result i32))) ;; CHECK: (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) + (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 18 18 funcref)) + (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) ;; CHECK: (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) diff --git a/test/lit/passes/jspi-args.wast b/test/lit/passes/jspi-args.wast index 1a23c171699..8229e34e971 100644 --- a/test/lit/passes/jspi-args.wast +++ b/test/lit/passes/jspi-args.wast @@ -3,18 +3,20 @@ (module ;; sleep_async should have a wrapper function built. + (import "js" "sleep_async" (func $sleep_async (param f64) (result i32))) ;; CHECK: (type $0 (func (param f64) (result i32))) ;; CHECK: (type $1 (func (param externref f64) (result i32))) ;; CHECK: (import "js" "sleep_sync" (func $sleep_sync (type $0) (param f64) (result i32))) - (import "js" "sleep_async" (func $sleep_async (param f64) (result i32))) - ;; CHECK: (import "js" "sleep_async" (func $import$sleep_async (type $1) (param externref f64) (result i32))) (import "js" "sleep_sync" (func $sleep_sync (param f64) (result i32))) + (export "update_state_async" (func $update_state_async)) + ;; CHECK: (import "js" "sleep_async" (func $import$sleep_async (type $1) (param externref f64) (result i32))) + ;; CHECK: (global $suspender (mut externref) (ref.null noextern)) ;; CHECK: (export "update_state_async" (func $export$update_state_async)) - (export "update_state_async" (func $update_state_async)) + ;; CHECK: (export "update_state_sync" (func $update_state_sync)) (export "update_state_sync" (func $update_state_sync)) ;; This function calls an async sleep so a wrapper should be created for it. diff --git a/test/lit/passes/jspi-table.wast b/test/lit/passes/jspi-table.wast index 526b0a4b7e2..c702357c014 100644 --- a/test/lit/passes/jspi-table.wast +++ b/test/lit/passes/jspi-table.wast @@ -12,10 +12,11 @@ ;; CHECK: (table $0 1 1 funcref) (table $0 1 1 funcref) (elem (i32.const 1) func $update_state) + (export "update_state" (func $update_state)) + ;; CHECK: (elem $0 (i32.const 1) $export$update_state) ;; CHECK: (export "update_state" (func $export$update_state)) - (export "update_state" (func $update_state)) ;; CHECK: (func $update_state (type $0) (param $param f64) (result i32) ;; CHECK-NEXT: (i32.const 42) diff --git a/test/lit/passes/jspi.wast b/test/lit/passes/jspi.wast index 780a54ccbe4..12396cc6d71 100644 --- a/test/lit/passes/jspi.wast +++ b/test/lit/passes/jspi.wast @@ -4,6 +4,19 @@ (module + (import "js" "compute_delta" (func $compute_delta (param f64) (result i32))) + (import "js" "import_and_export" (func $import_and_export (param i32) (result i32))) + (import "js" "import_void_return" (func $import_void_return (param i32))) + (export "update_state_void" (func $update_state_void)) + (export "update_state" (func $update_state)) + ;; Test duplicating an export. + (export "update_state_again" (func $update_state)) + ;; Test that a name collision on the parameters is handled. + (export "update_state_param_collision" (func $update_state_param_collision)) + ;; Test function that is imported and exported. + (export "import_and_export" (func $import_and_export)) + + ;; CHECK: (type $0 (func (param externref f64) (result i32))) ;; CHECK: (type $1 (func (param f64) (result i32))) @@ -19,27 +32,22 @@ ;; CHECK: (type $6 (func (param externref i32))) ;; CHECK: (import "js" "compute_delta" (func $import$compute_delta (type $0) (param externref f64) (result i32))) - (import "js" "compute_delta" (func $compute_delta (param f64) (result i32))) + ;; CHECK: (import "js" "import_and_export" (func $import$import_and_export (type $2) (param externref i32) (result i32))) - (import "js" "import_and_export" (func $import_and_export (param i32) (result i32))) + ;; CHECK: (import "js" "import_void_return" (func $import$import_void_return (type $6) (param externref i32))) - (import "js" "import_void_return" (func $import_void_return (param i32))) + ;; CHECK: (global $suspender (mut externref) (ref.null noextern)) ;; CHECK: (export "update_state_void" (func $export$update_state_void)) - (export "update_state_void" (func $update_state_void)) + ;; CHECK: (export "update_state" (func $export$update_state)) - (export "update_state" (func $update_state)) - ;; Test duplicating an export. + ;; CHECK: (export "update_state_again" (func $export$update_state)) - (export "update_state_again" (func $update_state)) - ;; Test that a name collision on the parameters is handled. + ;; CHECK: (export "update_state_param_collision" (func $export$update_state_param_collision)) - (export "update_state_param_collision" (func $update_state_param_collision)) - ;; Test function that is imported and exported. - ;; CHECK: (export "import_and_export" (func $export$import_and_export)) - (export "import_and_export" (func $import_and_export)) + ;; CHECK: (export "import_and_export" (func $export$import_and_export)) ;; CHECK: (func $update_state (type $1) (param $param f64) (result i32) ;; CHECK-NEXT: (call $compute_delta diff --git a/test/lit/passes/legalize-js-interface-exported-helpers.wast b/test/lit/passes/legalize-js-interface-exported-helpers.wast index 35271ee8420..707cbe5c9b1 100644 --- a/test/lit/passes/legalize-js-interface-exported-helpers.wast +++ b/test/lit/passes/legalize-js-interface-exported-helpers.wast @@ -6,6 +6,10 @@ ;; RUN: wasm-opt %s --legalize-js-interface --pass-arg=legalize-js-interface-exported-helpers -S -o - | filecheck %s (module + (export "get_i64" (func $get_i64)) + (import "env" "imported" (func $imported (result i64))) + (export "__set_temp_ret" (func $__set_temp_ret)) + (export "__get_temp_ret" (func $__get_temp_ret)) ;; CHECK: (type $0 (func (result i32))) ;; CHECK: (type $1 (func (result i64))) @@ -15,10 +19,7 @@ ;; CHECK: (import "env" "imported" (func $legalimport$imported (result i32))) ;; CHECK: (export "get_i64" (func $legalstub$get_i64)) - (export "get_i64" (func $get_i64)) - (import "env" "imported" (func $imported (result i64))) - (export "__set_temp_ret" (func $__set_temp_ret)) - (export "__get_temp_ret" (func $__get_temp_ret)) + ;; CHECK: (func $get_i64 (result i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $legalfunc$imported) diff --git a/test/lit/passes/legalize-js-interface-minimally.wast b/test/lit/passes/legalize-js-interface-minimally.wast index 76bed505c30..664b024b39f 100644 --- a/test/lit/passes/legalize-js-interface-minimally.wast +++ b/test/lit/passes/legalize-js-interface-minimally.wast @@ -16,14 +16,16 @@ ;; CHECK: (import "env" "imported" (func $imported (result i64))) (import "env" "imported" (func $imported (result i64))) - ;; CHECK: (import "env" "setTempRet0" (func $setTempRet0 (param i32))) (import "env" "invoke_vj" (func $invoke_vj (param i64))) + ;; CHECK: (import "env" "setTempRet0" (func $setTempRet0 (param i32))) + ;; CHECK: (import "env" "invoke_vj" (func $legalimport$invoke_vj (param i32 i32))) ;; CHECK: (export "func" (func $func)) (export "func" (func $func)) - ;; CHECK: (export "dynCall_foo" (func $legalstub$dyn)) (export "dynCall_foo" (func $dyn)) + ;; CHECK: (export "dynCall_foo" (func $legalstub$dyn)) + ;; CHECK: (func $func (result i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $imported) diff --git a/test/lit/passes/legalize-js-interface_all-features.wast b/test/lit/passes/legalize-js-interface_all-features.wast index 6afd2bc20e4..611a58da791 100644 --- a/test/lit/passes/legalize-js-interface_all-features.wast +++ b/test/lit/passes/legalize-js-interface_all-features.wast @@ -4,6 +4,10 @@ ;; RUN: foreach %s %t wasm-opt --legalize-js-interface --all-features -S -o - | filecheck %s (module + (import "env" "imported" (func $imported (result i64))) + (import "env" "other" (func $other (param i32) (param i64) (param i64))) + (import "env" "ref-func-arg" (func $ref-func-arg (result i64))) + (export "func" (func $func)) ;; CHECK: (type $0 (func (result i32))) ;; CHECK: (type $1 (func (result i64))) @@ -17,11 +21,11 @@ ;; CHECK: (type $5 (func (param i32 i64 i64))) ;; CHECK: (import "env" "setTempRet0" (func $setTempRet0 (type $4) (param i32))) - (import "env" "imported" (func $imported (result i64))) + ;; CHECK: (import "env" "getTempRet0" (func $getTempRet0 (type $0) (result i32))) - (import "env" "other" (func $other (param i32) (param i64) (param i64))) + ;; CHECK: (import "env" "imported" (func $legalimport$imported (type $0) (result i32))) - (import "env" "ref-func-arg" (func $ref-func-arg (result i64))) + ;; CHECK: (import "env" "other" (func $legalimport$other (type $2) (param i32 i32 i32 i32 i32))) ;; CHECK: (import "env" "ref-func-arg" (func $legalimport$ref-func-arg (type $0) (result i32))) @@ -29,15 +33,18 @@ ;; CHECK: (elem declare func $legalfunc$ref-func-arg) ;; CHECK: (export "func" (func $legalstub$func)) - (export "func" (func $func)) + ;; CHECK: (export "ref-func-test" (func $ref-func-test)) (export "ref-func-test" (func $ref-func-test)) - ;; CHECK: (export "imported" (func $legalstub$imported)) (export "imported" (func $imported)) - ;; CHECK: (export "imported_again" (func $legalstub$imported)) (export "imported_again" (func $imported)) - ;; CHECK: (export "other" (func $legalstub$other)) (export "other" (func $other)) + ;; CHECK: (export "imported" (func $legalstub$imported)) + + ;; CHECK: (export "imported_again" (func $legalstub$imported)) + + ;; CHECK: (export "other" (func $legalstub$other)) + ;; CHECK: (func $func (type $1) (result i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $legalfunc$imported) diff --git a/test/lit/passes/legalize-js-interface_pass-arg=legalize-js-interface-export-originals.wast b/test/lit/passes/legalize-js-interface_pass-arg=legalize-js-interface-export-originals.wast index ba9db7ee5a7..f56db7982c2 100644 --- a/test/lit/passes/legalize-js-interface_pass-arg=legalize-js-interface-export-originals.wast +++ b/test/lit/passes/legalize-js-interface_pass-arg=legalize-js-interface-export-originals.wast @@ -13,9 +13,9 @@ ;; CHECK: (import "env" "setTempRet0" (func $setTempRet0 (param i32))) ;; CHECK: (export "func" (func $legalstub$func)) - (export "func" (func $func)) - ;; CHECK: (export "orig$func" (func $func)) + ;; CHECK: (export "orig$func" (func $func)) + (export "func" (func $func)) ;; CHECK: (func $func (result i64) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/remove-unused-module-elements-refs.wast b/test/lit/passes/remove-unused-module-elements-refs.wast index 00ea9767fc5..44c87fefcd6 100644 --- a/test/lit/passes/remove-unused-module-elements-refs.wast +++ b/test/lit/passes/remove-unused-module-elements-refs.wast @@ -469,20 +469,18 @@ ;; OPEN_WORLD: (type $A (func)) (type $A (func)) - ;; CHECK: (type $1 (func (param funcref))) - - ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) - ;; OPEN_WORLD: (type $1 (func (param funcref))) - - ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref))) - ;; CHECK: (import "other" "import" (func $other-import (type $1) (param funcref))) - ;; OPEN_WORLD: (import "other" "import" (func $other-import (type $1) (param funcref))) (import "other" "import" (func $other-import (param funcref))) + ;; CHECK: (type $1 (func (param funcref))) + + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) + + ;; CHECK: (import "other" "import" (func $other-import (type $1) (param funcref))) + ;; CHECK: (elem declare func $target-drop $target-keep) ;; CHECK: (export "foo" (func $foo)) @@ -495,6 +493,12 @@ ;; CHECK-NEXT: (ref.func $target-drop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; OPEN_WORLD: (type $1 (func (param funcref))) + + ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) + + ;; OPEN_WORLD: (import "other" "import" (func $other-import (type $1) (param funcref))) + ;; OPEN_WORLD: (elem declare func $target-drop $target-keep) ;; OPEN_WORLD: (export "foo" (func $foo)) @@ -546,20 +550,18 @@ ;; OPEN_WORLD: (type $A (func)) (type $A (func)) - ;; CHECK: (type $1 (func (param funcref))) - - ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) - ;; OPEN_WORLD: (type $1 (func (param funcref))) - - ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref))) - ;; CHECK: (import "other" "import" (func $other-import (type $1) (param funcref))) - ;; OPEN_WORLD: (import "other" "import" (func $other-import (type $1) (param funcref))) (import "other" "import" (func $other-import (param funcref))) + ;; CHECK: (type $1 (func (param funcref))) + + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) + + ;; CHECK: (import "other" "import" (func $other-import (type $1) (param funcref))) + ;; CHECK: (elem declare func $target-keep $target-keep-2) ;; CHECK: (export "foo" (func $foo)) @@ -576,6 +578,12 @@ ;; CHECK-NEXT: (ref.func $target-keep-2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; OPEN_WORLD: (type $1 (func (param funcref))) + + ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (type $1) (param funcref))) + + ;; OPEN_WORLD: (import "other" "import" (func $other-import (type $1) (param funcref))) + ;; OPEN_WORLD: (elem declare func $target-keep $target-keep-2) ;; OPEN_WORLD: (export "foo" (func $foo)) diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index 385433189db..15a843064b7 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -175,11 +175,11 @@ (elem (table $1) (offset (i32.const 1)) func) ) (module ;; remove the first table and memory, but not the second one + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 funcref)) ;; CHECK: (type $0 (func)) ;; CHECK: (import "env" "table2" (table $1 1 1 funcref)) - (import "env" "memory" (memory $0 256)) - (import "env" "table" (table 0 funcref)) (import "env" "table2" (table $1 1 1 funcref)) (elem (table $1) (offset (i32.const 0)) func) (elem (table $1) (offset (i32.const 0)) func $f) @@ -203,22 +203,25 @@ (module ;; but not when exported ;; CHECK: (import "env" "memory" (memory $0 256)) (import "env" "memory" (memory $0 256)) - ;; CHECK: (import "env" "table" (table $timport$0 1 funcref)) (import "env" "table" (table 1 funcref)) - ;; CHECK: (export "mem" (memory $0)) (export "mem" (memory 0)) - ;; CHECK: (export "tab" (table $timport$0)) (export "tab" (table 0)) ) +;; CHECK: (import "env" "table" (table $timport$0 1 funcref)) + +;; CHECK: (export "mem" (memory $0)) + +;; CHECK: (export "tab" (table $timport$0)) (module ;; and not when there are segments ;; CHECK: (type $0 (func)) ;; CHECK: (import "env" "memory" (memory $0 256)) (import "env" "memory" (memory $0 256)) - ;; CHECK: (import "env" "table" (table $timport$0 1 funcref)) (import "env" "table" (table 1 funcref)) (data (i32.const 1) "hello, world!") (elem (i32.const 0) $waka) + ;; CHECK: (import "env" "table" (table $timport$0 1 funcref)) + ;; CHECK: (data $0 (i32.const 1) "hello, world!") ;; CHECK: (elem $0 (i32.const 0) $waka) @@ -233,10 +236,12 @@ (type $0 (func)) ;; CHECK: (import "env" "memory" (memory $0 256)) (import "env" "memory" (memory $0 256)) - ;; CHECK: (import "env" "table" (table $timport$0 0 funcref)) (import "env" "table" (table 0 funcref)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (import "env" "table" (table $timport$0 0 funcref)) + + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load @@ -257,8 +262,9 @@ ;; CHECK: (memory $0 (shared 23 256)) (memory $0 (shared 23 256)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 0) @@ -274,8 +280,9 @@ ;; CHECK: (memory $0 (shared 23 256)) (memory $0 (shared 23 256)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (i32.atomic.rmw.add ;; CHECK-NEXT: (i32.const 0) @@ -291,8 +298,9 @@ ;; CHECK: (memory $0 (shared 23 256)) (memory $0 (shared 23 256)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u ;; CHECK-NEXT: (i32.const 0) @@ -309,8 +317,9 @@ ;; CHECK: (memory $0 (shared 23 256)) (memory $0 (shared 23 256)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i64) @@ -339,8 +348,9 @@ ;; CHECK: (memory $0 (shared 23 256)) (memory $0 (shared 23 256)) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (memory.atomic.notify ;; CHECK-NEXT: (i32.const 0) @@ -354,12 +364,13 @@ (module ;; atomic.fence and data.drop do not use a memory, so should not keep the memory alive. (memory $0 (shared 1 1)) (data "") + (export "fake-user" $user) ;; CHECK: (type $0 (func)) ;; CHECK: (data $0 "") ;; CHECK: (export "fake-user" (func $user)) - (export "fake-user" $user) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (atomic.fence) ;; CHECK-NEXT: (data.drop $0) @@ -378,8 +389,9 @@ (memory $1 23 256) (memory $unused 1 1) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.grow $0 @@ -402,8 +414,9 @@ ;; CHECK: (memory $0 23 256) (memory $0 23 256) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (memory.size) ;; CHECK-NEXT: ) @@ -419,8 +432,9 @@ ;; CHECK: (memory $1 1 1) (memory $1 1 1) (memory $unused 1 1) - ;; CHECK: (export "user" (func $user)) (export "user" $user) + ;; CHECK: (export "user" (func $user)) + ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (memory.copy $0 $1 ;; CHECK-NEXT: (i32.const 0) @@ -441,8 +455,9 @@ ;; CHECK: (import "env" "memory" (memory $0 256)) (import "env" "memory" (memory $0 256)) - ;; CHECK: (import "env" "table" (table $timport$0 0 funcref)) (import "env" "table" (table 0 funcref)) + ;; CHECK: (import "env" "table" (table $timport$0 0 funcref)) + ;; CHECK: (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "memoryBase" (global $memoryBase i32)) ;; used in init ;; CHECK: (import "env" "tableBase" (global $tableBase i32)) @@ -467,8 +482,8 @@ ;; CHECK: (import "env" "imported" (global $imported i32)) (import "env" "imported" (global $imported i32)) - ;; CHECK: (import "env" "_puts" (func $_puts (type $2) (param i32) (result i32))) (import "env" "forgetme" (global $forgetme i32)) + ;; CHECK: (import "env" "_puts" (func $_puts (type $2) (param i32) (result i32))) (import "env" "_puts" (func $_puts (param i32) (result i32))) (import "env" "forget_puts" (func $forget_puts (param i32) (result i32))) ;; CHECK: (global $int (mut i32) (global.get $imported)) diff --git a/test/lit/wasm-split/jspi-secondary-export.wast b/test/lit/wasm-split/jspi-secondary-export.wast index 6bb388fecca..57fe849a9af 100644 --- a/test/lit/wasm-split/jspi-secondary-export.wast +++ b/test/lit/wasm-split/jspi-secondary-export.wast @@ -8,27 +8,6 @@ ;; enabled. (module - ;; PRIMARY: (type $0 (func (param i32) (result i32))) - - ;; PRIMARY: (type $3 (func (param externref))) - - ;; PRIMARY: (type $1 (func (param externref i32) (result i32))) - - ;; PRIMARY: (type $2 (func)) - - ;; PRIMARY: (import "env" "__load_secondary_module" (func $import$__load_secondary_module (param externref))) - - ;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32))) - - ;; PRIMARY: (global $suspender (mut externref) (ref.null noextern)) - - ;; PRIMARY: (global $global$1 (mut i32) (i32.const 0)) - - ;; PRIMARY: (table $0 1 funcref) - - ;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0) - - ;; PRIMARY: (export "foo" (func $export$foo)) (export "foo" (func $foo)) ;; SECONDARY: (type $0 (func (param i32) (result i32))) @@ -47,6 +26,28 @@ (i32.const 0) ) ) +;; PRIMARY: (type $0 (func (param i32) (result i32))) + +;; PRIMARY: (type $3 (func (param externref))) + +;; PRIMARY: (type $1 (func (param externref i32) (result i32))) + +;; PRIMARY: (type $2 (func)) + +;; PRIMARY: (import "env" "__load_secondary_module" (func $import$__load_secondary_module (param externref))) + +;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32))) + +;; PRIMARY: (global $suspender (mut externref) (ref.null noextern)) + +;; PRIMARY: (global $global$1 (mut i32) (i32.const 0)) + +;; PRIMARY: (table $0 1 funcref) + +;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0) + +;; PRIMARY: (export "foo" (func $export$foo)) + ;; PRIMARY: (export "load_secondary_module_status" (global $global$1)) ;; PRIMARY: (export "%table" (table $0)) diff --git a/test/lit/wasm-split/jspi.wast b/test/lit/wasm-split/jspi.wast index b1f1b56f36b..340b2acec79 100644 --- a/test/lit/wasm-split/jspi.wast +++ b/test/lit/wasm-split/jspi.wast @@ -29,11 +29,11 @@ ;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0) ;; PRIMARY: (export "foo" (func $export$foo)) - (export "foo" (func $foo)) + ;; PRIMARY: (export "load_secondary_module_status" (global $global$1)) ;; PRIMARY: (export "%foo" (func $foo)) - + (export "foo" (func $foo)) ;; PRIMARY: (export "%table" (table $0)) ;; PRIMARY: (export "%global" (global $suspender)) diff --git a/test/lit/wasm-split/multi-memory-lowering-export.wast b/test/lit/wasm-split/multi-memory-lowering-export.wast index 156ac2efe1e..0721ba2a462 100644 --- a/test/lit/wasm-split/multi-memory-lowering-export.wast +++ b/test/lit/wasm-split/multi-memory-lowering-export.wast @@ -5,17 +5,18 @@ (module (memory $memory1 1) (memory $memory2 1 1) - ;; CHECK: (type $0 (func (result i32))) + (export "mem" (memory $memory1)) +) - ;; CHECK: (type $1 (func (param i32) (result i32))) +;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (global $memory2_byte_offset (mut i32) (i32.const 65536)) +;; CHECK: (type $1 (func (param i32) (result i32))) - ;; CHECK: (memory $combined_memory 1 1) +;; CHECK: (global $memory2_byte_offset (mut i32) (i32.const 65536)) - ;; CHECK: (export "mem" (memory $combined_memory)) - (export "mem" (memory $memory1)) -) +;; CHECK: (memory $combined_memory 1 1) + +;; CHECK: (export "mem" (memory $combined_memory)) ;; CHECK: (func $memory1_size (type $0) (result i32) ;; CHECK-NEXT: (return diff --git a/test/lit/wasm-split/multi-memory-lowering-import.wast b/test/lit/wasm-split/multi-memory-lowering-import.wast index e00c137990f..d62609108c2 100644 --- a/test/lit/wasm-split/multi-memory-lowering-import.wast +++ b/test/lit/wasm-split/multi-memory-lowering-import.wast @@ -3,15 +3,16 @@ ;; RUN: wasm-opt %s --multi-memory-lowering -all -S -o - | filecheck %s (module - ;; CHECK: (type $0 (func (result i32))) - - ;; CHECK: (type $1 (func (param i32) (result i32))) - - ;; CHECK: (import "env" "mem" (memory $combined_memory 2 2)) (import "env" "mem" (memory $memory1 1 1)) (memory $memory2 1 1) ) +;; CHECK: (type $0 (func (result i32))) + +;; CHECK: (type $1 (func (param i32) (result i32))) + +;; CHECK: (import "env" "mem" (memory $combined_memory 2 2)) + ;; CHECK: (global $memory2_byte_offset (mut i32) (i32.const 65536)) ;; CHECK: (func $memory1_size (type $0) (result i32) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index af2fbffc5f5..a45ef7e9c17 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -354,6 +354,7 @@ (tag $tag-pair (param i32 i64)) ;; explicit exports + (export "exported-func" (func 0)) ;; CHECK: (export "g1" (global $g1)) ;; CHECK: (export "g1.1" (global $g1)) @@ -375,19 +376,21 @@ ;; CHECK: (export "t0.1" (tag $imported)) ;; CHECK: (export "exported-func" (func $fimport$0)) - (export "exported-func" (func 0)) - ;; CHECK: (export "exported-table" (table $timport$0)) - (export "exported-table" (table 0)) - ;; CHECK: (export "exported-memory" (memory $mimport$0)) + + ;; CHECK: (export "exported-table" (table $funcs)) + (export "exported-table" (table $funcs)) (export "exported-memory" (memory 0)) + ;; CHECK: (export "exported-memory" (memory $mimport$0)) + ;; CHECK: (export "exported-global" (global $g1)) - (export "exported-global" (global 0)) - ;; CHECK: (export "exported-tag" (tag $imported)) + (export "exported-global" (global $g1)) (export "exported-tag" (tag 0)) ;; functions (func) + ;; CHECK: (export "exported-tag" (tag $imported)) + ;; CHECK: (func $1 (type $void) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) From 5e3f81ceb1259de752bb61d80b26381ff1448828 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 2 Jan 2024 12:36:30 -0800 Subject: [PATCH 018/553] [Parser] Support standalone import definitions (#6191) We previously support the in-line import abbreviation, but now add support for explicit, non-abbreviated imports as well. --- src/parser/contexts.h | 12 +++- src/parser/parsers.h | 70 +++++++++++++++++++ src/parser/wat-parser.cpp | 20 ++++-- test/lit/wat-kitchen-sink.wast | 124 ++++++++++++++++++--------------- 4 files changed, 164 insertions(+), 62 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index e09f8bbd0aa..503f4dc3af9 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -1249,6 +1249,11 @@ struct ParseDefsCtx : TypeParserCtx { return Ok{}; } + Result<> + addMemory(Name, const std::vector&, ImportNames*, TableTypeT, Index) { + return Ok{}; + } + Result<> addGlobal(Name, const std::vector&, ImportNames*, @@ -1259,7 +1264,7 @@ struct ParseDefsCtx : TypeParserCtx { Result<> addImplicitElems(Type type, std::vector&& elems); Result<> addDeclareElem(Name, std::vector&&, Index) { - // TODO: Validate that referenced functions appear in a declaratve element + // TODO: Validate that referenced functions appear in a declarative element // segment. return Ok{}; } @@ -1273,6 +1278,11 @@ struct ParseDefsCtx : TypeParserCtx { Result<> addData(Name, Name* mem, std::optional offset, DataStringT, Index pos); + Result<> + addTag(Name, const std::vector, ImportNames*, TypeUseT, Index) { + return Ok{}; + } + Result<> addExport(Index, Name value, Name name, ExternalKind kind) { wasm.addExport(builder.makeExport(name, value, kind)); return Ok{}; diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 7f4005c3d2a..6dd61730910 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -191,6 +191,7 @@ template Result<> strtype(Ctx&); template MaybeResult subtype(Ctx&); template MaybeResult<> deftype(Ctx&); template MaybeResult locals(Ctx&); +template MaybeResult<> import_(Ctx&); template MaybeResult<> func(Ctx&); template MaybeResult<> table(Ctx&); template MaybeResult<> memory(Ctx&); @@ -2168,6 +2169,71 @@ template MaybeResult locals(Ctx& ctx) { return {}; } +// import ::= '(' 'import' mod:name nm:name importdesc ')' +// importdesc ::= '(' 'func' id? typeuse ')' +// | '(' 'table' id? tabletype ')' +// | '(' 'memory' id? memtype ')' +// | '(' 'global' id? globaltype ')' +// | '(' 'tag' id? typeuse ')' +template MaybeResult<> import_(Ctx& ctx) { + auto pos = ctx.in.getPos(); + + if (!ctx.in.takeSExprStart("import"sv)) { + return {}; + } + + auto mod = ctx.in.takeName(); + if (!mod) { + return ctx.in.err("expected import module name"); + } + + auto nm = ctx.in.takeName(); + if (!nm) { + return ctx.in.err("expected import name"); + } + ImportNames names{*mod, *nm}; + + if (ctx.in.takeSExprStart("func"sv)) { + auto name = ctx.in.takeID(); + auto type = typeuse(ctx); + CHECK_ERR(type); + CHECK_ERR( + ctx.addFunc(name ? *name : Name{}, {}, &names, *type, std::nullopt, pos)); + } else if (ctx.in.takeSExprStart("table"sv)) { + auto name = ctx.in.takeID(); + auto type = tabletype(ctx); + CHECK_ERR(type); + CHECK_ERR(ctx.addTable(name ? *name : Name{}, {}, &names, *type, pos)); + } else if (ctx.in.takeSExprStart("memory"sv)) { + auto name = ctx.in.takeID(); + auto type = memtype(ctx); + CHECK_ERR(type); + CHECK_ERR(ctx.addMemory(name ? *name : Name{}, {}, &names, *type, pos)); + } else if (ctx.in.takeSExprStart("global"sv)) { + auto name = ctx.in.takeID(); + auto type = globaltype(ctx); + CHECK_ERR(type); + CHECK_ERR(ctx.addGlobal( + name ? *name : Name{}, {}, &names, *type, std::nullopt, pos)); + } else if (ctx.in.takeSExprStart("tag"sv)) { + auto name = ctx.in.takeID(); + auto type = typeuse(ctx); + CHECK_ERR(type); + CHECK_ERR(ctx.addTag(name ? *name : Name{}, {}, &names, *type, pos)); + } else { + return ctx.in.err("expected import description"); + } + + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of import description"); + } + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of import"); + } + + return Ok{}; +} + // func ::= '(' 'func' id? ('(' 'export' name ')')* // x,I:typeuse t*:vec(local) (in:instr)* ')' // | '(' 'func' id? ('(' 'export' name ')')* @@ -2651,6 +2717,10 @@ template MaybeResult<> modulefield(Ctx& ctx) { CHECK_ERR(res); return Ok{}; } + if (auto res = import_(ctx)) { + CHECK_ERR(res); + return Ok{}; + } if (auto res = func(ctx)) { CHECK_ERR(res); return Ok{}; diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp index 95dfa1405fb..a9ee2a18923 100644 --- a/src/parser/wat-parser.cpp +++ b/src/parser/wat-parser.cpp @@ -80,9 +80,13 @@ Result<> parseDefs(Ctx& ctx, for (auto& def : defs) { ctx.index = def.index; WithPosition with(ctx, def.pos); - auto parsed = parser(ctx); - CHECK_ERR(parsed); - assert(parsed); + if (auto parsed = parser(ctx)) { + CHECK_ERR(parsed); + } else { + auto im = import_(ctx); + assert(im); + CHECK_ERR(im); + } } return Ok{}; } @@ -174,9 +178,13 @@ Result<> parseModule(Module& wasm, std::string_view input) { ctx.index = i; CHECK_ERR(ctx.visitFunctionStart(wasm.functions[i].get())); WithPosition with(ctx, decls.funcDefs[i].pos); - auto parsed = func(ctx); - CHECK_ERR(parsed); - assert(parsed); + if (auto parsed = func(ctx)) { + CHECK_ERR(parsed); + } else { + auto im = import_(ctx); + assert(im); + CHECK_ERR(im); + } } // Parse exports. diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index a45ef7e9c17..9cf3c1494d7 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -34,12 +34,12 @@ (rec) + ;; CHECK: (type $11 (func)) + ;; CHECK: (type $packed-i8 (array (mut i8))) ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) - ;; CHECK: (type $13 (func)) - ;; CHECK: (type $14 (func (param i32))) ;; CHECK: (type $15 (func (param i32 i64 v128))) @@ -210,48 +210,61 @@ ;; CHECK: (type $submany (sub final $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) (type $submany (sub $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) + ;; imported memories + (memory (export "mem") (export "mem2") (import "" "mem") 0) + ;; CHECK: (type $88 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) + + ;; CHECK: (import "" "mem" (memory $mimport$0 0)) + + ;; CHECK: (import "mod" "imported-m" (memory $m-imported (shared 1 2))) + (import "mod" "imported-m" (memory $m-imported 1 2 shared)) + + ;; imported tables + (table (export "tab") (export "tab2") (import "" "tab") 0 funcref) + (import "mod" "imported-tab" (table 2 3 externref)) + ;; imported globals (global $g1 (export "g1") (export "g1.1") (import "mod" "g1") i32) (global $g2 (import "mod" "g2") (mut i64)) (global (import "" "g3") (ref 0)) (global (import "mod" "") (ref null $many)) + ;; CHECK: (import "" "tab" (table $timport$0 0 funcref)) - ;; imported memories - (memory (export "mem") (export "mem2") (import "" "mem") 0) + ;; CHECK: (import "mod" "imported-tab" (table $timport$1 2 3 externref)) - ;; imported tables - (table (export "tab") (export "tab2") (import "" "tab") 0 funcref) + ;; CHECK: (import "mod" "g1" (global $g1 i32)) + + ;; CHECK: (import "mod" "g2" (global $g2 (mut i64))) + + ;; CHECK: (import "" "g3" (global $gimport$0 (ref $ret2))) + + ;; CHECK: (import "mod" "" (global $gimport$1 (ref null $many))) + + ;; CHECK: (import "mod" "imported-g" (global $g-imported (mut i32))) + (import "mod" "imported-g" (global $g-imported (mut i32))) ;; imported functions (func (export "f5.0") (export "f5.1") (import "mod" "f5")) + (import "mod" "imported-f" (func (param) (result))) ;; imported tags (tag $imported (export "t0.0") (export "t0.1") (import "mod" "t0") (param i32 i64)) (tag (import "mod" "t1")) + (import "mod" "imported-tag" (tag (param) (result))) ;; globals (global (mut i32) i32.const 0) - ;; CHECK: (type $88 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) - - ;; CHECK: (import "" "mem" (memory $mimport$0 0)) - - ;; CHECK: (import "" "tab" (table $timport$0 0 funcref)) - - ;; CHECK: (import "mod" "g1" (global $g1 i32)) - - ;; CHECK: (import "mod" "g2" (global $g2 (mut i64))) - - ;; CHECK: (import "" "g3" (global $gimport$0 (ref $ret2))) - - ;; CHECK: (import "mod" "" (global $gimport$1 (ref null $many))) - ;; CHECK: (import "mod" "f5" (func $fimport$0 (type $void))) + ;; CHECK: (import "mod" "imported-f" (func $fimport$1 (type $void))) + ;; CHECK: (import "mod" "t0" (tag $imported (param i32 i64))) ;; CHECK: (import "mod" "t1" (tag $timport$0)) + ;; CHECK: (import "mod" "imported-tag" (tag $timport$1)) + ;; CHECK: (global $2 (mut i32) (i32.const 0)) ;; CHECK: (global $i32 i32 (i32.const 42)) @@ -293,7 +306,7 @@ ;; CHECK: (data $active4 (memory $mem-i32) (i32.const 16) "") (data $active4 (memory $mem-i32) (i32.const 16) "") - (data (memory 4) (offset i64.const 0) "64-bit") + (data (memory 5) (offset i64.const 0) "64-bit") ;; tables ;; CHECK: (data $1 (memory $mem-i64) (i64.const 0) "64-bit") @@ -317,10 +330,10 @@ ;; CHECK: (elem $implicit-table-2 (table $timport$0) (i32.const 1) func) (elem $implicit-table-2 (i32.const 1) funcref) - ;; CHECK: (elem $implicit-table-indices (table $timport$0) (i32.const 2) func $fimport$0 $1 $f1) + ;; CHECK: (elem $implicit-table-indices (table $timport$0) (i32.const 2) func $fimport$0 $fimport$1 $2) (elem $implicit-table-indices (offset (i32.const 2)) func 0 1 2) - ;; CHECK: (elem $implicit-table-legacy-indices (table $timport$0) (i32.const 3) func $fimport$0 $1 $f1 $f2) + ;; CHECK: (elem $implicit-table-legacy-indices (table $timport$0) (i32.const 3) func $fimport$0 $fimport$1 $2 $f1) (elem $implicit-table-legacy-indices (i32.const 3) 0 1 2 3) ;; CHECK: (elem $explicit-table (table $timport$0) (i32.const 0) funcref (ref.null nofunc)) @@ -335,14 +348,15 @@ ;; CHECK: (elem $passive-2 anyref (struct.new_default $s0) (struct.new_default $s0)) (elem $passive-2 anyref (item struct.new $s0) (struct.new $s0)) - ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set) + ;; CHECK: (elem declare func $ref-func $ref-is-null $table-fill $table-grow $table-set) (elem declare func 0 1 2 3) (elem $declare-2 declare funcref (item ref.func 0) (ref.func 1) (item (ref.func 2))) ;; tags (tag) - ;; CHECK: (tag $1) + + ;; CHECK: (tag $2) ;; CHECK: (tag $empty) (tag $empty) @@ -355,10 +369,6 @@ ;; explicit exports (export "exported-func" (func 0)) - ;; CHECK: (export "g1" (global $g1)) - - ;; CHECK: (export "g1.1" (global $g1)) - ;; CHECK: (export "mem" (memory $mimport$0)) ;; CHECK: (export "mem2" (memory $mimport$0)) @@ -367,6 +377,10 @@ ;; CHECK: (export "tab2" (table $timport$0)) + ;; CHECK: (export "g1" (global $g1)) + + ;; CHECK: (export "g1.1" (global $g1)) + ;; CHECK: (export "f5.0" (func $fimport$0)) ;; CHECK: (export "f5.1" (func $fimport$0)) @@ -391,7 +405,7 @@ ;; CHECK: (export "exported-tag" (tag $imported)) - ;; CHECK: (func $1 (type $void) + ;; CHECK: (func $2 (type $void) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -2623,7 +2637,7 @@ ;; CHECK-NEXT: (memory.size $mimport$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.size $mem) + ;; CHECK-NEXT: (memory.size $m-imported) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.size $mem-i64) @@ -2645,7 +2659,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (memory.grow $mem + ;; CHECK-NEXT: (memory.grow $m-imported ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2668,7 +2682,7 @@ ) ;; CHECK: (func $globals (type $void) - ;; CHECK-NEXT: (global.set $2 + ;; CHECK-NEXT: (global.set $g-imported ;; CHECK-NEXT: (global.get $i32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2684,7 +2698,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.load8_s $mem + ;; CHECK-NEXT: (i64.load8_s $m-imported ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2711,7 +2725,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i64.atomic.store8 $mem + ;; CHECK-NEXT: (i64.atomic.store8 $m-imported ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i64.const 1) ;; CHECK-NEXT: ) @@ -2777,12 +2791,12 @@ local.get 0 i32.const 1 i32.const 2 - i32.atomic.rmw8.cmpxchg_u 1 align=1 + i32.atomic.rmw8.cmpxchg_u 2 align=1 drop local.get 1 i64.const 3 i64.const 4 - i64.atomic.rmw32.cmpxchg_u 4 offset=16 + i64.atomic.rmw32.cmpxchg_u 5 offset=16 drop ) @@ -2947,7 +2961,7 @@ drop local.get 1 local.get 2 - v128.store64_lane 4 align=4 0 + v128.store64_lane 5 align=4 0 ) ;; CHECK: (func $memory-init (type $17) (param $0 i32) (param $1 i32) (param $2 i32) @@ -2975,7 +2989,7 @@ i64.const 0 local.get 1 local.get 2 - memory.init 4 1 + memory.init 5 1 local.get 0 local.get 1 local.get 2 @@ -3016,11 +3030,11 @@ local.get 0 local.get 1 i32.const 3 - memory.copy 1 $mem-i32 + memory.copy 2 $mem-i32 local.get 2 local.get 3 i64.const 4 - memory.copy $mem-i64 4 + memory.copy $mem-i64 5 ) ;; CHECK: (func $memory-fill (type $4) (param $0 i32) (param $1 i64) @@ -3132,7 +3146,7 @@ ;; CHECK-NEXT: (ref.func $ref-func) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.func $ref-func) + ;; CHECK-NEXT: (ref.func $ref-is-null) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ref-func @@ -3143,7 +3157,7 @@ ) ;; CHECK: (func $throw (type $void) - ;; CHECK-NEXT: (throw $1) + ;; CHECK-NEXT: (throw $timport$1) ;; CHECK-NEXT: (throw $tag-i32 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -3180,7 +3194,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (table.get $funcs + ;; CHECK-NEXT: (table.get $timport$1 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3222,7 +3236,7 @@ table.set i32.const 1 ref.func $table-set - table.set 1 + table.set 2 i32.const 2 ref.null any table.set $table-any @@ -3233,7 +3247,7 @@ ;; CHECK-NEXT: (table.size $timport$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (table.size $funcs) + ;; CHECK-NEXT: (table.size $timport$1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.size $table-any) @@ -3275,7 +3289,7 @@ drop ref.func $table-grow i32.const 1 - table.grow 1 + table.grow 2 drop ref.null any i32.const 2 @@ -3308,7 +3322,7 @@ i32.const 2 ref.func $table-fill i32.const 3 - table.fill 1 + table.fill 2 i32.const 4 ref.null any i32.const 5 @@ -3335,7 +3349,7 @@ i32.const 3 i32.const 4 i32.const 5 - table.copy 1 $funcs + table.copy 2 $funcs ) ;; CHECK: (func $i31-new (type $37) (param $0 i32) (result i31ref) @@ -4276,19 +4290,19 @@ local.get 0 call_indirect local.get 0 - call_indirect 1 + call_indirect 2 local.get 0 call_indirect $funcs local.get 0 call_indirect (type $void) local.get 0 - call_indirect 1 (type $void) (param) (result) + call_indirect 2 (type $void) (param) (result) local.get 0 call_indirect $funcs (type $void) local.get 0 call_indirect (param) (result) local.get 0 - call_indirect 1 (param) (result) + call_indirect 2 (param) (result) local.get 0 call_indirect $funcs (param) (result) local.get 1 @@ -4336,19 +4350,19 @@ local.get 0 return_call_indirect local.get 0 - return_call_indirect 1 + return_call_indirect 2 local.get 0 return_call_indirect $funcs local.get 0 return_call_indirect (type $void) local.get 0 - return_call_indirect 1 (type $void) (param) (result) + return_call_indirect 2 (type $void) (param) (result) local.get 0 return_call_indirect $funcs (type $void) local.get 0 return_call_indirect (param) (result) local.get 0 - return_call_indirect 1 (param) (result) + return_call_indirect 2 (param) (result) local.get 0 return_call_indirect $funcs (param) (result) local.get 1 From 4acd47676c0eb91550a448920395ce45bd86ec50 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Jan 2024 13:02:33 -0800 Subject: [PATCH 019/553] wasm-reduce: Improve tryToReduceCurrentToConst() (#6193) Avoid replacing with the exact same thing in the case of RefNull and a default tuple. Also be more careful with handling of numbers. Before we exited immediately if we saw a number, but we can try to replace a number with a 0 or a 1, even if it was a number before. That is, we consider 1 simpler than e.g. 12345678, and 0 simpler than 1. --- src/tools/wasm-reduce.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index fe6e2b22e86..094338beab7 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -31,6 +31,7 @@ #include "ir/iteration.h" #include "ir/literal-utils.h" #include "ir/properties.h" +#include "ir/utils.h" #include "pass.h" #include "support/colors.h" #include "support/command-line.h" @@ -42,6 +43,7 @@ #include "wasm-builder.h" #include "wasm-io.h" #include "wasm-validator.h" + #ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX @@ -71,6 +73,7 @@ std::string GetLastErrorStdStr() { return std::string(); } #endif + using namespace wasm; // A timeout on every execution of the command. @@ -1139,33 +1142,47 @@ struct Reducer return false; } - // try to replace a concrete value with a trivial constant + // Try to replace a concrete value with a trivial constant. bool tryToReduceCurrentToConst() { auto* curr = getCurrent(); - if (curr->is()) { - return false; - } - // try to replace with a trivial value - if (curr->type.isNullable()) { + + // References. + if (curr->type.isNullable() && !curr->is()) { RefNull* n = builder->makeRefNull(curr->type.getHeapType()); return tryToReplaceCurrent(n); } + + // Tuples. if (curr->type.isTuple() && curr->type.isDefaultable()) { Expression* n = builder->makeConstantExpression(Literal::makeZeros(curr->type)); + if (ExpressionAnalyzer::equal(n, curr)) { + return false; + } return tryToReplaceCurrent(n); } + + // Numbers. We try to replace them with a 0 or a 1. if (!curr->type.isNumber()) { return false; } - // It's a number: try to replace it with a 0 or a 1 (trying more values - // could make sense too, but these handle most cases). + auto* existing = curr->dynCast(); + if (existing && existing->value.isZero()) { + // It's already a zero. + return false; + } auto* c = builder->makeConst(Literal::makeZero(curr->type)); if (tryToReplaceCurrent(c)) { return true; } + // It's not a zero, and can't be replaced with a zero. Try to make it a one, + // if it isn't already. + if (existing && + existing->value == Literal::makeFromInt32(1, existing->type)) { + // It's already a one. + return false; + } c->value = Literal::makeOne(curr->type); - c->type = curr->type; return tryToReplaceCurrent(c); } From 260fdfcdaaeba3f4a47ef057db28c61203c8d3b1 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 2 Jan 2024 17:30:55 -0800 Subject: [PATCH 020/553] [EH] Misc. fixes for EH (#6195) - Deletes a stray whitespace after `throw_ref` - Adds missing `makeThrowRef` to `wasm-builder.h` - Adds a case for `TryTable` in `ControlFlowWalker` --- src/passes/Print.cpp | 2 +- src/wasm-builder.h | 6 ++++++ src/wasm-traversal.h | 14 +++++++++----- test/lit/basic/exception-handling.wast | 24 ++++++++++++------------ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 5ea62c9f21d..5e290ebca9d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2018,7 +2018,7 @@ struct PrintExpressionContents printMedium(o, "rethrow "); printName(curr->target, o); } - void visitThrowRef(ThrowRef* curr) { printMedium(o, "throw_ref "); } + void visitThrowRef(ThrowRef* curr) { printMedium(o, "throw_ref"); } void visitNop(Nop* curr) { printMinor(o, "nop"); } void visitUnreachable(Unreachable* curr) { printMinor(o, "unreachable"); } void visitPop(Pop* curr) { diff --git a/src/wasm-builder.h b/src/wasm-builder.h index dd5b498be8f..a873a73094b 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -836,6 +836,12 @@ class Builder { ret->finalize(); return ret; } + ThrowRef* makeThrowRef(Expression* exnref) { + auto* ret = wasm.allocator.alloc(); + ret->exnref = exnref; + ret->finalize(); + return ret; + } Unreachable* makeUnreachable() { return wasm.allocator.alloc(); } Pop* makePop(Type type) { auto* ret = wasm.allocator.alloc(); diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 1a458bdf7cb..f5f25dd1fe5 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -403,7 +403,8 @@ using ExpressionStack = SmallVector; template> struct ControlFlowWalker : public PostWalker { - ExpressionStack controlFlowStack; // contains blocks, loops, and ifs + // contains blocks, loops, ifs, trys, and try_tables + ExpressionStack controlFlowStack; // Uses the control flow stack to find the target of a break to a name Expression* findBreakTarget(Name name) { @@ -420,8 +421,9 @@ struct ControlFlowWalker : public PostWalker { return curr; } } else { - // an if or try, ignorable - assert(curr->template is() || curr->template is()); + // an if, try, or try_table, ignorable + assert(curr->template is() || curr->template is() || + curr->template is()); } if (i == 0) { return nullptr; @@ -447,7 +449,8 @@ struct ControlFlowWalker : public PostWalker { case Expression::Id::BlockId: case Expression::Id::IfId: case Expression::Id::LoopId: - case Expression::Id::TryId: { + case Expression::Id::TryId: + case Expression::Id::TryTableId: { self->pushTask(SubType::doPostVisitControlFlow, currp); break; } @@ -461,7 +464,8 @@ struct ControlFlowWalker : public PostWalker { case Expression::Id::BlockId: case Expression::Id::IfId: case Expression::Id::LoopId: - case Expression::Id::TryId: { + case Expression::Id::TryId: + case Expression::Id::TryTableId: { self->pushTask(SubType::doPreVisitControlFlow, currp); break; } diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index cf0e8a62e70..b94f89e1aad 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -162,7 +162,7 @@ ) ;; CHECK-TEXT: (func $try-table-and-throw-ref (type $0) - ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (throw_ref ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) ;; CHECK-TEXT-NEXT: (try_table (catch_all_ref $l-catch-all-ref) ;; CHECK-TEXT-NEXT: (throw $e-i64 @@ -173,7 +173,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $try-table-and-throw-ref (type $0) - ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (throw_ref ;; CHECK-BIN-NEXT: (block $label$1 (result exnref) ;; CHECK-BIN-NEXT: (try_table (catch_all_ref $label$1) ;; CHECK-BIN-NEXT: (throw $e-i64 @@ -300,7 +300,7 @@ ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (block $l-catch-ref (result exnref) ;; CHECK-TEXT-NEXT: (block $l-catch-all - ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (throw_ref ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) ;; CHECK-TEXT-NEXT: (try_table (catch $e-empty $l-catch) (catch_ref $e-empty $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) ;; CHECK-TEXT-NEXT: (call $foo) @@ -323,7 +323,7 @@ ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $label$3 (result exnref) ;; CHECK-BIN-NEXT: (block $label$4 - ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (throw_ref ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NEXT: (try_table (catch $e-empty $label$2) (catch_ref $e-empty $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NEXT: (call $foo) @@ -376,7 +376,7 @@ ;; CHECK-TEXT-NEXT: (tuple.drop 2 ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $5) (result i32 exnref) ;; CHECK-TEXT-NEXT: (block $l-catch-all - ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (throw_ref ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch) (catch_ref $e-i32 $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) ;; CHECK-TEXT-NEXT: (call $foo) @@ -403,7 +403,7 @@ ;; CHECK-BIN-NEXT: (local.set $0 ;; CHECK-BIN-NEXT: (block $label$3 (type $5) (result i32 exnref) ;; CHECK-BIN-NEXT: (block $label$4 - ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (throw_ref ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$2) (catch_ref $e-i32 $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NEXT: (call $foo) @@ -474,7 +474,7 @@ ;; CHECK-TEXT-NEXT: (tuple.drop 3 ;; CHECK-TEXT-NEXT: (block $l-catch-ref (type $2) (result i32 i64 exnref) ;; CHECK-TEXT-NEXT: (block $l-catch-all - ;; CHECK-TEXT-NEXT: (throw_ref + ;; CHECK-TEXT-NEXT: (throw_ref ;; CHECK-TEXT-NEXT: (block $l-catch-all-ref (result exnref) ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32-i64 $l-catch) (catch_ref $e-i32-i64 $l-catch-ref) (catch_all $l-catch-all) (catch_all_ref $l-catch-all-ref) ;; CHECK-TEXT-NEXT: (call $foo) @@ -504,7 +504,7 @@ ;; CHECK-BIN-NEXT: (local.set $0 ;; CHECK-BIN-NEXT: (block $label$3 (type $2) (result i32 i64 exnref) ;; CHECK-BIN-NEXT: (block $label$4 - ;; CHECK-BIN-NEXT: (throw_ref + ;; CHECK-BIN-NEXT: (throw_ref ;; CHECK-BIN-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NEXT: (try_table (catch $e-i32-i64 $label$2) (catch_ref $e-i32-i64 $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NEXT: (call $foo) @@ -754,7 +754,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $4 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch_all_ref $label$1) ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$1 @@ -836,7 +836,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref ;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$4 $label$2) (catch_ref $tag$4 $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NODEBUG-NEXT: (call $0) @@ -863,7 +863,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 ;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $5) (result i32 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref ;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$2) (catch_ref $tag$0 $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NODEBUG-NEXT: (call $0) @@ -909,7 +909,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 ;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (type $2) (result i32 i64 exnref) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$4 -;; CHECK-BIN-NODEBUG-NEXT: (throw_ref +;; CHECK-BIN-NODEBUG-NEXT: (throw_ref ;; CHECK-BIN-NODEBUG-NEXT: (block $label$5 (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$2 $label$2) (catch_ref $tag$2 $label$3) (catch_all $label$4) (catch_all_ref $label$5) ;; CHECK-BIN-NODEBUG-NEXT: (call $0) From a6bc9542e98b4164d3a26c67c94b1136b4fc8b86 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 3 Jan 2024 12:55:00 -0800 Subject: [PATCH 021/553] [Parser] Parse folded instructions that contain parentheses (#6196) To parse folded instructions in the right order, we need to defer parsing each instruction until we have parsed each of its children and found its closing parenthesis. Previously we naively looked for parentheses to determine where instructions began and ended before we parsed them, but that scheme did not correctly handle instructions that can contain parentheses in their immediates, such as call_indirect. Fix the problem by using the actual instruction parser functions with a placeholder context to find the end of the instructions, including any kind of immediates they might have. --- src/parser/contexts.h | 8 + src/parser/parsers.h | 81 +++---- test/lit/wat-kitchen-sink.wast | 376 +++++++++++++++++++++++---------- 3 files changed, 310 insertions(+), 155 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 503f4dc3af9..2565a4817dd 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -517,6 +517,14 @@ struct NullInstrParserCtx { Result<> makeStringSliceIter(Index) { return Ok{}; } }; +struct NullCtx : NullTypeParserCtx, NullInstrParserCtx { + ParseInput in; + NullCtx(const ParseInput& in) : in(in) {} + Result<> makeTypeUse(Index, std::optional, ParamsT*, ResultsT*) { + return Ok{}; + } +}; + // Phase 1: Parse definition spans for top-level module elements and determine // their indices and names. struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 6dd61730910..9302f4fc9a9 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -18,6 +18,7 @@ #define parser_parsers_h #include "common.h" +#include "contexts.h" #include "input.h" namespace wasm::WATParser { @@ -706,14 +707,13 @@ template MaybeResult<> instr(Ctx& ctx) { } template MaybeResult<> foldedinstr(Ctx& ctx) { - // Check for valid strings that are not instructions. - if (ctx.in.peekSExprStart("then"sv) || ctx.in.peekSExprStart("else")) { + // We must have an '(' to start a folded instruction. + if (auto tok = ctx.in.peek(); !tok || !tok->isLParen()) { return {}; } - if (auto inst = foldedBlockinstr(ctx)) { - return inst; - } - if (!ctx.in.takeLParen()) { + + // Check for valid strings that look like folded instructions but are not. + if (ctx.in.peekSExprStart("then"sv) || ctx.in.peekSExprStart("else")) { return {}; } @@ -721,47 +721,52 @@ template MaybeResult<> foldedinstr(Ctx& ctx) { // instructions that need to be parsed after their folded children. std::vector>> foldedInstrs; - // Begin a folded instruction. Push its start position and a placeholder - // end position. - foldedInstrs.push_back({ctx.in.getPos(), {}}); - while (!foldedInstrs.empty()) { - // Consume everything up to the next paren. This span will be parsed as - // an instruction later after its folded children have been parsed. - if (!ctx.in.takeUntilParen()) { - return ctx.in.err(foldedInstrs.back().first, - "unterminated folded instruction"); - } + do { + if (ctx.in.takeRParen()) { + // We've reached the end of a folded instruction. Parse it for real. + auto [start, end] = foldedInstrs.back(); + if (!end) { + return ctx.in.err("unexpected end of folded instruction"); + } + foldedInstrs.pop_back(); - if (!foldedInstrs.back().second) { - // The folded instruction we just started should end here. - foldedInstrs.back().second = ctx.in.getPos(); + WithPosition with(ctx, start); + auto inst = plaininstr(ctx); + assert(inst && "unexpectedly failed to parse instruction"); + CHECK_ERR(inst); + assert(ctx.in.getPos() == *end && "expected end of instruction"); + continue; } - // We have either the start of a new folded child or the end of the last - // one. + // We're not ending an instruction, so we must be starting a new one. Maybe + // it is a block instruction. if (auto blockinst = foldedBlockinstr(ctx)) { CHECK_ERR(blockinst); - } else if (ctx.in.takeLParen()) { - foldedInstrs.push_back({ctx.in.getPos(), {}}); - } else if (ctx.in.takeRParen()) { - auto [start, end] = foldedInstrs.back(); - assert(end && "Should have found end of instruction"); - foldedInstrs.pop_back(); + continue; + } - WithPosition with(ctx, start); - if (auto inst = plaininstr(ctx)) { - CHECK_ERR(inst); - } else { - return ctx.in.err(start, "expected folded instruction"); - } + // We must be starting a new plain instruction. + if (!ctx.in.takeLParen()) { + return ctx.in.err("expected folded instruction"); + } + foldedInstrs.push_back({ctx.in.getPos(), {}}); - if (ctx.in.getPos() != *end) { - return ctx.in.err("expected end of instruction"); - } + // Consume the span for the instruction without meaningfully parsing it yet. + // It will be parsed for real using the real context after its s-expression + // children have been found and parsed. + NullCtx nullCtx(ctx.in); + if (auto inst = plaininstr(nullCtx)) { + CHECK_ERR(inst); + ctx.in = nullCtx.in; } else { - WASM_UNREACHABLE("expected paren"); + return ctx.in.err("expected instruction"); } - } + + // The folded instruction we just started ends here. + assert(!foldedInstrs.back().second); + foldedInstrs.back().second = ctx.in.getPos(); + } while (!foldedInstrs.empty()); + return Ok{}; } diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 9cf3c1494d7..303cfc53b0c 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -25,6 +25,8 @@ ;; CHECK: (type $8 (func (param anyref))) + ;; CHECK: (type $9 (func (param i32 i64 v128))) + ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct )) (type $s0 (sub (struct))) @@ -34,15 +36,13 @@ (rec) - ;; CHECK: (type $11 (func)) + ;; CHECK: (type $12 (func)) ;; CHECK: (type $packed-i8 (array (mut i8))) ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) - ;; CHECK: (type $14 (func (param i32))) - - ;; CHECK: (type $15 (func (param i32 i64 v128))) + ;; CHECK: (type $15 (func (param i32))) ;; CHECK: (type $a0 (array i32)) @@ -60,113 +60,113 @@ ;; CHECK: (type $23 (func (param i32 i64) (result f32))) - ;; CHECK: (type $24 (func (param i32 i32))) + ;; CHECK: (type $24 (func (param i64 v128) (result v128))) - ;; CHECK: (type $25 (func (param i32 i32 f64 f64))) + ;; CHECK: (type $25 (func (param i64 v128))) - ;; CHECK: (type $26 (func (param i64))) + ;; CHECK: (type $26 (func (param i32 i32))) - ;; CHECK: (type $27 (func (param v128) (result i32))) + ;; CHECK: (type $27 (func (param i32 i32 f64 f64))) - ;; CHECK: (type $28 (func (param v128 v128) (result v128))) + ;; CHECK: (type $28 (func (param i64))) - ;; CHECK: (type $29 (func (param v128 v128 v128) (result v128))) + ;; CHECK: (type $29 (func (param v128) (result i32))) - ;; CHECK: (type $30 (func (param i32 i32 i64 i64))) + ;; CHECK: (type $30 (func (param v128 v128) (result v128))) - ;; CHECK: (type $31 (func (param i32) (result i32))) + ;; CHECK: (type $31 (func (param v128 v128 v128) (result v128))) - ;; CHECK: (type $32 (func (param i32 i64) (result i32 i64))) + ;; CHECK: (type $32 (func (param i32 i32 i64 i64))) - ;; CHECK: (type $33 (func (param i64) (result i32 i64))) + ;; CHECK: (type $33 (func (param i32) (result i32))) - ;; CHECK: (type $34 (func (param i32) (result i32 i64))) + ;; CHECK: (type $34 (func (param i32 i64) (result i32 i64))) - ;; CHECK: (type $35 (func (param anyref) (result i32))) + ;; CHECK: (type $35 (func (param i64) (result i32 i64))) - ;; CHECK: (type $36 (func (param eqref eqref) (result i32))) + ;; CHECK: (type $36 (func (param i32) (result i32 i64))) - ;; CHECK: (type $37 (func (param i32) (result i31ref))) + ;; CHECK: (type $37 (func (param anyref) (result i32))) - ;; CHECK: (type $38 (func (param i31ref))) + ;; CHECK: (type $38 (func (param eqref eqref) (result i32))) - ;; CHECK: (type $39 (func (param i32 i64) (result (ref $pair)))) + ;; CHECK: (type $39 (func (param i32) (result i31ref))) - ;; CHECK: (type $40 (func (result (ref $pair)))) + ;; CHECK: (type $40 (func (param i31ref))) - ;; CHECK: (type $41 (func (param (ref $pair)) (result i32))) + ;; CHECK: (type $41 (func (param i32 i64) (result (ref $pair)))) - ;; CHECK: (type $42 (func (param (ref $pair)) (result i64))) + ;; CHECK: (type $42 (func (result (ref $pair)))) - ;; CHECK: (type $43 (func (param (ref $pair) i32))) + ;; CHECK: (type $43 (func (param (ref $pair)) (result i32))) - ;; CHECK: (type $44 (func (param (ref $pair) i64))) + ;; CHECK: (type $44 (func (param (ref $pair)) (result i64))) - ;; CHECK: (type $45 (func (param i64 i32) (result (ref $a1)))) + ;; CHECK: (type $45 (func (param (ref $pair) i32))) - ;; CHECK: (type $46 (func (param i32) (result (ref $a1)))) + ;; CHECK: (type $46 (func (param (ref $pair) i64))) - ;; CHECK: (type $47 (func (param i32 i32) (result (ref $a1)))) + ;; CHECK: (type $47 (func (param i64 i32) (result (ref $a1)))) - ;; CHECK: (type $48 (func (param (ref $a1) i32) (result i64))) + ;; CHECK: (type $48 (func (param i32) (result (ref $a1)))) - ;; CHECK: (type $49 (func (param (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $49 (func (param i32 i32) (result (ref $a1)))) - ;; CHECK: (type $50 (func (param (ref $packed-i16) i32) (result i32))) + ;; CHECK: (type $50 (func (param (ref $a1) i32) (result i64))) - ;; CHECK: (type $51 (func (param (ref $a2) i32 f32))) + ;; CHECK: (type $51 (func (param (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $52 (func (param arrayref) (result i32))) + ;; CHECK: (type $52 (func (param (ref $packed-i16) i32) (result i32))) - ;; CHECK: (type $53 (func (param (ref $a2) i32 (ref $a2) i32 i32))) + ;; CHECK: (type $53 (func (param (ref $a2) i32 f32))) - ;; CHECK: (type $54 (func (param (ref $a2) i32 f32 i32))) + ;; CHECK: (type $54 (func (param arrayref) (result i32))) - ;; CHECK: (type $55 (func (param (ref $a2) i32 i32 i32))) + ;; CHECK: (type $55 (func (param (ref $a2) i32 (ref $a2) i32 i32))) - ;; CHECK: (type $56 (func (param (ref $any-array) i32 i32 i32))) + ;; CHECK: (type $56 (func (param (ref $a2) i32 f32 i32))) - ;; CHECK: (type $57 (func (param externref))) + ;; CHECK: (type $57 (func (param (ref $a2) i32 i32 i32))) - ;; CHECK: (type $58 (func (param i32 i32) (result stringref))) + ;; CHECK: (type $58 (func (param (ref $any-array) i32 i32 i32))) - ;; CHECK: (type $59 (func (param (ref $packed-i8) i32 i32) (result stringref))) + ;; CHECK: (type $59 (func (param externref))) - ;; CHECK: (type $60 (func (param i32) (result stringref))) + ;; CHECK: (type $60 (func (param i32 i32) (result stringref))) - ;; CHECK: (type $61 (func (result (ref string)))) + ;; CHECK: (type $61 (func (param (ref $packed-i8) i32 i32) (result stringref))) - ;; CHECK: (type $62 (func (param stringref) (result i32))) + ;; CHECK: (type $62 (func (param i32) (result stringref))) - ;; CHECK: (type $63 (func (param stringview_wtf16) (result i32))) + ;; CHECK: (type $63 (func (result (ref string)))) - ;; CHECK: (type $64 (func (param stringref (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $64 (func (param stringref) (result i32))) - ;; CHECK: (type $65 (func (param stringref stringref) (result (ref string)))) + ;; CHECK: (type $65 (func (param stringview_wtf16) (result i32))) - ;; CHECK: (type $66 (func (param stringref) (result stringview_wtf8))) + ;; CHECK: (type $66 (func (param stringref (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $67 (func (param stringref) (result (ref stringview_wtf16)))) + ;; CHECK: (type $67 (func (param stringref stringref) (result (ref string)))) - ;; CHECK: (type $68 (func (param stringref) (result stringview_iter))) + ;; CHECK: (type $68 (func (param stringref) (result stringview_wtf8))) - ;; CHECK: (type $69 (func (param (ref stringview_wtf8) i32 i32) (result i32))) + ;; CHECK: (type $69 (func (param stringref) (result (ref stringview_wtf16)))) - ;; CHECK: (type $70 (func (param stringview_wtf16 i32) (result i32))) + ;; CHECK: (type $70 (func (param stringref) (result stringview_iter))) - ;; CHECK: (type $71 (func (param stringview_iter) (result i32))) + ;; CHECK: (type $71 (func (param (ref stringview_wtf8) i32 i32) (result i32))) - ;; CHECK: (type $72 (func (param stringview_iter i32) (result i32))) + ;; CHECK: (type $72 (func (param stringview_wtf16 i32) (result i32))) - ;; CHECK: (type $73 (func (param (ref stringview_iter) i32) (result i32))) + ;; CHECK: (type $73 (func (param stringview_iter) (result i32))) - ;; CHECK: (type $74 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) + ;; CHECK: (type $74 (func (param stringview_iter i32) (result i32))) - ;; CHECK: (type $75 (func (param stringview_iter i32) (result (ref string)))) + ;; CHECK: (type $75 (func (param (ref stringview_iter) i32) (result i32))) - ;; CHECK: (type $76 (func (param i64 v128) (result v128))) + ;; CHECK: (type $76 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) - ;; CHECK: (type $77 (func (param i64 v128))) + ;; CHECK: (type $77 (func (param stringview_iter i32) (result (ref string)))) ;; CHECK: (type $s2 (struct (field i32))) (type $s2 (struct i32)) @@ -409,11 +409,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK: (func $f1 (type $14) (param $0 i32) + ;; CHECK: (func $f1 (type $15) (param $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f1 (param i32)) - ;; CHECK: (func $f2 (type $14) (param $x i32) + ;; CHECK: (func $f2 (type $15) (param $x i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f2 (param $x i32)) @@ -856,7 +856,7 @@ drop ) - ;; CHECK: (func $locals (type $24) (param $0 i32) (param $x i32) + ;; CHECK: (func $locals (type $26) (param $0 i32) (param $x i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (drop @@ -2541,7 +2541,7 @@ ) - ;; CHECK: (func $binary (type $25) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) + ;; CHECK: (func $binary (type $27) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $0) @@ -2566,7 +2566,7 @@ drop ) - ;; CHECK: (func $unary (type $26) (param $0 i64) + ;; CHECK: (func $unary (type $28) (param $0 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $0) @@ -2861,7 +2861,7 @@ atomic.fence ) - ;; CHECK: (func $simd-extract (type $27) (param $0 v128) (result i32) + ;; CHECK: (func $simd-extract (type $29) (param $0 v128) (result i32) ;; CHECK-NEXT: (i32x4.extract_lane 3 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2883,7 +2883,7 @@ i32x4.replace_lane 2 ) - ;; CHECK: (func $simd-shuffle (type $28) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK: (func $simd-shuffle (type $30) (param $0 v128) (param $1 v128) (result v128) ;; CHECK-NEXT: (i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2895,7 +2895,7 @@ i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ) - ;; CHECK: (func $simd-ternary (type $29) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK: (func $simd-ternary (type $31) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) ;; CHECK-NEXT: (v128.bitselect ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2942,7 +2942,7 @@ drop ) - ;; CHECK: (func $simd-load-store-lane (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $simd-load-store-lane (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load16_lane $mimport$0 7 ;; CHECK-NEXT: (local.get $0) @@ -3005,7 +3005,7 @@ data.drop $passive ) - ;; CHECK: (func $memory-copy (type $30) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) + ;; CHECK: (func $memory-copy (type $32) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) ;; CHECK-NEXT: (memory.copy $mimport$0 $mimport$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3076,7 +3076,7 @@ return ) - ;; CHECK: (func $return-one (type $31) (param $0 i32) (result i32) + ;; CHECK: (func $return-one (type $33) (param $0 i32) (result i32) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3086,7 +3086,7 @@ return ) - ;; CHECK: (func $return-two (type $32) (param $0 i32) (param $1 i64) (result i32 i64) + ;; CHECK: (func $return-two (type $34) (param $0 i32) (param $1 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (local.get $0) @@ -3100,7 +3100,7 @@ return ) - ;; CHECK: (func $return-two-first-unreachable (type $33) (param $0 i64) (result i32 i64) + ;; CHECK: (func $return-two-first-unreachable (type $35) (param $0 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (unreachable) @@ -3114,7 +3114,7 @@ return ) - ;; CHECK: (func $return-two-second-unreachable (type $34) (param $0 i32) (result i32 i64) + ;; CHECK: (func $return-two-second-unreachable (type $36) (param $0 i32) (result i32 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3131,7 +3131,7 @@ return ) - ;; CHECK: (func $ref-is-null (type $35) (param $0 anyref) (result i32) + ;; CHECK: (func $ref-is-null (type $37) (param $0 anyref) (result i32) ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3175,7 +3175,7 @@ throw $tag-pair ) - ;; CHECK: (func $ref-eq (type $36) (param $0 eqref) (param $1 eqref) (result i32) + ;; CHECK: (func $ref-eq (type $38) (param $0 eqref) (param $1 eqref) (result i32) ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3352,7 +3352,7 @@ table.copy 2 $funcs ) - ;; CHECK: (func $i31-new (type $37) (param $0 i32) (result i31ref) + ;; CHECK: (func $i31-new (type $39) (param $0 i32) (result i31ref) ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3362,7 +3362,7 @@ ref.i31 ) - ;; CHECK: (func $i31-get (type $38) (param $0 i31ref) + ;; CHECK: (func $i31-get (type $40) (param $0 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i31.get_s ;; CHECK-NEXT: (local.get $0) @@ -3581,7 +3581,7 @@ drop ) - ;; CHECK: (func $struct-new (type $39) (param $0 i32) (param $1 i64) (result (ref $pair)) + ;; CHECK: (func $struct-new (type $41) (param $0 i32) (param $1 i64) (result (ref $pair)) ;; CHECK-NEXT: (struct.new $pair ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3593,14 +3593,14 @@ struct.new $pair ) - ;; CHECK: (func $struct-new-default (type $40) (result (ref $pair)) + ;; CHECK: (func $struct-new-default (type $42) (result (ref $pair)) ;; CHECK-NEXT: (struct.new_default $pair) ;; CHECK-NEXT: ) (func $struct-new-default (result (ref $pair)) struct.new_default 14 ) - ;; CHECK: (func $struct-get-0 (type $41) (param $0 (ref $pair)) (result i32) + ;; CHECK: (func $struct-get-0 (type $43) (param $0 (ref $pair)) (result i32) ;; CHECK-NEXT: (struct.get $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3610,7 +3610,7 @@ struct.get 14 0 ) - ;; CHECK: (func $struct-get-1 (type $42) (param $0 (ref $pair)) (result i64) + ;; CHECK: (func $struct-get-1 (type $44) (param $0 (ref $pair)) (result i64) ;; CHECK-NEXT: (struct.get $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3620,7 +3620,7 @@ struct.get $pair 1 ) - ;; CHECK: (func $struct-set-0 (type $43) (param $0 (ref $pair)) (param $1 i32) + ;; CHECK: (func $struct-set-0 (type $45) (param $0 (ref $pair)) (param $1 i32) ;; CHECK-NEXT: (struct.set $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3632,7 +3632,7 @@ struct.set $pair 0 ) - ;; CHECK: (func $struct-set-1 (type $44) (param $0 (ref $pair)) (param $1 i64) + ;; CHECK: (func $struct-set-1 (type $46) (param $0 (ref $pair)) (param $1 i64) ;; CHECK-NEXT: (struct.set $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3644,7 +3644,7 @@ struct.set 14 1 ) - ;; CHECK: (func $array-new (type $45) (param $0 i64) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new (type $47) (param $0 i64) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3656,7 +3656,7 @@ array.new $a1 ) - ;; CHECK: (func $array-new-default (type $46) (param $0 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-default (type $48) (param $0 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_default $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3666,7 +3666,7 @@ array.new_default 11 ) - ;; CHECK: (func $array-new-data (type $47) (param $0 i32) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-data (type $49) (param $0 i32) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_data $a1 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3700,7 +3700,7 @@ drop ) - ;; CHECK: (func $array-get (type $48) (param $0 (ref $a1)) (param $1 i32) (result i64) + ;; CHECK: (func $array-get (type $50) (param $0 (ref $a1)) (param $1 i32) (result i64) ;; CHECK-NEXT: (array.get $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3712,7 +3712,7 @@ array.get $a1 ) - ;; CHECK: (func $array-get-s (type $49) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-s (type $51) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_s $packed-i8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3724,7 +3724,7 @@ array.get_s 15 ) - ;; CHECK: (func $array-get-u (type $50) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-u (type $52) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_u $packed-i16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3736,7 +3736,7 @@ array.get_u $packed-i16 ) - ;; CHECK: (func $array-set (type $51) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) + ;; CHECK: (func $array-set (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) ;; CHECK-NEXT: (array.set $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3750,7 +3750,7 @@ array.set $a2 ) - ;; CHECK: (func $array-len (type $52) (param $0 arrayref) (result i32) + ;; CHECK: (func $array-len (type $54) (param $0 arrayref) (result i32) ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3760,7 +3760,7 @@ array.len ) - ;; CHECK: (func $array-copy (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) + ;; CHECK: (func $array-copy (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) ;; CHECK-NEXT: (array.copy $a2 $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3778,7 +3778,7 @@ array.copy $a2 $a2 ) - ;; CHECK: (func $array-fill (type $54) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) + ;; CHECK: (func $array-fill (type $56) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) ;; CHECK-NEXT: (array.fill $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3794,7 +3794,7 @@ array.fill $a2 ) - ;; CHECK: (func $array-init-data (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-data (type $57) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_data $a2 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3810,7 +3810,7 @@ array.init_data $a2 0 ) - ;; CHECK: (func $array-init-elem (type $56) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-elem (type $58) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_elem $any-array $passive-2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3839,7 +3839,7 @@ drop ) - ;; CHECK: (func $any-convert-extern (type $57) (param $0 externref) + ;; CHECK: (func $any-convert-extern (type $59) (param $0 externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.internalize ;; CHECK-NEXT: (local.get $0) @@ -3865,7 +3865,7 @@ drop ) - ;; CHECK: (func $string-new (type $58) (param $0 i32) (param $1 i32) (result stringref) + ;; CHECK: (func $string-new (type $60) (param $0 i32) (param $1 i32) (result stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_utf8_try ;; CHECK-NEXT: (local.get $0) @@ -3907,7 +3907,7 @@ string.new_wtf16 ) - ;; CHECK: (func $string-new-gc (type $59) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) + ;; CHECK: (func $string-new-gc (type $61) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) ;; CHECK-NEXT: (string.new_utf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3921,7 +3921,7 @@ string.new_utf8_array ) - ;; CHECK: (func $string-new-code-point (type $60) (param $0 i32) (result stringref) + ;; CHECK: (func $string-new-code-point (type $62) (param $0 i32) (result stringref) ;; CHECK-NEXT: (string.from_code_point ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3931,7 +3931,7 @@ string.from_code_point ) - ;; CHECK: (func $string-const (type $61) (result (ref string)) + ;; CHECK: (func $string-const (type $63) (result (ref string)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.const "foobar") ;; CHECK-NEXT: ) @@ -3980,7 +3980,7 @@ drop ) - ;; CHECK: (func $string-hash (type $62) (param $0 stringref) (result i32) + ;; CHECK: (func $string-hash (type $64) (param $0 stringref) (result i32) ;; CHECK-NEXT: (string.hash ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3990,7 +3990,7 @@ string.hash ) - ;; CHECK: (func $stringview-length (type $63) (param $0 stringview_wtf16) (result i32) + ;; CHECK: (func $stringview-length (type $65) (param $0 stringview_wtf16) (result i32) ;; CHECK-NEXT: (stringview_wtf16.length ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4045,7 +4045,7 @@ drop ) - ;; CHECK: (func $string-encode-gc (type $64) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) + ;; CHECK: (func $string-encode-gc (type $66) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) ;; CHECK-NEXT: (string.encode_wtf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4059,7 +4059,7 @@ string.encode_wtf8_array ) - ;; CHECK: (func $string-concat (type $65) (param $0 stringref) (param $1 stringref) (result (ref string)) + ;; CHECK: (func $string-concat (type $67) (param $0 stringref) (param $1 stringref) (result (ref string)) ;; CHECK-NEXT: (string.concat ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4095,7 +4095,7 @@ string.compare ) - ;; CHECK: (func $string-as-wtf8 (type $66) (param $0 stringref) (result stringview_wtf8) + ;; CHECK: (func $string-as-wtf8 (type $68) (param $0 stringref) (result stringview_wtf8) ;; CHECK-NEXT: (string.as_wtf8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4105,7 +4105,7 @@ string.as_wtf8 ) - ;; CHECK: (func $string-as-wtf16 (type $67) (param $0 stringref) (result (ref stringview_wtf16)) + ;; CHECK: (func $string-as-wtf16 (type $69) (param $0 stringref) (result (ref stringview_wtf16)) ;; CHECK-NEXT: (string.as_wtf16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4115,7 +4115,7 @@ string.as_wtf16 ) - ;; CHECK: (func $string-as-iter (type $68) (param $0 stringref) (result stringview_iter) + ;; CHECK: (func $string-as-iter (type $70) (param $0 stringref) (result stringview_iter) ;; CHECK-NEXT: (string.as_iter ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4125,7 +4125,7 @@ string.as_iter ) - ;; CHECK: (func $string-advance (type $69) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK: (func $string-advance (type $71) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf8.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4139,7 +4139,7 @@ stringview_wtf8.advance ) - ;; CHECK: (func $string-get (type $70) (param $0 stringview_wtf16) (param $1 i32) (result i32) + ;; CHECK: (func $string-get (type $72) (param $0 stringview_wtf16) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf16.get_codeunit ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4151,7 +4151,7 @@ stringview_wtf16.get_codeunit ) - ;; CHECK: (func $string-iter-next (type $71) (param $0 stringview_iter) (result i32) + ;; CHECK: (func $string-iter-next (type $73) (param $0 stringview_iter) (result i32) ;; CHECK-NEXT: (stringview_iter.next ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4161,7 +4161,7 @@ stringview_iter.next ) - ;; CHECK: (func $string-iter-advance (type $72) (param $0 stringview_iter) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-advance (type $74) (param $0 stringview_iter) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4173,7 +4173,7 @@ stringview_iter.advance ) - ;; CHECK: (func $string-iter-rewind (type $73) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-rewind (type $75) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.rewind ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4185,7 +4185,7 @@ stringview_iter.rewind ) - ;; CHECK: (func $string-slice (type $74) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) + ;; CHECK: (func $string-slice (type $76) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (stringview_wtf8.slice ;; CHECK-NEXT: (local.get $0) @@ -4214,7 +4214,7 @@ drop ) - ;; CHECK: (func $string-iter-slice (type $75) (param $0 stringview_iter) (param $1 i32) (result (ref string)) + ;; CHECK: (func $string-iter-slice (type $77) (param $0 stringview_iter) (param $1 i32) (result (ref string)) ;; CHECK-NEXT: (stringview_iter.slice ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4250,7 +4250,7 @@ return_call $return_call ) - ;; CHECK: (func $call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4279,7 +4279,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $76) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4312,7 +4312,80 @@ drop ) - ;; CHECK: (func $return-call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect-folded (type $9) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $call-indirect-folded (param i32 i64 v128) + (call_indirect + (local.get 0) + ) + (call_indirect 2 + (local.get 0) + ) + (call_indirect $funcs + (local.get 0) + ) + (call_indirect (type $void) + (local.get 0) + ) + (call_indirect 2 (type $void) (param) (result) + (local.get 0) + ) + (call_indirect $funcs (type $void) + (local.get 0) + ) + (call_indirect (param) (result) + (local.get 0) + ) + (call_indirect 2 (param) (result) + (local.get 0) + ) + (call_indirect $funcs (param) (result) + (local.get 0) + ) + (drop + (call_indirect (param i64 v128) (result v128) + (local.get 1) + (local.get 2) + (local.get 0) + ) + ) + ) + + ;; CHECK: (func $return-call-indirect (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4340,7 +4413,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $77) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4371,6 +4444,75 @@ return_call_indirect (param i64 v128) ) + ;; CHECK: (func $return-call-indirect-folded (type $9) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-call-indirect-folded (param i32 i64 v128) + (return_call_indirect + (local.get 0) + ) + (return_call_indirect 2 + (local.get 0) + ) + (return_call_indirect $funcs + (local.get 0) + ) + (return_call_indirect (type $void) + (local.get 0) + ) + (return_call_indirect 2 (type $void) (param) (result) + (local.get 0) + ) + (return_call_indirect $funcs (type $void) + (local.get 0) + ) + (return_call_indirect (param) (result) + (local.get 0) + ) + (return_call_indirect 2 (param) (result) + (local.get 0) + ) + (return_call_indirect $funcs (param) (result) + (local.get 0) + ) + (return_call_indirect (param i64 v128) + (local.get 1) + (local.get 2) + (local.get 0) + ) + ) + ;; CHECK: (func $use-types (type $88) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) From c923521a61205dd2358201e311b009886e095381 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 3 Jan 2024 13:36:27 -0800 Subject: [PATCH 022/553] Drop support for type annotations on array.len (#6197) These type annotations were removed during the development of the GC proposal, but we maintained support for parsing them to ease the transition. Now that GC is shipped, remove support for the non-standard annotation and update our tests accordingly. --- src/wasm/wasm-s-parser.cpp | 9 +-------- test/lit/arrays.wast | 7 +++---- test/lit/passes/gufa-refs.wast | 2 +- test/lit/passes/gufa-tnh.wast | 2 +- test/lit/passes/optimize-instructions-gc.wast | 2 +- test/passes/Oz_fuzz-exec_all-features.wast | 4 ++-- test/spec/array.wast | 2 +- 7 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 42785e40eba..9f5f412be82 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3160,14 +3160,7 @@ Expression* SExpressionWasmBuilder::makeArraySet(Element& s) { } Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) { - // There may or may not be a type annotation. - Index i = 1; - try { - parseHeapType(*s[i]); - ++i; - } catch (...) { - } - auto ref = parseExpression(*s[i]); + auto ref = parseExpression(*s[1]); return Builder(wasm).makeArrayLen(ref); } diff --git a/test/lit/arrays.wast b/test/lit/arrays.wast index 47338fdf126..4dde528cf21 100644 --- a/test/lit/arrays.wast +++ b/test/lit/arrays.wast @@ -60,8 +60,7 @@ ;; ROUNDTRIP-NEXT: ) ;; ROUNDTRIP-NEXT: ) (func $len (param $a (ref array)) (result i32) - ;; TODO: remove the unused type annotation - (array.len $byte-array + (array.len (local.get $a) ) ) @@ -77,7 +76,7 @@ ;; ROUNDTRIP-NEXT: ) ;; ROUNDTRIP-NEXT: ) (func $impossible-len (param $none nullref) (result i32) - (array.len $byte-array + (array.len (local.get $none) ) ) @@ -91,7 +90,7 @@ ;; ROUNDTRIP-NEXT: (unreachable) ;; ROUNDTRIP-NEXT: ) (func $unreachable-len (param $a arrayref) (result i32) - (array.len $byte-array + (array.len (unreachable) ) ) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index a99df47e06a..6aa741eb1b7 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -4153,7 +4153,7 @@ ;; CHECK-NEXT: ) (func $arrays (param $B (ref $B)) (drop - (array.len $B + (array.len (array.new_fixed $B 2 (ref.null none) (ref.null none) diff --git a/test/lit/passes/gufa-tnh.wast b/test/lit/passes/gufa-tnh.wast index 3a9c77a3098..b3d5b122b67 100644 --- a/test/lit/passes/gufa-tnh.wast +++ b/test/lit/passes/gufa-tnh.wast @@ -1803,7 +1803,7 @@ (i32.const 3) ) (drop - (array.len $B + (array.len (local.get $array.len) ) ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index cbf44aee4d9..cb732d68b31 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -366,7 +366,7 @@ ) ) (drop - (array.len $array + (array.len (ref.as_non_null (local.get $y) ) diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 83cee56e866..1d2b106b7ee 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -52,7 +52,7 @@ ) ;; The length should be 50 (call $log - (array.len $bytes (local.get $x)) + (array.len (local.get $x)) ) ;; The value should be 42 (call $log @@ -281,7 +281,7 @@ ) ;; The length should be 2 (call $log - (array.len $bytes (local.get $x)) + (array.len (local.get $x)) ) ;; The first value should be 42 (call $log diff --git a/test/spec/array.wast b/test/spec/array.wast index 6e7b8cddb19..d9b75e28710 100644 --- a/test/spec/array.wast +++ b/test/spec/array.wast @@ -83,7 +83,7 @@ ) (func $len (param $v (ref $vec)) (result i32) - (array.len $vec (local.get $v)) + (array.len (local.get $v)) ) (func (export "len") (result i32) (call $len (array.new_default $vec (i32.const 3))) From 328bd7a7d6cce32e893c5839b95574f8a3d8bd9a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 3 Jan 2024 14:04:26 -0800 Subject: [PATCH 023/553] [Parser] Parse br_on_cast{_fail} input annotations (#6198) And validate in IRBuilder both that the input annotation is valid and that the input matches it. --- src/parser/contexts.h | 12 ++++++++---- src/parser/parsers.h | 8 +++++--- src/wasm-ir-builder.h | 2 +- src/wasm/wasm-ir-builder.cpp | 12 ++++++++++-- test/lit/wat-kitchen-sink.wast | 4 ++-- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 2565a4817dd..1cefb288da3 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -443,7 +443,8 @@ struct NullInstrParserCtx { Result<> makeBrOn(Index, LabelIdxT, BrOnOp) { return Ok{}; } - template Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT) { + template + Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT, TypeT) { return Ok{}; } @@ -1690,9 +1691,12 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeRefCast(type)); } - Result<> - makeBrOn(Index pos, Index label, BrOnOp op, Type castType = Type::none) { - return withLoc(pos, irBuilder.makeBrOn(label, op, castType)); + Result<> makeBrOn(Index pos, + Index label, + BrOnOp op, + Type in = Type::none, + Type out = Type::none) { + return withLoc(pos, irBuilder.makeBrOn(label, op, in, out)); } Result<> makeStructNew(Index pos, HeapType type) { diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 9302f4fc9a9..1d786f363d1 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1594,9 +1594,11 @@ template Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { template Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { auto label = labelidx(ctx); CHECK_ERR(label); - auto type = reftype(ctx); - CHECK_ERR(type); - return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *type); + auto in = reftype(ctx); + CHECK_ERR(in); + auto out = reftype(ctx); + CHECK_ERR(out); + return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *in, *out); } template diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index dcb25efa785..5add042a63b 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -168,7 +168,7 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeRefTest(Type type); [[nodiscard]] Result<> makeRefCast(Type type); [[nodiscard]] Result<> - makeBrOn(Index label, BrOnOp op, Type castType = Type::none); + makeBrOn(Index label, BrOnOp op, Type in = Type::none, Type out = Type::none); [[nodiscard]] Result<> makeStructNew(HeapType type); [[nodiscard]] Result<> makeStructNewDefault(HeapType type); [[nodiscard]] Result<> diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 3cfe0ea30c2..43a989c6e0f 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1420,12 +1420,20 @@ Result<> IRBuilder::makeRefCast(Type type) { return Ok{}; } -Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type castType) { +Result<> IRBuilder::makeBrOn(Index label, BrOnOp op, Type in, Type out) { BrOn curr; CHECK_ERR(visitBrOn(&curr)); + if (out != Type::none) { + if (!Type::isSubType(out, in)) { + return Err{"output type is not a subtype of the input type"}; + } + if (!Type::isSubType(curr.ref->type, in)) { + return Err{"expected input to match input type annotation"}; + } + } auto name = getLabelName(label); CHECK_ERR(name); - push(builder.makeBrOn(op, *name, curr.ref, castType)); + push(builder.makeBrOn(op, *name, curr.ref, out)); return Ok{}; } diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 303cfc53b0c..775a0a139db 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -3549,7 +3549,7 @@ block (result i31ref) block (result (ref any)) local.get 0 - br_on_cast 1 i31ref + br_on_cast 1 anyref i31ref end unreachable end @@ -3574,7 +3574,7 @@ block (result (ref any)) block (result i31ref) local.get 0 - br_on_cast_fail 1 i31ref + br_on_cast_fail 1 anyref i31ref end unreachable end From 1878403ec9c4382ab51ca72257f4d97a23a1fc0d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 3 Jan 2024 14:32:28 -0800 Subject: [PATCH 024/553] [Parser] Go back to "sub final" intead of "sub open" (#6199) The planned spec change to use "sub open" never came together, so the standard format remains "sub final". --- src/parser/parsers.h | 2 +- test/lit/wat-kitchen-sink.wast | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 1d786f363d1..60100703600 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -2094,7 +2094,7 @@ template MaybeResult<> subtype(Ctx& ctx) { } if (ctx.in.takeSExprStart("sub"sv)) { - if (ctx.in.takeKeyword("open"sv)) { + if (!ctx.in.takeKeyword("final"sv)) { ctx.setOpen(); } if (auto super = maybeTypeidx(ctx)) { diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 775a0a139db..479a8412d45 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -29,7 +29,7 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct )) - (type $s0 (sub (struct))) + (type $s0 (struct)) ;; CHECK: (type $s1 (struct )) (type $s1 (struct (field))) ) @@ -198,17 +198,17 @@ (type $any-array (array (mut anyref))) (rec - (type $void (sub open (func))) + (type $void (sub (func))) ) ;; CHECK: (type $subvoid (sub final $void (func))) - (type $subvoid (sub $void (func))) + (type $subvoid (sub final $void (func))) - (type $many (sub open (func (param $x i32) (param i64 f32) (param) (param $y f64) + (type $many (sub (func (param $x i32) (param i64 f32) (param) (param $y f64) (result anyref (ref func))))) ;; CHECK: (type $submany (sub final $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) - (type $submany (sub $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) + (type $submany (sub final $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) ;; imported memories (memory (export "mem") (export "mem2") (import "" "mem") 0) From 0ed42cf976ce9a3dfbe9cbb0885122e8fb6a377b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 3 Jan 2024 14:59:38 -0800 Subject: [PATCH 025/553] Use the standard shared memory text format (#6200) Update the legacy text parser and all tests to use the standard text format for shared memories, e.g. `(memory $m 1 1 shared)` rather than `(memory $m (shared 1 1))`. Also remove support for non-standard in-line "data" or "segment" declarations. This change makes the tests more compatible with the new text parser, which only supports the standard format. --- src/passes/Print.cpp | 6 +- src/wasm/wasm-s-parser.cpp | 66 +-------- test/binaryen.js/atomics.js | 2 +- test/binaryen.js/atomics.js.txt | 2 +- test/binaryen.js/kitchen-sink.js.txt | 4 +- test/example/c-api-kitchen-sink.txt | 2 +- test/example/module-splitting.cpp | 6 +- test/example/module-splitting.txt | 18 +-- test/lit/basic/atomics.wast | 8 +- test/lit/basic/atomics64.wast | 8 +- test/lit/basic/memory-shared.wast | 8 +- test/lit/basic/multi-memories-atomics64.wast | 24 +-- test/lit/basic/nonspec-bulk-memory.wast | 137 ------------------ test/lit/basic/unreachable-instr-type.wast | 8 +- test/lit/ctor-eval/array_new_data.wast | 4 +- test/lit/ctor-eval/v128.wast | 4 +- .../passes/code-folding_enable-threads.wast | 5 +- .../passes/flatten_dfo_O3_enable-threads.wast | 5 +- ...g_souperify-single-use_enable-threads.wast | 4 +- ...ls-nonesting_souperify_enable-threads.wast | 4 +- .../inlining-optimizing_enable-threads.wast | 4 +- .../passes/memory-packing_all-features.wast | 8 +- .../passes/merge-similar-functions_types.wast | 4 +- .../passes/optimize-instructions-atomics.wast | 4 +- ...e-unused-module-elements_all-features.wast | 22 +-- test/lit/validation/shared-memory.wast | 4 +- ...ment-in-secondary-memory-custom-names.wast | 2 +- .../instrument-in-secondary-memory.wast | 2 +- test/lit/wasm-split/profile-guided.wast | 2 +- test/lit/wat-kitchen-sink.wast | 6 +- test/lld/em_asm_pthread.wasm.out | 2 +- test/passes/fuzz-exec_all-features.txt | 8 +- test/passes/fuzz-exec_all-features.wast | 8 +- test/passes/pick-load-signs_all-features.txt | 2 +- test/passes/pick-load-signs_all-features.wast | 2 +- test/passes/precompute_all-features.txt | 2 +- test/passes/precompute_all-features.wast | 4 +- test/passes/remove-memory.txt | 2 +- test/passes/remove-memory.wast | 7 +- ...unused-names_merge-blocks_all-features.txt | 2 +- ...nused-names_merge-blocks_all-features.wast | 2 +- ...nfunction-module-elements_all-features.txt | 10 +- ...function-module-elements_all-features.wast | 10 +- .../safe-heap_enable-threads_enable-simd.txt | 4 +- .../safe-heap_enable-threads_enable-simd.wast | 4 +- ...safe-heap_enable-threads_enable-simd64.txt | 4 +- ...afe-heap_enable-threads_enable-simd64.wast | 4 +- ...mory-unused_enable-threads_enable-simd.txt | 4 +- ...ory-unused_enable-threads_enable-simd.wast | 4 +- test/passes/simplify-locals_all-features.txt | 4 +- test/passes/simplify-locals_all-features.wast | 4 +- ...ll-features_disable-exception-handling.txt | 2 +- ...l-features_disable-exception-handling.wast | 2 +- test/passes/ssa_fuzz-exec_enable-threads.txt | 2 +- test/passes/ssa_fuzz-exec_enable-threads.wast | 3 +- test/print/memory-import-shared.minified.txt | 2 +- test/print/memory-import-shared.txt | 2 +- test/print/memory-import-shared.wast | 2 +- test/print/memory-shared.minified.txt | 2 +- test/print/memory-shared.txt | 2 +- test/print/memory-shared.wast | 2 +- test/spec/atomics.wast | 2 +- test/wasm2js/atomic_fence.wast | 2 +- test/wasm2js/atomics_32.wast | 2 +- 64 files changed, 152 insertions(+), 351 deletions(-) delete mode 100644 test/lit/basic/nonspec-bulk-memory.wast diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 5e290ebca9d..dcd43c323e2 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -3148,10 +3148,6 @@ void PrintSExpression::printMemoryHeader(Memory* curr) { o << '('; printMedium(o, "memory") << ' '; printName(curr->name, o) << ' '; - if (curr->shared) { - o << '('; - printMedium(o, "shared "); - } if (curr->is64()) { o << "i64 "; } @@ -3160,7 +3156,7 @@ void PrintSExpression::printMemoryHeader(Memory* curr) { o << ' ' << curr->max; } if (curr->shared) { - o << ")"; + printMedium(o, " shared"); } o << ")"; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 9f5f412be82..41a5b188495 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3480,7 +3480,7 @@ Index SExpressionWasmBuilder::parseMemoryLimits( void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { auto memory = std::make_unique(); - memory->shared = false; + memory->shared = *s[s.size() - 1] == SHARED; Index i = 1; if (s[i]->dollared()) { memory->setExplicitName(s[i++]->str()); @@ -3507,10 +3507,6 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { memory->module = inner[1]->str(); memory->base = inner[2]->str(); i++; - } else if (elementStartsWith(inner, SHARED)) { - memory->shared = true; - parseMemoryLimits(inner, 1, memory); - i++; } else { if (!(inner.size() > 0 ? inner[0]->str() != IMPORT : true)) { throw SParseException("bad import ending", inner); @@ -3533,52 +3529,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { return; } } - if (!memory->shared) { - i = parseMemoryLimits(s, i, memory); - } - - // Parse memory initializers. - while (i < s.size()) { - Element& curr = *s[i]; - size_t j = 1; - Address offsetValue; - if (elementStartsWith(curr, DATA)) { - offsetValue = 0; - } else { - auto offsetElem = curr[j++]; - offsetValue = getAddress(offsetElem); - if (!memory->is64()) { - checkAddress(offsetValue, "excessive memory offset", offsetElem); - } - } - std::string_view input = curr[j]->str().str; - auto* offset = allocator.alloc(); - if (memory->is64()) { - offset->type = Type::i64; - offset->value = Literal(offsetValue); - } else { - offset->type = Type::i32; - offset->value = Literal(int32_t(offsetValue)); - } - if (input.size()) { - std::vector data; - stringToBinary(*curr[j], input, data); - auto segment = Builder::makeDataSegment(Name::fromInt(dataCounter++), - memory->name, - false, - offset, - data.data(), - data.size()); - segment->hasExplicitName = false; - dataSegmentNames.push_back(segment->name); - wasm.addDataSegment(std::move(segment)); - } else { - auto segment = Builder::makeDataSegment( - Name::fromInt(dataCounter++), memory->name, false, offset); - segment->hasExplicitName = false; - wasm.addDataSegment(std::move(segment)); - } - i++; + i = parseMemoryLimits(s, i, memory); + if (i + int(memory->shared) != s.size()) { + throw SParseException("expected end of memory", *s[i]); } wasm.addMemory(std::move(memory)); } @@ -3774,15 +3727,10 @@ void SExpressionWasmBuilder::parseImport(Element& s) { memory->base = base; memoryNames.push_back(name); - if (inner[j]->isList()) { - auto& limits = *inner[j]; - if (!elementStartsWith(limits, SHARED)) { - throw SParseException("bad memory limit declaration", inner, *inner[j]); - } + j = parseMemoryLimits(inner, j, memory); + if (j != inner.size() && *inner[j] == SHARED) { memory->shared = true; - j = parseMemoryLimits(limits, 1, memory); - } else { - j = parseMemoryLimits(inner, j, memory); + j++; } wasm.addMemory(std::move(memory)); diff --git a/test/binaryen.js/atomics.js b/test/binaryen.js/atomics.js index ce68656e02d..471e4c52923 100644 --- a/test/binaryen.js/atomics.js +++ b/test/binaryen.js/atomics.js @@ -1,6 +1,6 @@ var wast = ` (module - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) ) `; diff --git a/test/binaryen.js/atomics.js.txt b/test/binaryen.js/atomics.js.txt index 40d2be26aae..aec17b82af1 100644 --- a/test/binaryen.js/atomics.js.txt +++ b/test/binaryen.js/atomics.js.txt @@ -1,6 +1,6 @@ (module (type $0 (func)) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (func $main (i32.atomic.store (i32.const 0) diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 8c6138413a9..bbef03377e6 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -139,7 +139,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (import "module" "base" (func $an-imported (type $2) (param i32 f64) (result f32))) (import "module" "base" (tag $a-tag-imp (param i32))) (global $a-global i32 (i32.const 1)) - (memory $0 (shared 1 256)) + (memory $0 1 256 shared) (data $0 (i32.const 10) "hello, world") (data $1 "I am passive") (table $t0 1 funcref) @@ -2243,7 +2243,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (import "module" "base" (func $an-imported (type $2) (param i32 f64) (result f32))) (import "module" "base" (tag $a-tag-imp (param i32))) (global $a-global i32 (i32.const 1)) - (memory $0 (shared 1 256)) + (memory $0 1 256 shared) (data $0 (i32.const 10) "hello, world") (data $1 "I am passive") (table $t0 1 funcref) diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 8955921b85b..06ec3a1b7d1 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -88,7 +88,7 @@ BinaryenFeatureAll: 131071 )) (global $i32Struct-global (mut (ref null $1)) (struct.new_default $1)) (global $string-global (mut stringref) (string.const "")) - (memory $0 (shared 1 256)) + (memory $0 1 256 shared) (data $0 (i32.const 10) "hello, world") (data $1 "I am passive") (table $tab 0 100 funcref) diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp index 95d6de44cad..cb3df4e78e3 100644 --- a/test/example/module-splitting.cpp +++ b/test/example/module-splitting.cpp @@ -73,7 +73,7 @@ int main() { // Global stuff do_test({}, R"( (module - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (global $glob (mut i32) (i32.const 7)) (tag $e (param i32)) @@ -82,7 +82,7 @@ int main() { // Imported global stuff do_test({}, R"( (module - (import "env" "mem" (memory $mem (shared 3 42))) + (import "env" "mem" (memory $mem 3 42 shared)) (import "env" "tab" (table $tab 3 42 funcref)) (import "env" "glob" (global $glob (mut i32))) (import "env" "e" (tag $e (param i32))) @@ -91,7 +91,7 @@ int main() { // Exported global stuff do_test({}, R"( (module - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (global $glob (mut i32) (i32.const 7)) (tag $e (param i32)) diff --git a/test/example/module-splitting.txt b/test/example/module-splitting.txt index 69146cbf95d..b083e8967b6 100644 --- a/test/example/module-splitting.txt +++ b/test/example/module-splitting.txt @@ -14,7 +14,7 @@ Before: (module (type $0 (func (param i32))) (global $glob (mut i32) (i32.const 7)) - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (param i32)) ) @@ -23,7 +23,7 @@ After: (module (type $0 (func (param i32))) (global $glob (mut i32) (i32.const 7)) - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (param i32)) (export "%memory" (memory $mem)) @@ -34,7 +34,7 @@ After: Secondary: (module (type $0 (func (param i32))) - (import "primary" "%memory" (memory $mem (shared 3 42))) + (import "primary" "%memory" (memory $mem 3 42 shared)) (import "primary" "%table" (table $tab 3 42 funcref)) (import "primary" "%global" (global $glob (mut i32))) (import "primary" "%tag" (tag $e (param i32))) @@ -44,7 +44,7 @@ Secondary: Before: (module (type $0 (func (param i32))) - (import "env" "mem" (memory $mem (shared 3 42))) + (import "env" "mem" (memory $mem 3 42 shared)) (import "env" "tab" (table $tab 3 42 funcref)) (import "env" "glob" (global $glob (mut i32))) (import "env" "e" (tag $e (param i32))) @@ -53,7 +53,7 @@ Keeping: After: (module (type $0 (func (param i32))) - (import "env" "mem" (memory $mem (shared 3 42))) + (import "env" "mem" (memory $mem 3 42 shared)) (import "env" "tab" (table $tab 3 42 funcref)) (import "env" "glob" (global $glob (mut i32))) (import "env" "e" (tag $e (param i32))) @@ -65,7 +65,7 @@ After: Secondary: (module (type $0 (func (param i32))) - (import "primary" "%memory" (memory $mem (shared 3 42))) + (import "primary" "%memory" (memory $mem 3 42 shared)) (import "primary" "%table" (table $tab 3 42 funcref)) (import "primary" "%global" (global $glob (mut i32))) (import "primary" "%tag" (tag $e (param i32))) @@ -76,7 +76,7 @@ Before: (module (type $0 (func (param i32))) (global $glob (mut i32) (i32.const 7)) - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (param i32)) (export "mem" (memory $mem)) @@ -89,7 +89,7 @@ After: (module (type $0 (func (param i32))) (global $glob (mut i32) (i32.const 7)) - (memory $mem (shared 3 42)) + (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (param i32)) (export "mem" (memory $mem)) @@ -100,7 +100,7 @@ After: Secondary: (module (type $0 (func (param i32))) - (import "primary" "mem" (memory $mem (shared 3 42))) + (import "primary" "mem" (memory $mem 3 42 shared)) (import "primary" "tab" (table $tab 3 42 funcref)) (import "primary" "glob" (global $glob (mut i32))) (import "primary" "e" (tag $e (param i32))) diff --git a/test/lit/basic/atomics.wast b/test/lit/basic/atomics.wast index ef98afe4e9a..e73d6b6111d 100644 --- a/test/lit/basic/atomics.wast +++ b/test/lit/basic/atomics.wast @@ -14,10 +14,10 @@ ;; CHECK-BIN: (type $0 (func)) ;; CHECK-BIN-NODEBUG: (type $0 (func)) (type $0 (func)) - ;; CHECK-TEXT: (memory $0 (shared 23 256)) - ;; CHECK-BIN: (memory $0 (shared 23 256)) - ;; CHECK-BIN-NODEBUG: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK-TEXT: (memory $0 23 256 shared) + ;; CHECK-BIN: (memory $0 23 256 shared) + ;; CHECK-BIN-NODEBUG: (memory $0 23 256 shared) + (memory $0 23 256 shared) ;; CHECK-TEXT: (func $atomic-loadstore (type $0) ;; CHECK-TEXT-NEXT: (local $0 i32) diff --git a/test/lit/basic/atomics64.wast b/test/lit/basic/atomics64.wast index b30b1ce6e36..255ecc033c3 100644 --- a/test/lit/basic/atomics64.wast +++ b/test/lit/basic/atomics64.wast @@ -14,10 +14,10 @@ ;; CHECK-BIN: (type $0 (func)) ;; CHECK-BIN-NODEBUG: (type $0 (func)) (type $0 (func)) - ;; CHECK-TEXT: (memory $0 (shared i64 23 256)) - ;; CHECK-BIN: (memory $0 (shared i64 23 256)) - ;; CHECK-BIN-NODEBUG: (memory $0 (shared i64 23 256)) - (memory $0 (shared i64 23 256)) + ;; CHECK-TEXT: (memory $0 i64 23 256 shared) + ;; CHECK-BIN: (memory $0 i64 23 256 shared) + ;; CHECK-BIN-NODEBUG: (memory $0 i64 23 256 shared) + (memory $0 i64 23 256 shared) ;; CHECK-TEXT: (func $atomic-loadstore (type $0) ;; CHECK-TEXT-NEXT: (local $0 i64) diff --git a/test/lit/basic/memory-shared.wast b/test/lit/basic/memory-shared.wast index bc2f8baccf7..fe15c20e714 100644 --- a/test/lit/basic/memory-shared.wast +++ b/test/lit/basic/memory-shared.wast @@ -10,8 +10,8 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module - ;; CHECK-TEXT: (memory $0 (shared 23 256)) - ;; CHECK-BIN: (memory $0 (shared 23 256)) - ;; CHECK-BIN-NODEBUG: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK-TEXT: (memory $0 23 256 shared) + ;; CHECK-BIN: (memory $0 23 256 shared) + ;; CHECK-BIN-NODEBUG: (memory $0 23 256 shared) + (memory $0 23 256 shared) ) diff --git a/test/lit/basic/multi-memories-atomics64.wast b/test/lit/basic/multi-memories-atomics64.wast index 79afddb3b9b..0795d10ad74 100644 --- a/test/lit/basic/multi-memories-atomics64.wast +++ b/test/lit/basic/multi-memories-atomics64.wast @@ -14,15 +14,15 @@ ;; CHECK-BIN: (type $0 (func)) ;; CHECK-BIN-NODEBUG: (type $0 (func)) (type $0 (func)) - ;; CHECK-TEXT: (memory $appMemory (shared i64 23 256)) - ;; CHECK-BIN: (memory $appMemory (shared i64 23 256)) - (memory $appMemory (shared i64 23 256)) - ;; CHECK-TEXT: (memory $dataMemory (shared i64 23 256)) - ;; CHECK-BIN: (memory $dataMemory (shared i64 23 256)) - (memory $dataMemory (shared i64 23 256)) - ;; CHECK-TEXT: (memory $instrumentMemory (shared i64 23 256)) - ;; CHECK-BIN: (memory $instrumentMemory (shared i64 23 256)) - (memory $instrumentMemory (shared i64 23 256)) + ;; CHECK-TEXT: (memory $appMemory i64 23 256 shared) + ;; CHECK-BIN: (memory $appMemory i64 23 256 shared) + (memory $appMemory i64 23 256 shared) + ;; CHECK-TEXT: (memory $dataMemory i64 23 256 shared) + ;; CHECK-BIN: (memory $dataMemory i64 23 256 shared) + (memory $dataMemory i64 23 256 shared) + ;; CHECK-TEXT: (memory $instrumentMemory i64 23 256 shared) + ;; CHECK-BIN: (memory $instrumentMemory i64 23 256 shared) + (memory $instrumentMemory i64 23 256 shared) ;; CHECK-TEXT: (func $atomic-loadstore (type $0) ;; CHECK-TEXT-NEXT: (local $0 i64) @@ -1064,11 +1064,11 @@ (atomic.fence) ) ) -;; CHECK-BIN-NODEBUG: (memory $0 (shared i64 23 256)) +;; CHECK-BIN-NODEBUG: (memory $0 i64 23 256 shared) -;; CHECK-BIN-NODEBUG: (memory $1 (shared i64 23 256)) +;; CHECK-BIN-NODEBUG: (memory $1 i64 23 256 shared) -;; CHECK-BIN-NODEBUG: (memory $2 (shared i64 23 256)) +;; CHECK-BIN-NODEBUG: (memory $2 i64 23 256 shared) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (local $0 i64) diff --git a/test/lit/basic/nonspec-bulk-memory.wast b/test/lit/basic/nonspec-bulk-memory.wast deleted file mode 100644 index 980598f5d91..00000000000 --- a/test/lit/basic/nonspec-bulk-memory.wast +++ /dev/null @@ -1,137 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. - -;; RUN: wasm-opt %s -all -o %t.text.wast -g -S -;; RUN: wasm-as %s -all -g -o %t.wasm -;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast -;; RUN: wasm-as %s -all -o %t.nodebug.wasm -;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast -;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT -;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN -;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG - -(module - (memory 1024 1024 - (segment 0 "hello, world") - ) - - ;; CHECK-TEXT: (type $0 (func)) - - ;; CHECK-TEXT: (memory $0 1024 1024) - - ;; CHECK-TEXT: (data $0 (i32.const 0) "hello, world") - - ;; CHECK-TEXT: (func $memory.init (type $0) - ;; CHECK-TEXT-NEXT: (memory.init $0 - ;; CHECK-TEXT-NEXT: (i32.const 512) - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i32.const 12) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (type $0 (func)) - - ;; CHECK-BIN: (memory $0 1024 1024) - - ;; CHECK-BIN: (data $0 (i32.const 0) "hello, world") - - ;; CHECK-BIN: (func $memory.init (type $0) - ;; CHECK-BIN-NEXT: (memory.init $0 - ;; CHECK-BIN-NEXT: (i32.const 512) - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i32.const 12) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $memory.init - (memory.init 0 - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - - ;; CHECK-TEXT: (func $data.drop (type $0) - ;; CHECK-TEXT-NEXT: (data.drop $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $data.drop (type $0) - ;; CHECK-BIN-NEXT: (data.drop $0) - ;; CHECK-BIN-NEXT: ) - (func $data.drop - (data.drop 0) - ) - - ;; CHECK-TEXT: (func $memory.copy (type $0) - ;; CHECK-TEXT-NEXT: (memory.copy - ;; CHECK-TEXT-NEXT: (i32.const 512) - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i32.const 12) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $memory.copy (type $0) - ;; CHECK-BIN-NEXT: (memory.copy - ;; CHECK-BIN-NEXT: (i32.const 512) - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i32.const 12) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $memory.copy - (memory.copy - (i32.const 512) - (i32.const 0) - (i32.const 12) - ) - ) - - ;; CHECK-TEXT: (func $memory.fill (type $0) - ;; CHECK-TEXT-NEXT: (memory.fill - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i32.const 42) - ;; CHECK-TEXT-NEXT: (i32.const 1024) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $memory.fill (type $0) - ;; CHECK-BIN-NEXT: (memory.fill - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i32.const 42) - ;; CHECK-BIN-NEXT: (i32.const 1024) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - (func $memory.fill - (memory.fill - (i32.const 0) - (i32.const 42) - (i32.const 1024) - ) - ) -) -;; CHECK-BIN-NODEBUG: (type $0 (func)) - -;; CHECK-BIN-NODEBUG: (memory $0 1024 1024) - -;; CHECK-BIN-NODEBUG: (data $0 (i32.const 0) "hello, world") - -;; CHECK-BIN-NODEBUG: (func $0 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (memory.init $0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 512) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $1 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (data.drop $0) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $2 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (memory.copy -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 512) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 12) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $3 (type $0) -;; CHECK-BIN-NODEBUG-NEXT: (memory.fill -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 42) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1024) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/unreachable-instr-type.wast b/test/lit/basic/unreachable-instr-type.wast index ff6df8bac03..494678a3272 100644 --- a/test/lit/basic/unreachable-instr-type.wast +++ b/test/lit/basic/unreachable-instr-type.wast @@ -10,11 +10,11 @@ ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG (module - (memory (shared 1 1)) + (memory 1 1 shared) ;; CHECK-TEXT: (type $0 (func)) - ;; CHECK-TEXT: (memory $0 (shared 1 1)) + ;; CHECK-TEXT: (memory $0 1 1 shared) ;; CHECK-TEXT: (func $test (type $0) ;; CHECK-TEXT-NEXT: (i32.load @@ -41,7 +41,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $0 (func)) - ;; CHECK-BIN: (memory $0 (shared 1 1)) + ;; CHECK-BIN: (memory $0 1 1 shared) ;; CHECK-BIN: (func $test (type $0) ;; CHECK-BIN-NEXT: (unreachable) @@ -74,7 +74,7 @@ ) ;; CHECK-BIN-NODEBUG: (type $0 (func)) -;; CHECK-BIN-NODEBUG: (memory $0 (shared 1 1)) +;; CHECK-BIN-NODEBUG: (memory $0 1 1 shared) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) diff --git a/test/lit/ctor-eval/array_new_data.wast b/test/lit/ctor-eval/array_new_data.wast index a185c171f0c..90551862dd6 100644 --- a/test/lit/ctor-eval/array_new_data.wast +++ b/test/lit/ctor-eval/array_new_data.wast @@ -7,8 +7,8 @@ ;; CHECK: (type $[i8] (array i8)) (type $[i8] (array i8)) - ;; CHECK: (memory $0 (shared 16 17)) - (memory $0 (shared 16 17)) + ;; CHECK: (memory $0 16 17 shared) + (memory $0 16 17 shared) ;; CHECK: (data $0 (i32.const 40) "") (data $0 (i32.const 40) "") ;; CHECK: (data $1 (i32.const 0) "") diff --git a/test/lit/ctor-eval/v128.wast b/test/lit/ctor-eval/v128.wast index 009ef57f25c..71a380623ef 100644 --- a/test/lit/ctor-eval/v128.wast +++ b/test/lit/ctor-eval/v128.wast @@ -6,8 +6,8 @@ ;; CHECK: (type $1 (func (result v128))) - ;; CHECK: (memory $0 (shared 16 17)) - (memory $0 (shared 16 17)) + ;; CHECK: (memory $0 16 17 shared) + (memory $0 16 17 shared) (export "v128" (func $v128)) ;; CHECK: (data $0 (i32.const 23) "\e0\ff\c0N\8e\00\00\fe\01\00\12\81\85\fd\ff\90") diff --git a/test/lit/passes/code-folding_enable-threads.wast b/test/lit/passes/code-folding_enable-threads.wast index 15b83f71bd7..487fbd3acda 100644 --- a/test/lit/passes/code-folding_enable-threads.wast +++ b/test/lit/passes/code-folding_enable-threads.wast @@ -262,8 +262,8 @@ (module ;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) ;; CHECK: (export "func_2224" (func $0)) (export "func_2224" (func $0)) ;; CHECK: (func $0 (result i32) @@ -420,4 +420,3 @@ ) ) ) - diff --git a/test/lit/passes/flatten_dfo_O3_enable-threads.wast b/test/lit/passes/flatten_dfo_O3_enable-threads.wast index 55bf54dc911..ccb029060be 100644 --- a/test/lit/passes/flatten_dfo_O3_enable-threads.wast +++ b/test/lit/passes/flatten_dfo_O3_enable-threads.wast @@ -14,8 +14,8 @@ ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) ;; CHECK: (export "one" (func $one)) ;; CHECK: (export "two" (func $two)) @@ -264,4 +264,3 @@ ) ) ) - diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast index 0bcc36de280..ea693d50230 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast @@ -30,8 +30,8 @@ ;; CHECK: (type $12 (func (param i32 i32 i32 i32 i32) (result i32))) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) ;; Figure 1a from the Souper paper https://arxiv.org/pdf/1711.04422.pdf ;; CHECK: (export "replaced-print-internal" (func $replaced-print-internal)) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast index 61430d653c0..e8d423058ac 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast @@ -30,8 +30,8 @@ ;; CHECK: (type $12 (func (param i32 i32 i32 i32 i32) (result i32))) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) ;; Figure 1a from the Souper paper https://arxiv.org/pdf/1711.04422.pdf ;; CHECK: (export "replaced-print-internal" (func $replaced-print-internal)) diff --git a/test/lit/passes/inlining-optimizing_enable-threads.wast b/test/lit/passes/inlining-optimizing_enable-threads.wast index 60385b11a24..631fc1fa58f 100644 --- a/test/lit/passes/inlining-optimizing_enable-threads.wast +++ b/test/lit/passes/inlining-optimizing_enable-threads.wast @@ -153,8 +153,8 @@ (module ;; CHECK: (type $0 (func (result i64))) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) (func $0 (result i32) (i32.atomic.store16 (i32.const 0) diff --git a/test/lit/passes/memory-packing_all-features.wast b/test/lit/passes/memory-packing_all-features.wast index dfcf5ce53f7..1f0886d66a8 100644 --- a/test/lit/passes/memory-packing_all-features.wast +++ b/test/lit/passes/memory-packing_all-features.wast @@ -2279,8 +2279,8 @@ ;; the wrong segments in the presence of unreferenced segments. ;; CHECK: (type $0 (func)) - ;; CHECK: (memory $0 (shared 1 1)) - (memory $0 (shared 1 1)) + ;; CHECK: (memory $0 1 1 shared) + (memory $0 1 1 shared) (data (i32.const 0) "") (data "foo") ;; CHECK: (data $1 "foo") @@ -2394,8 +2394,8 @@ (type $array (array (mut i32))) ;; CHECK: (type $1 (func (param (ref $array) i32 i32 i32))) - ;; CHECK: (memory $0 (shared 16 17)) - (memory $0 (shared 16 17)) + ;; CHECK: (memory $0 16 17 shared) + (memory $0 16 17 shared) ;; CHECK: (data $0 "") (data $0 "") ;; CHECK: (func $0 (type $1) (param $0 (ref $array)) (param $1 i32) (param $2 i32) (param $3 i32) diff --git a/test/lit/passes/merge-similar-functions_types.wast b/test/lit/passes/merge-similar-functions_types.wast index 717777ab7df..980f10cd9c1 100644 --- a/test/lit/passes/merge-similar-functions_types.wast +++ b/test/lit/passes/merge-similar-functions_types.wast @@ -120,8 +120,8 @@ ;; CHECK: (global $global$0 (mut i32) (i32.const 10)) (global $global$0 (mut i32) (i32.const 10)) - ;; CHECK: (memory $0 (shared 16 17)) - (memory $0 (shared 16 17)) + ;; CHECK: (memory $0 16 17 shared) + (memory $0 16 17 shared) ;; CHECK: (elem declare func $2 $3) diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast index 29037186dcb..e59c6a4e79b 100644 --- a/test/lit/passes/optimize-instructions-atomics.wast +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -2,8 +2,8 @@ ;; RUN: wasm-opt %s --optimize-instructions --enable-threads -S -o - | filecheck %s (module - ;; CHECK: (import "env" "memory" (memory $0 (shared 256 256))) - (import "env" "memory" (memory $0 (shared 256 256))) + ;; CHECK: (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "memory" (memory $0 256 256 shared)) ;; CHECK: (func $x ;; CHECK-NEXT: (drop diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index 15a843064b7..f287df88f0a 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -260,8 +260,8 @@ (module ;; more use checks ;; CHECK: (type $0 (func)) - ;; CHECK: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK: (memory $0 23 256 shared) + (memory $0 23 256 shared) (export "user" $user) ;; CHECK: (export "user" (func $user)) @@ -278,8 +278,8 @@ (module ;; more use checks ;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK: (memory $0 23 256 shared) + (memory $0 23 256 shared) (export "user" $user) ;; CHECK: (export "user" (func $user)) @@ -296,8 +296,8 @@ (module ;; more use checks ;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK: (memory $0 23 256 shared) + (memory $0 23 256 shared) (export "user" $user) ;; CHECK: (export "user" (func $user)) @@ -315,8 +315,8 @@ (module ;; more use checks ;; CHECK: (type $0 (func)) - ;; CHECK: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK: (memory $0 23 256 shared) + (memory $0 23 256 shared) (export "user" $user) ;; CHECK: (export "user" (func $user)) @@ -346,8 +346,8 @@ (module ;; more use checks ;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (memory $0 (shared 23 256)) - (memory $0 (shared 23 256)) + ;; CHECK: (memory $0 23 256 shared) + (memory $0 23 256 shared) (export "user" $user) ;; CHECK: (export "user" (func $user)) @@ -362,7 +362,7 @@ ) ) (module ;; atomic.fence and data.drop do not use a memory, so should not keep the memory alive. - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (data "") (export "fake-user" $user) ;; CHECK: (type $0 (func)) diff --git a/test/lit/validation/shared-memory.wast b/test/lit/validation/shared-memory.wast index 03128756c99..34619594961 100644 --- a/test/lit/validation/shared-memory.wast +++ b/test/lit/validation/shared-memory.wast @@ -4,8 +4,8 @@ ;; RUN: wasm-opt %s --enable-threads -o - -S | filecheck %s --check-prefix ATOMICS ;; NO-ATOMICS: shared memory requires threads [--enable-threads] -;; ATOMICS: (memory $0 (shared 10 20)) +;; ATOMICS: (memory $0 10 20 shared) (module - (memory (shared 10 20)) + (memory 10 20 shared) ) diff --git a/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast b/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast index 9035a0b8b17..a211e5d8a5d 100644 --- a/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast +++ b/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast @@ -17,7 +17,7 @@ ) ;; Check that a memory import has been added for secondary memory -;; CHECK: (import "custom_env" "custom_name" (memory $custom_name (shared 1 1))) +;; CHECK: (import "custom_env" "custom_name" (memory $custom_name 1 1 shared)) ;; And the profiling function exported ;; CHECK: (export "__write_profile" (func $__write_profile)) diff --git a/test/lit/wasm-split/instrument-in-secondary-memory.wast b/test/lit/wasm-split/instrument-in-secondary-memory.wast index d68e4c1d667..26ac0ad18d9 100644 --- a/test/lit/wasm-split/instrument-in-secondary-memory.wast +++ b/test/lit/wasm-split/instrument-in-secondary-memory.wast @@ -17,7 +17,7 @@ ) ;; Check that a memory import has been added for secondary memory -;; CHECK: (import "env" "profile-data" (memory $profile-data (shared 1 1))) +;; CHECK: (import "env" "profile-data" (memory $profile-data 1 1 shared)) ;; And the profiling function exported ;; CHECK: (export "__write_profile" (func $__write_profile)) diff --git a/test/lit/wasm-split/profile-guided.wast b/test/lit/wasm-split/profile-guided.wast index 8270204a2a6..6828c19fcde 100644 --- a/test/lit/wasm-split/profile-guided.wast +++ b/test/lit/wasm-split/profile-guided.wast @@ -69,7 +69,7 @@ ;; NONE: Splitting out functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee, uncalled (module - (memory $mem (shared 1 1)) + (memory $mem 1 1 shared) (export "memory" (memory $mem)) (export "foo" (func $foo)) (export "bar" (func $bar)) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 479a8412d45..05aedd51985 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -216,7 +216,7 @@ ;; CHECK: (import "" "mem" (memory $mimport$0 0)) - ;; CHECK: (import "mod" "imported-m" (memory $m-imported (shared 1 2))) + ;; CHECK: (import "mod" "imported-m" (memory $m-imported 1 2 shared)) (import "mod" "imported-m" (memory $m-imported 1 2 shared)) ;; imported tables @@ -271,10 +271,10 @@ (global $i32 i32 i32.const 42) ;; memories - ;; CHECK: (memory $mem (shared 1 1)) + ;; CHECK: (memory $mem 1 1 shared) (memory $mem 1 1 shared) (memory 0 1 shared) - ;; CHECK: (memory $1 (shared 0 1)) + ;; CHECK: (memory $1 0 1 shared) ;; CHECK: (memory $mem-i32 0 1) (memory $mem-i32 i32 0 1) diff --git a/test/lld/em_asm_pthread.wasm.out b/test/lld/em_asm_pthread.wasm.out index 676178bd33a..40f61e3a71a 100644 --- a/test/lld/em_asm_pthread.wasm.out +++ b/test/lld/em_asm_pthread.wasm.out @@ -38,7 +38,7 @@ (type $36 (func (param i32 f64) (result i32))) (type $37 (func (param i32 i32 i32 i32) (result f64))) (type $38 (func (param i32 i32 i64 i32) (result i64))) - (import "env" "memory" (memory $mimport$0 (shared 256 256))) + (import "env" "memory" (memory $mimport$0 256 256 shared)) (import "env" "emscripten_asm_const_int" (func $fimport$0 (param i32 i32 i32) (result i32))) (import "env" "world" (func $fimport$1)) (import "env" "__cxa_thread_atexit" (func $fimport$2 (param i32 i32 i32) (result i32))) diff --git a/test/passes/fuzz-exec_all-features.txt b/test/passes/fuzz-exec_all-features.txt index 6a0ee8585c4..22ea5f06ad8 100644 --- a/test/passes/fuzz-exec_all-features.txt +++ b/test/passes/fuzz-exec_all-features.txt @@ -75,7 +75,7 @@ (type $2 (func (param i32 i32))) (type $3 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $1) (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (export "unaligned_load" (func $unaligned_load)) (export "unaligned_load_offset" (func $unaligned_load_offset)) (export "aligned_for_size" (func $aligned_for_size)) @@ -148,7 +148,7 @@ [fuzz-exec] note result: unsigned_2_bytes => 65535 (module (type $0 (func (result i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (data $0 (i32.const 0) "\ff\ff") (export "unsigned_2_bytes" (func $unsigned_2_bytes)) (func $unsigned_2_bytes (type $0) (result i32) @@ -167,7 +167,7 @@ (type $0 (func (param i32))) (type $1 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $0) (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (export "rmw-reads-modifies-and-writes" (func $rmw-reads-modifies-and-writes)) (func $rmw-reads-modifies-and-writes (type $1) (drop @@ -192,7 +192,7 @@ (type $0 (func (param i32))) (type $1 (func)) (import "fuzzing-support" "log-i32" (func $fimport$0 (type $0) (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (export "rmw-reads-modifies-and-writes-asymmetrical" (func $rmw-reads-modifies-and-writes-asymmetrical)) (func $rmw-reads-modifies-and-writes-asymmetrical (type $1) (drop diff --git a/test/passes/fuzz-exec_all-features.wast b/test/passes/fuzz-exec_all-features.wast index 2c9d95d16c9..bab6afb79e1 100644 --- a/test/passes/fuzz-exec_all-features.wast +++ b/test/passes/fuzz-exec_all-features.wast @@ -32,7 +32,7 @@ ) (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (func $unaligned_load (export "unaligned_load") (result i32) (i32.atomic.load (i32.const 1) ;; unaligned ptr @@ -78,7 +78,7 @@ ) ) (module - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (data (i32.const 0) "\ff\ff") (func $unsigned_2_bytes (export "unsigned_2_bytes") (result i32) (i32.atomic.rmw16.xor_u ;; should be unsigned @@ -89,7 +89,7 @@ ) (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (func $rmw-reads-modifies-and-writes (export "rmw-reads-modifies-and-writes") (drop (i64.atomic.rmw16.and_u offset=4 @@ -106,7 +106,7 @@ ) (module (import "fuzzing-support" "log-i32" (func $fimport$0 (param i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (func $rmw-reads-modifies-and-writes-asymmetrical (export "rmw-reads-modifies-and-writes-asymmetrical") (drop (i32.atomic.rmw8.sub_u diff --git a/test/passes/pick-load-signs_all-features.txt b/test/passes/pick-load-signs_all-features.txt index 9b73de23e82..4bb3c1c98f5 100644 --- a/test/passes/pick-load-signs_all-features.txt +++ b/test/passes/pick-load-signs_all-features.txt @@ -1,6 +1,6 @@ (module (type $0 (func (result i32))) - (memory $0 (shared 16 16)) + (memory $0 16 16) (func $atomics-are-always-unsigned (type $0) (result i32) (local $0 i32) (drop diff --git a/test/passes/pick-load-signs_all-features.wast b/test/passes/pick-load-signs_all-features.wast index 20a77eae489..4b7e11f10da 100644 --- a/test/passes/pick-load-signs_all-features.wast +++ b/test/passes/pick-load-signs_all-features.wast @@ -1,5 +1,5 @@ (module - (memory $0 (shared 16 16)) + (memory $0 16 16) (func $atomics-are-always-unsigned (result i32) (local $0 i32) (drop diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt index e5cdbb20914..affa325310d 100644 --- a/test/passes/precompute_all-features.txt +++ b/test/passes/precompute_all-features.txt @@ -8,7 +8,7 @@ (type $6 (func (result externref))) (global $global i32 (i32.const 1)) (global $global-mut (mut i32) (i32.const 2)) - (memory $0 512 512) + (memory $0 6 65536) (data $0 (i32.const 0) "hello!") (elem declare func $dummy) (func $x (type $0) (param $x i32) diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast index cef6d4cc834..45000153353 100644 --- a/test/passes/precompute_all-features.wast +++ b/test/passes/precompute_all-features.wast @@ -1,7 +1,5 @@ (module - (memory 512 512 - (data "hello!") - ) + (memory (data "hello!") 512 512) (type $0 (func (param i32))) (global $global i32 (i32.const 1)) (global $global-mut (mut i32) (i32.const 2)) diff --git a/test/passes/remove-memory.txt b/test/passes/remove-memory.txt index ee65d237e23..ddfdde49329 100644 --- a/test/passes/remove-memory.txt +++ b/test/passes/remove-memory.txt @@ -1,3 +1,3 @@ (module - (memory $0 1024 1024) + (memory $mem 1024 1024) ) diff --git a/test/passes/remove-memory.wast b/test/passes/remove-memory.wast index bbb99900794..26b4949a81f 100644 --- a/test/passes/remove-memory.wast +++ b/test/passes/remove-memory.wast @@ -1,6 +1,5 @@ (module - (memory 1024 1024 - (segment 10 "123") - (segment 20 "149") - ) + (memory $mem 1024 1024) + (data (memory $mem) (i32.const 10) "123") + (data (memory $mem) (i32.const 20) "149") ) diff --git a/test/passes/remove-unused-names_merge-blocks_all-features.txt b/test/passes/remove-unused-names_merge-blocks_all-features.txt index e10a8707ca2..ac7647507b7 100644 --- a/test/passes/remove-unused-names_merge-blocks_all-features.txt +++ b/test/passes/remove-unused-names_merge-blocks_all-features.txt @@ -5,7 +5,7 @@ (type $ii (func (param i32 i32))) (type $iii (func (param i32 i32 i32))) (type $5 (func (result f64))) - (memory $0 (shared 256 256)) + (memory $0 256 256 shared) (table $0 1 1 funcref) (elem $0 (i32.const 0) $call-i) (func $call-i (type $i) (param $0 i32) diff --git a/test/passes/remove-unused-names_merge-blocks_all-features.wast b/test/passes/remove-unused-names_merge-blocks_all-features.wast index 3ec2768e0a9..1063e246331 100644 --- a/test/passes/remove-unused-names_merge-blocks_all-features.wast +++ b/test/passes/remove-unused-names_merge-blocks_all-features.wast @@ -1,5 +1,5 @@ (module - (memory (shared 256 256)) + (memory 256 256 shared) (type $i (func (param i32))) (type $ii (func (param i32 i32))) (type $iii (func (param i32 i32 i32))) diff --git a/test/passes/remove-unused-nonfunction-module-elements_all-features.txt b/test/passes/remove-unused-nonfunction-module-elements_all-features.txt index d19fcc5140d..b54087b8176 100644 --- a/test/passes/remove-unused-nonfunction-module-elements_all-features.txt +++ b/test/passes/remove-unused-nonfunction-module-elements_all-features.txt @@ -132,7 +132,7 @@ ) (module (type $0 (func)) - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" (func $user)) (func $user (type $0) (i32.store @@ -143,7 +143,7 @@ ) (module (type $0 (func (result i32))) - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" (func $user)) (func $user (type $0) (result i32) (i32.atomic.rmw.add @@ -154,7 +154,7 @@ ) (module (type $0 (func (result i32))) - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" (func $user)) (func $user (type $0) (result i32) (i32.atomic.rmw8.cmpxchg_u @@ -166,7 +166,7 @@ ) (module (type $0 (func)) - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" (func $user)) (func $user (type $0) (local $0 i32) @@ -182,7 +182,7 @@ ) (module (type $0 (func (result i32))) - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" (func $user)) (func $user (type $0) (result i32) (memory.atomic.notify diff --git a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast index 057088798e0..942a20ee7e1 100644 --- a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast +++ b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast @@ -101,28 +101,28 @@ ) ) (module ;; more use checks - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" $user) (func $user (i32.store (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" $user) (func $user (result i32) (i32.atomic.rmw.add (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" $user) (func $user (result i32) (i32.atomic.rmw8.cmpxchg_u (i32.const 0) (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" $user) (func $user (local $0 i32) @@ -137,7 +137,7 @@ ) ) (module ;; more use checks - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (export "user" $user) (func $user (result i32) (memory.atomic.notify (i32.const 0) (i32.const 0)) diff --git a/test/passes/safe-heap_enable-threads_enable-simd.txt b/test/passes/safe-heap_enable-threads_enable-simd.txt index 3d00dc96db2..c1f8110077c 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd.txt @@ -14,7 +14,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $loads (drop (call $SAFE_HEAP_LOAD_i32_4_4 @@ -5441,7 +5441,7 @@ (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $actions (drop (call $SAFE_HEAP_LOAD_i32_4_4 diff --git a/test/passes/safe-heap_enable-threads_enable-simd.wast b/test/passes/safe-heap_enable-threads_enable-simd.wast index b1cd1f05080..a973230a527 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd.wast +++ b/test/passes/safe-heap_enable-threads_enable-simd.wast @@ -1,5 +1,5 @@ (module - (memory (shared 100 100)) + (memory 100 100 shared) (func $loads (drop (i32.load (i32.const 1))) (drop (i32.atomic.load (i32.const 1))) @@ -47,7 +47,7 @@ (type $FUNCSIG$v (func)) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $actions (drop (i32.load (i32.const 1))) (i32.store (i32.const 1) (i32.const 100)) diff --git a/test/passes/safe-heap_enable-threads_enable-simd64.txt b/test/passes/safe-heap_enable-threads_enable-simd64.txt index 0e282f0ce1e..49319377e44 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd64.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd64.txt @@ -14,7 +14,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i64))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared i64 100 100)) + (memory $0 i64 100 100 shared) (func $loads (drop (call $SAFE_HEAP_LOAD_i32_4_4 @@ -5627,7 +5627,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i64))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared i64 100 100)) + (memory $0 i64 100 100 shared) (func $actions (drop (call $SAFE_HEAP_LOAD_i32_4_4 diff --git a/test/passes/safe-heap_enable-threads_enable-simd64.wast b/test/passes/safe-heap_enable-threads_enable-simd64.wast index d34c5772bd8..dc70a037b1c 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd64.wast +++ b/test/passes/safe-heap_enable-threads_enable-simd64.wast @@ -1,5 +1,5 @@ (module - (memory (shared i64 100 100)) + (memory i64 100 100 shared) (func $loads (drop (i32.load (i64.const 1))) (drop (i32.atomic.load (i64.const 1))) @@ -48,7 +48,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i64))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared i64 100 100)) + (memory $0 i64 100 100 shared) (func $actions (drop (i32.load (i64.const 1))) (i32.store (i64.const 1) (i32.const 100)) diff --git a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt index 26c45953637..53b048331a7 100644 --- a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt @@ -14,7 +14,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $loads (drop (call $SAFE_HEAP_LOAD_i32_4_4 @@ -5441,7 +5441,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $actions (drop (call $SAFE_HEAP_LOAD_i32_4_4 diff --git a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast index bad9fb8d4b8..6b0adf3e3cd 100644 --- a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast +++ b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast @@ -1,5 +1,5 @@ (module - (memory (shared 100 100)) + (memory 100 100 shared) (func $loads (drop (i32.load (i32.const 1))) (drop (i32.atomic.load (i32.const 1))) @@ -48,7 +48,7 @@ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) - (memory $0 (shared 100 100)) + (memory $0 100 100 shared) (func $actions (drop (i32.load (i32.const 1))) (i32.store (i32.const 1) (i32.const 100)) diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt index 5e5478ddf34..4225a70336e 100644 --- a/test/passes/simplify-locals_all-features.txt +++ b/test/passes/simplify-locals_all-features.txt @@ -1136,7 +1136,7 @@ (import "fuzzing-support" "log2" (func $fimport$1 (type $4) (param i32))) (import "fuzzing-support" "log3" (func $fimport$2 (type $5) (param f32))) (global $global$0 (mut i32) (i32.const 10)) - (memory $0 (shared 256 256)) + (memory $0 256 256 shared) (func $nonatomics (type $FUNCSIG$i) (result i32) (local $x i32) (nop) @@ -1884,7 +1884,7 @@ ) (module (type $0 (func (result i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (data $0 "data") (export "foo" (func $foo)) (func $foo (type $0) (result i32) diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast index a2868b45dd9..f46f9fd7129 100644 --- a/test/passes/simplify-locals_all-features.wast +++ b/test/passes/simplify-locals_all-features.wast @@ -1087,7 +1087,7 @@ ) ) (module - (memory (shared 256 256)) + (memory 256 256 shared) (type $FUNCSIG$v (func)) (type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result i32))) @@ -1673,7 +1673,7 @@ ) ;; data.drop has global side effects (module - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (data "data") (func $foo (export "foo") (result i32) (local $0 i32) diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.txt b/test/passes/simplify-locals_all-features_disable-exception-handling.txt index 6e5e3871662..6ee89372d20 100644 --- a/test/passes/simplify-locals_all-features_disable-exception-handling.txt +++ b/test/passes/simplify-locals_all-features_disable-exception-handling.txt @@ -1130,7 +1130,7 @@ (import "fuzzing-support" "log2" (func $fimport$1 (type $4) (param i32))) (import "fuzzing-support" "log3" (func $fimport$2 (type $5) (param f32))) (global $global$0 (mut i32) (i32.const 10)) - (memory $0 (shared 256 256)) + (memory $0 256 256 shared) (func $nonatomics (type $FUNCSIG$i) (result i32) (local $x i32) (nop) diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.wast b/test/passes/simplify-locals_all-features_disable-exception-handling.wast index 25b452511e6..1f308723a65 100644 --- a/test/passes/simplify-locals_all-features_disable-exception-handling.wast +++ b/test/passes/simplify-locals_all-features_disable-exception-handling.wast @@ -1087,7 +1087,7 @@ ) ) (module - (memory (shared 256 256)) + (memory 256 256 shared) (type $FUNCSIG$v (func)) (type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result i32))) diff --git a/test/passes/ssa_fuzz-exec_enable-threads.txt b/test/passes/ssa_fuzz-exec_enable-threads.txt index 6334b35a7b5..f9d49d5bbaa 100644 --- a/test/passes/ssa_fuzz-exec_enable-threads.txt +++ b/test/passes/ssa_fuzz-exec_enable-threads.txt @@ -2,7 +2,7 @@ [fuzz-exec] note result: func_0 => 16384 (module (type $0 (func (result i32))) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (table $0 0 0 funcref) (export "func_0" (func $0)) (func $0 (result i32) diff --git a/test/passes/ssa_fuzz-exec_enable-threads.wast b/test/passes/ssa_fuzz-exec_enable-threads.wast index 1ad1e2a6f8e..5917a3eb360 100644 --- a/test/passes/ssa_fuzz-exec_enable-threads.wast +++ b/test/passes/ssa_fuzz-exec_enable-threads.wast @@ -2,7 +2,7 @@ (type $0 (func (result i32))) (type $1 (func)) (table 0 0 funcref) - (memory $0 (shared 1 1)) + (memory $0 1 1 shared) (export "func_0" (func $0)) (func $0 (; 0 ;) (type $0) (result i32) (local $var$0 i32) @@ -109,4 +109,3 @@ ) ) ) - diff --git a/test/print/memory-import-shared.minified.txt b/test/print/memory-import-shared.minified.txt index 8691f813cae..75cbecb8bd3 100644 --- a/test/print/memory-import-shared.minified.txt +++ b/test/print/memory-import-shared.minified.txt @@ -1 +1 @@ -(module(import "env" "memory" (memory $0 (shared 256 256)))) \ No newline at end of file +(module(import "env" "memory" (memory $0 256 256 shared))) \ No newline at end of file diff --git a/test/print/memory-import-shared.txt b/test/print/memory-import-shared.txt index ba5a0463ca2..30374cff029 100644 --- a/test/print/memory-import-shared.txt +++ b/test/print/memory-import-shared.txt @@ -1,3 +1,3 @@ (module - (import "env" "memory" (memory $0 (shared 256 256))) + (import "env" "memory" (memory $0 256 256 shared)) ) diff --git a/test/print/memory-import-shared.wast b/test/print/memory-import-shared.wast index ba5a0463ca2..30374cff029 100644 --- a/test/print/memory-import-shared.wast +++ b/test/print/memory-import-shared.wast @@ -1,3 +1,3 @@ (module - (import "env" "memory" (memory $0 (shared 256 256))) + (import "env" "memory" (memory $0 256 256 shared)) ) diff --git a/test/print/memory-shared.minified.txt b/test/print/memory-shared.minified.txt index c6aeccdcd99..3f07a008007 100644 --- a/test/print/memory-shared.minified.txt +++ b/test/print/memory-shared.minified.txt @@ -1,2 +1,2 @@ -(module(memory $0 (shared 23 256)) +(module(memory $0 23 256 shared) ) \ No newline at end of file diff --git a/test/print/memory-shared.txt b/test/print/memory-shared.txt index ee02979b117..daff79f22f1 100644 --- a/test/print/memory-shared.txt +++ b/test/print/memory-shared.txt @@ -1,3 +1,3 @@ (module - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) ) diff --git a/test/print/memory-shared.wast b/test/print/memory-shared.wast index ee02979b117..daff79f22f1 100644 --- a/test/print/memory-shared.wast +++ b/test/print/memory-shared.wast @@ -1,3 +1,3 @@ (module - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) ) diff --git a/test/spec/atomics.wast b/test/spec/atomics.wast index 4e6dd35638c..4ff91ddafb0 100644 --- a/test/spec/atomics.wast +++ b/test/spec/atomics.wast @@ -1,5 +1,5 @@ (module - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (func (export "atomic-fence") (atomic.fence) ) diff --git a/test/wasm2js/atomic_fence.wast b/test/wasm2js/atomic_fence.wast index 2e605b690a3..cb1837dc4d8 100644 --- a/test/wasm2js/atomic_fence.wast +++ b/test/wasm2js/atomic_fence.wast @@ -1,5 +1,5 @@ (module - (memory $0 (shared 23 256)) + (memory $0 23 256 shared) (func (export "atomic-fence") (atomic.fence) ) diff --git a/test/wasm2js/atomics_32.wast b/test/wasm2js/atomics_32.wast index eeec9337631..e366b7f4e81 100644 --- a/test/wasm2js/atomics_32.wast +++ b/test/wasm2js/atomics_32.wast @@ -1,5 +1,5 @@ (module - (memory (shared 256 256)) + (memory 256 256 shared) (data "hello,") (data "world!") (func $test (export "test") From a58281ca114359cd6e65f5daaf086636aa18b0b0 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 4 Jan 2024 14:25:18 -0800 Subject: [PATCH 026/553] Require `then` and `else` with `if` (#6201) We previously supported (and primarily used) a non-standard text format for conditionals in which the condition, if-true expression, and if-false expression were all simply s-expression children of the `if` expression. The standard text format, however, requires the use of `then` and `else` forms to introduce the if-true and if-false arms of the conditional. Update the legacy text parser to require the standard format and update all tests to match. Update the printer to print the standard format as well. The .wast and .wat test inputs were mechanically updated with this script: https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1 --- CHANGELOG.md | 2 + src/passes/Print.cpp | 32 +- src/passes/wasm-intrinsics.wat | 302 +- src/wasm/wasm-s-parser.cpp | 15 +- test/binaryen.js/expressions.js | 4 +- test/binaryen.js/expressions.js.txt | 12 +- test/binaryen.js/kitchen-sink.js.txt | 170 +- test/binaryen.js/optimize-levels.js | 4 +- test/binaryen.js/optimize-levels.js.txt | 12 +- test/binaryen.js/sieve.js.txt | 40 +- test/binaryen.js/stackir.js | 4 +- test/binaryen.js/stackir.js.txt | 4 +- test/ctor-eval/partial-return.wast | 4 +- test/ctor-eval/results.wast | 14 +- test/example/c-api-kitchen-sink.txt | 152 +- test/example/relooper-fuzz.txt | 82 +- test/example/relooper-fuzz1.txt | 114 +- test/example/relooper-fuzz2.txt | 4 +- test/example/relooper-merge1.txt | 4 +- test/example/relooper-merge2.txt | 4 +- test/example/relooper-merge3.txt | 4 +- test/example/relooper-merge4.txt | 4 +- test/example/relooper-merge5.txt | 4 +- test/example/relooper-merge6.txt | 4 +- test/example/relooper-merge7.txt | 8 +- test/fib-dbg.wasm.fromBinary | 10 +- test/gtest/cfg.cpp | 24 +- test/gtest/stringify.cpp | 16 +- test/lit/basic/exception-handling-old.wast | 32 +- test/lit/basic/exception-handling.wast | 116 +- test/lit/basic/polymorphic_stack.wast | 80 +- test/lit/basic/reference-types.wast | 200 +- test/lit/basic/reg_switch.wast | 32 +- test/lit/basic/unit.wat | 352 +- test/lit/basic/unreachable-code.wast | 192 +- test/lit/basic/untaken-br_if.wast | 56 +- test/lit/if-then-else.wast | 16 +- test/lit/multivalue.wast | 40 +- test/lit/non-nullable-locals.wast | 24 +- test/lit/passes/O.wast | 64 +- ..._flexible-inline-max-function-size=30.wast | 10 +- test/lit/passes/O3_inlining.wast | 20 +- test/lit/passes/O4_disable-bulk-memory.wast | 420 +- test/lit/passes/Oz.wast | 60 +- test/lit/passes/asyncify-wasm64.wast | 200 +- ...y-wasm64_pass-arg=in-secondary-memory.wast | 32 +- test/lit/passes/asyncify.wast | 200 +- .../passes/asyncify_enable-multivalue.wast | 706 +- ...y_mod-asyncify-always-and-only-unwind.wast | 74 +- ...mod-asyncify-always-and-only-unwind_O.wast | 12 +- .../asyncify_mod-asyncify-never-unwind.wast | 74 +- .../asyncify_mod-asyncify-never-unwind_O.wast | 22 +- .../lit/passes/asyncify_optimize-level=1.wast | 264 +- ...syncify_pass-arg=asyncify-addlist@foo.wast | 26 +- ...foo_pass-arg=asyncify-ignore-indirect.wast | 34 +- ...serts_pass-arg=asyncify-onlylist@waka.wast | 32 +- ...y_pass-arg=asyncify-blacklist@foo,bar.wast | 44 +- ...cify_pass-arg=asyncify-ignore-imports.wast | 54 +- ...ify_pass-arg=asyncify-ignore-indirect.wast | 158 +- ...yncify-imports@env.import,env.import2.wast | 430 +- ...fy_pass-arg=asyncify-onlylist@foo,bar.wast | 44 +- ...syncify_pass-arg=asyncify-side-module.wast | 16 +- .../asyncify_pass-arg=asyncify-verbose.wast | 58 +- ...asyncify_pass-arg=in-secondary-memory.wast | 64 +- test/lit/passes/catch-pop-fixup-eh.wast | 16 +- test/lit/passes/cfp.wast | 16 +- test/lit/passes/coalesce-locals-gc.wast | 76 +- test/lit/passes/coalesce-locals-learning.wast | 1388 +- test/lit/passes/coalesce-locals.wast | 1652 +- .../passes/code-folding_enable-threads.wast | 228 +- test/lit/passes/code-pushing-eh.wast | 20 +- .../code-pushing_ignore-implicit-traps.wast | 22 +- test/lit/passes/code-pushing_into_if.wast | 368 +- test/lit/passes/code-pushing_tnh.wast | 20 +- test/lit/passes/dae-gc-refine-return.wast | 148 +- test/lit/passes/dae-optimizing.wast | 82 +- test/lit/passes/dce-eh.wast | 4 +- test/lit/passes/dce_all-features.wast | 730 +- .../dce_vacuum_remove-unused-names.wast | 22 +- test/lit/passes/denan.wast | 32 +- test/lit/passes/directize_all-features.wast | 112 +- test/lit/passes/flatten_all-features.wast | 778 +- .../passes/flatten_dfo_O3_enable-threads.wast | 184 +- .../passes/flatten_i64-to-i32-lowering.wast | 10 +- test/lit/passes/flatten_rereloop.wast | 794 +- ...tten_simplify-locals-nonesting_dfo_O3.wast | 70 +- ...g_souperify-single-use_enable-threads.wast | 882 +- ...ls-nonesting_souperify_enable-threads.wast | 882 +- test/lit/passes/global-effects.wast | 40 +- test/lit/passes/gufa-refs.wast | 36 +- test/lit/passes/gufa-ssa.wast | 12 +- test/lit/passes/gufa-tnh.wast | 44 +- test/lit/passes/gufa-vs-cfp.wast | 16 +- test/lit/passes/gufa.wast | 100 +- test/lit/passes/heap2local.wast | 94 +- .../inlining-optimizing_optimize-level=3.wast | 30934 ++++++++-------- .../lit/passes/inlining_enable-tail-call.wast | 170 +- test/lit/passes/inlining_splitting.wast | 606 +- .../lit/passes/inlining_splitting_basics.wast | 46 +- test/lit/passes/j2cl-inline.wast | 8 +- test/lit/passes/local-cse.wast | 42 +- test/lit/passes/local-subtyping-nn.wast | 14 +- test/lit/passes/local-subtyping.wast | 42 +- .../passes/memory-packing_all-features.wast | 80 +- .../memory-packing_zero-filled-memory64.wast | 4 +- test/lit/passes/merge-blocks.wast | 20 +- test/lit/passes/multi-memory-lowering.wast | 112 +- test/lit/passes/no-inline.wast | 152 +- test/lit/passes/once-reduction.wast | 444 +- test/lit/passes/optimize-casts.wast | 30 +- .../optimize-instructions-call_ref.wast | 32 +- .../optimize-instructions-exceptions.wast | 8 +- .../passes/optimize-instructions-gc-tnh.wast | 90 +- test/lit/passes/optimize-instructions-gc.wast | 100 +- .../optimize-instructions-ignore-traps.wast | 130 +- .../optimize-instructions-multivalue.wast | 20 +- .../lit/passes/optimize-instructions-mvp.wast | 576 +- test/lit/passes/optimize-stack-ir.wast | 112 +- test/lit/passes/outlining.wast | 124 +- test/lit/passes/poppify.wast | 24 +- test/lit/passes/precompute-gc-immutable.wast | 104 +- test/lit/passes/precompute-gc.wast | 92 +- test/lit/passes/remove-unused-brs-gc.wast | 96 +- test/lit/passes/remove-unused-brs.wast | 180 +- .../remove-unused-brs_all-features.wast | 58 +- test/lit/passes/remove-unused-brs_levels.wast | 56 +- ...e-unused-module-elements_all-features.wast | 32 +- test/lit/passes/rse-gc.wast | 24 +- test/lit/passes/signature-refining.wast | 48 +- .../passes/simplify-globals-dominance.wast | 34 +- .../simplify-globals-read_only_to_write.wast | 332 +- test/lit/passes/simplify-locals-eh.wast | 30 +- test/lit/passes/simplify-locals-gc-nn.wast | 14 +- test/lit/passes/simplify-locals-gc.wast | 24 +- test/lit/passes/simplify-locals-tnh.wast | 18 +- test/lit/passes/stack-check-memory64.wast | 34 +- test/lit/passes/stack-ir-non-nullable.wast | 386 +- test/lit/passes/type-generalizing.wast | 16 +- test/lit/passes/type-merging.wast | 4 - test/lit/passes/type-refining.wast | 40 +- test/lit/passes/type-ssa_and_merging.wast | 44 +- test/lit/passes/unsubtyping.wast | 16 +- test/lit/passes/vacuum-eh.wast | 18 +- test/lit/passes/vacuum-func.wast | 8 +- test/lit/passes/vacuum-gc.wast | 10 +- test/lit/passes/vacuum-intrinsics.wast | 88 +- test/lit/passes/vacuum-tnh.wast | 242 +- test/lit/passes/vacuum_all-features.wast | 352 +- test/lit/source-map.wast | 10 +- .../validation/bad-non-nullable-locals.wast | 10 +- test/lit/wasm-split/instrument-funcs.wast | 4 +- test/lit/wasm-split/instrument-in-memory.wast | 2 +- .../instrument-in-secondary-memory.wast | 2 +- test/lit/wasm-split/instrument-memory64.wast | 2 +- .../lit/wasm-split/jspi-secondary-export.wast | 4 +- test/lit/wasm-split/jspi.wast | 4 +- .../multi-memory-lowering-export.wast | 12 +- .../multi-memory-lowering-import.wast | 12 +- test/lit/wat-kitchen-sink.wast | 212 +- test/lld/basic_safe_stack.wat.out | 12 +- test/lld/em_asm_pthread.wasm.out | 14 +- test/lld/recursive_safe_stack.wat.out | 24 +- test/lld/safe_stack_standalone-wasm.wat.out | 16 +- test/passes/O.bin.txt | 66 +- test/passes/O3_low-memory-unused_metrics.txt | 162 +- test/passes/converge_O3_metrics.bin.txt | 138 +- test/passes/fannkuch3_manyopts_dwarf.bin.txt | 468 +- test/passes/func-metrics.txt | 38 +- test/passes/func-metrics.wast | 38 +- test/passes/interesting-pass-mix.txt | 76 +- test/passes/interesting-pass-mix.wast | 96 +- test/passes/licm.txt | 12 +- test/passes/licm.wast | 8 +- test/passes/log-execution.txt | 14 +- test/passes/log-execution.wast | 8 +- test/passes/merge-blocks.txt | 84 +- test/passes/merge-blocks.wast | 112 +- test/passes/merge-locals_all-features.txt | 242 +- test/passes/merge-locals_all-features.wast | 282 +- test/passes/metrics_all-features.txt | 38 +- test/passes/metrics_all-features.wast | 38 +- ...-constants-propagate_low-memory-unused.txt | 16 +- ...constants-propagate_low-memory-unused.wast | 14 +- ...mize-added-constants_low-memory-unused.txt | 6 +- ...ize-added-constants_low-memory-unused.wast | 4 +- .../precompute-propagate_all-features.txt | 78 +- .../precompute-propagate_all-features.wast | 72 +- test/passes/precompute_all-features.txt | 42 +- test/passes/precompute_all-features.wast | 54 +- test/passes/print-call-graph.txt | 280 +- test/passes/print-call-graph.wast | 878 +- test/passes/print.bin.txt | 64 +- test/passes/print_g.bin.txt | 136 +- test/passes/print_g_metrics.bin.txt | 64 +- test/passes/print_g_strip-dwarf.bin.txt | 64 +- test/passes/remove-non-js-ops.txt | 38 +- .../remove-unused-brs_enable-multivalue.txt | 860 +- .../remove-unused-brs_enable-multivalue.wast | 1040 +- ...s_precompute_vacuum_remove-unused-brs.wast | 12 +- .../remove-unused-brs_shrink-level=1.txt | 28 +- .../remove-unused-brs_shrink-level=1.wast | 36 +- ...s_shrink-level=1_ignore-implicit-traps.txt | 8 +- ..._shrink-level=1_ignore-implicit-traps.wast | 36 +- .../remove-unused-names_code-folding.txt | 602 +- .../remove-unused-names_code-folding.wast | 1424 +- ...unused-names_merge-blocks_all-features.txt | 34 +- ...nused-names_merge-blocks_all-features.wast | 44 +- ...-unused-names_remove-unused-brs_vacuum.txt | 48 +- ...unused-names_remove-unused-brs_vacuum.wast | 78 +- ...ed-names_vacuum_ignore-implicit-traps.wast | 22 +- ...nfunction-module-elements_all-features.txt | 28 +- ...function-module-elements_all-features.wast | 24 +- test/passes/reverse_dwarf_abbrevs.bin.txt | 496 +- test/passes/roundtrip_signed.bin.txt | 4 +- test/passes/rse_all-features.txt | 140 +- test/passes/rse_all-features.wast | 108 +- test/passes/safe-heap_disable-simd.txt | 1044 +- .../safe-heap_enable-threads_enable-simd.txt | 1516 +- ...safe-heap_enable-threads_enable-simd64.txt | 1516 +- ...mory-unused_enable-threads_enable-simd.txt | 1516 +- test/passes/safe-heap_start-function.txt | 348 +- ...mplify-globals-optimizing_all-features.txt | 12 +- ...plify-globals-optimizing_all-features.wast | 8 +- test/passes/simplify-globals_all-features.txt | 12 +- .../passes/simplify-globals_all-features.wast | 4 +- test/passes/simplify-locals-nonesting.txt | 8 +- test/passes/simplify-locals-nonesting.wast | 168 +- test/passes/simplify-locals-nostructure.txt | 44 +- test/passes/simplify-locals-nostructure.wast | 40 +- .../simplify-locals-notee-nostructure.txt | 30 +- .../simplify-locals-notee-nostructure.wast | 22 +- test/passes/simplify-locals-notee.txt | 22 +- test/passes/simplify-locals-notee.wast | 22 +- test/passes/simplify-locals_all-features.txt | 316 +- test/passes/simplify-locals_all-features.wast | 498 +- ...ll-features_disable-exception-handling.txt | 316 +- ...l-features_disable-exception-handling.wast | 498 +- test/passes/souperify.txt | 12 +- test/passes/souperify.wast | 12 +- test/passes/spill-pointers.txt | 8 +- test/passes/spill-pointers.wast | 16 +- test/passes/ssa-nomerge_enable-simd.txt | 80 +- test/passes/ssa-nomerge_enable-simd.wast | 72 +- test/passes/ssa_enable-threads.txt | 164 +- test/passes/ssa_enable-threads.wast | 148 +- test/passes/ssa_fuzz-exec_enable-threads.txt | 148 +- test/passes/ssa_fuzz-exec_enable-threads.wast | 152 +- .../stack-check_enable-mutable-globals.txt | 4 +- test/passes/trap-mode-clamp.txt | 416 +- test/passes/trap-mode-js.txt | 280 +- test/reduce/destructive.wast | 4 +- test/spec/exception-handling-old.wast | 8 +- test/spec/old_br_if.wast | 4 +- test/spec/old_call.wast | 48 +- test/spec/old_call_indirect.wast | 62 +- test/spec/old_float_exprs.wast | 32 +- test/spec/old_unreachable.wast | 6 +- test/spec/stack.wast | 32 +- test/unit/input/asyncify-pure.wat | 24 +- test/unit/input/asyncify-sleep.wat | 54 +- test/unit/test_poppy_validation.py | 12 +- test/wasm2js/br.2asm.js | 18 +- test/wasm2js/br_table.2asm.js | 24 +- test/wasm2js/br_table_temp.wast | 24 +- test/wasm2js/deterministic.wast | 4 +- test/wasm2js/emscripten.wast | 96 +- test/wasm2js/fac.2asm.js | 54 +- test/wasm2js/forward.2asm.js | 16 +- test/wasm2js/if_unreachable.wast | 12 +- test/wasm2js/stack-modified.wast | 130 +- test/wasm2js/unreachable-get-cycle.wast | 36 +- test/wasm2js/unreachable-later.wast | 76 +- 272 files changed, 41627 insertions(+), 28272 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fc9847e1fb..a505a9509d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ Current Trunk ------------- - The `tuple.make` pseudoinstruction now requires an immediate giving its arity. For example, to make a tuple of two elements, use `tuple.make 2`. + - The text format for `if` expressions now requires `then` and `else` to + introduce the two branch arms, matching the spec. v116 ---- diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index dcd43c323e2..b6060a85363 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -306,7 +306,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor { // loop, if, and try can contain implicit blocks. But they are not needed to // be printed in some cases. - void maybePrintImplicitBlock(Expression* curr, bool allowMultipleInsts); + void maybePrintImplicitBlock(Expression* curr); // Generic visitor, overridden only when necessary. void visitExpression(Expression* curr); @@ -2563,11 +2563,9 @@ void PrintSExpression::printFullLine(Expression* expression) { o << maybeNewLine; } -void PrintSExpression::maybePrintImplicitBlock(Expression* curr, - bool allowMultipleInsts) { +void PrintSExpression::maybePrintImplicitBlock(Expression* curr) { auto block = curr->dynCast(); - if (!full && block && block->name.isNull() && - (allowMultipleInsts || block->list.size() == 1)) { + if (!full && block && block->name.isNull()) { for (auto expression : block->list) { printFullLine(expression); } @@ -2657,13 +2655,23 @@ void PrintSExpression::visitIf(If* curr) { printExpressionContents(curr); incIndent(); printFullLine(curr->condition); - maybePrintImplicitBlock(curr->ifTrue, false); + doIndent(o, indent); + o << "(then"; + incIndent(); + maybePrintImplicitBlock(curr->ifTrue); + decIndent(); + o << maybeNewLine; if (curr->ifFalse) { + doIndent(o, indent); + o << "(else"; + incIndent(); // Note: debug info here is not used as LLVM does not emit ifs, and since // LLVM is the main source of DWARF, effectively we never encounter ifs // with DWARF. printDebugDelimiterLocation(curr, BinaryLocations::Else); - maybePrintImplicitBlock(curr->ifFalse, false); + maybePrintImplicitBlock(curr->ifFalse); + decIndent(); + o << maybeNewLine; } decIndent(); if (full) { @@ -2677,7 +2685,7 @@ void PrintSExpression::visitLoop(Loop* curr) { o << '('; printExpressionContents(curr); incIndent(); - maybePrintImplicitBlock(curr->body, true); + maybePrintImplicitBlock(curr->body); decIndent(); if (full) { o << " ;; end loop"; @@ -2722,7 +2730,7 @@ void PrintSExpression::visitTry(Try* curr) { o << '('; printMedium(o, "do"); incIndent(); - maybePrintImplicitBlock(curr->body, true); + maybePrintImplicitBlock(curr->body); decIndent(); o << "\n"; for (size_t i = 0; i < curr->catchTags.size(); i++) { @@ -2732,7 +2740,7 @@ void PrintSExpression::visitTry(Try* curr) { printMedium(o, "catch "); printName(curr->catchTags[i], o); incIndent(); - maybePrintImplicitBlock(curr->catchBodies[i], true); + maybePrintImplicitBlock(curr->catchBodies[i]); decIndent(); o << "\n"; } @@ -2742,7 +2750,7 @@ void PrintSExpression::visitTry(Try* curr) { o << '('; printMedium(o, "catch_all"); incIndent(); - maybePrintImplicitBlock(curr->catchBodies.back(), true); + maybePrintImplicitBlock(curr->catchBodies.back()); decIndent(); o << "\n"; } @@ -2770,7 +2778,7 @@ void PrintSExpression::visitTryTable(TryTable* curr) { o << '('; printExpressionContents(curr); incIndent(); - maybePrintImplicitBlock(curr->body, true); + maybePrintImplicitBlock(curr->body); decIndent(); if (full) { o << " ;; end if"; diff --git a/src/passes/wasm-intrinsics.wat b/src/passes/wasm-intrinsics.wat index 185bef961a8..efa31264556 100644 --- a/src/passes/wasm-intrinsics.wat +++ b/src/passes/wasm-intrinsics.wat @@ -146,16 +146,18 @@ (func $__wasm_ctz_i32 (; 7 ;) (type $3) (param $var$0 i32) (result i32) (if (local.get $var$0) - (return - (i32.sub - (i32.const 31) - (i32.clz - (i32.xor - (i32.add + (then + (return + (i32.sub + (i32.const 31) + (i32.clz + (i32.xor + (i32.add + (local.get $var$0) + (i32.const -1) + ) (local.get $var$0) - (i32.const -1) ) - (local.get $var$0) ) ) ) @@ -171,16 +173,18 @@ (local.get $var$0) ) ) - (return - (i64.sub - (i64.const 63) - (i64.clz - (i64.xor - (i64.add + (then + (return + (i64.sub + (i64.const 63) + (i64.clz + (i64.xor + (i64.add + (local.get $var$0) + (i64.const -1) + ) (local.get $var$0) - (i64.const -1) ) - (local.get $var$0) ) ) ) @@ -369,38 +373,42 @@ (f32.const 0.5) ) ) - (block - (local.set $var$0 - (f32.ceil - (local.get $var$0) - ) - ) - (if - (f32.gt - (local.get $var$2) - (f32.const 0.5) + (then + (block + (local.set $var$0 + (f32.ceil + (local.get $var$0) + ) ) - (return - (local.get $var$0) + (if + (f32.gt + (local.get $var$2) + (f32.const 0.5) + ) + (then + (return + (local.get $var$0) + ) + ) ) - ) - (local.set $var$1 - (select - (local.get $var$1) - (local.get $var$0) - (f32.eq - (f32.sub - (local.tee $var$2 - (f32.mul - (local.get $var$1) - (f32.const 0.5) + (local.set $var$1 + (select + (local.get $var$1) + (local.get $var$0) + (f32.eq + (f32.sub + (local.tee $var$2 + (f32.mul + (local.get $var$1) + (f32.const 0.5) + ) + ) + (f32.floor + (local.get $var$2) ) ) - (f32.floor - (local.get $var$2) - ) + (f32.const 0) ) - (f32.const 0) ) ) ) @@ -429,38 +437,42 @@ (f64.const 0.5) ) ) - (block - (local.set $var$0 - (f64.ceil - (local.get $var$0) - ) - ) - (if - (f64.gt - (local.get $var$2) - (f64.const 0.5) + (then + (block + (local.set $var$0 + (f64.ceil + (local.get $var$0) + ) ) - (return - (local.get $var$0) + (if + (f64.gt + (local.get $var$2) + (f64.const 0.5) + ) + (then + (return + (local.get $var$0) + ) + ) ) - ) - (local.set $var$1 - (select - (local.get $var$1) - (local.get $var$0) - (f64.eq - (f64.sub - (local.tee $var$2 - (f64.mul - (local.get $var$1) - (f64.const 0.5) + (local.set $var$1 + (select + (local.get $var$1) + (local.get $var$0) + (f64.eq + (f64.sub + (local.tee $var$2 + (f64.mul + (local.get $var$1) + (f64.const 0.5) + ) + ) + (f64.floor + (local.get $var$2) ) ) - (f64.floor - (local.get $var$2) - ) + (f64.const 0) ) - (f64.const 0) ) ) ) @@ -496,44 +508,46 @@ ) ) ) - (block - (br_if $label$11 - (i32.eqz - (local.tee $var$3 - (i32.wrap_i64 - (local.get $var$1) + (then + (block + (br_if $label$11 + (i32.eqz + (local.tee $var$3 + (i32.wrap_i64 + (local.get $var$1) + ) ) ) ) - ) - (br_if $label$9 - (i32.eqz - (local.tee $var$4 - (i32.wrap_i64 - (i64.shr_u - (local.get $var$1) - (i64.const 32) + (br_if $label$9 + (i32.eqz + (local.tee $var$4 + (i32.wrap_i64 + (i64.shr_u + (local.get $var$1) + (i64.const 32) + ) ) ) ) ) - ) - (br_if $label$8 - (i32.le_u - (local.tee $var$2 - (i32.sub - (i32.clz - (local.get $var$4) - ) - (i32.clz - (local.get $var$2) + (br_if $label$8 + (i32.le_u + (local.tee $var$2 + (i32.sub + (i32.clz + (local.get $var$4) + ) + (i32.clz + (local.get $var$2) + ) ) ) + (i32.const 31) ) - (i32.const 31) ) + (br $label$2) ) - (br $label$2) ) ) (br_if $label$2 @@ -790,69 +804,71 @@ (block $label$13 (if (local.get $var$2) - (block - (local.set $var$8 - (i64.add - (local.get $var$1) - (i64.const -1) + (then + (block + (local.set $var$8 + (i64.add + (local.get $var$1) + (i64.const -1) + ) ) - ) - (loop $label$15 - (local.set $var$5 - (i64.sub - (local.tee $var$5 - (i64.or - (i64.shl - (local.get $var$5) - (i64.const 1) - ) - (i64.shr_u - (local.get $var$0) - (i64.const 63) + (loop $label$15 + (local.set $var$5 + (i64.sub + (local.tee $var$5 + (i64.or + (i64.shl + (local.get $var$5) + (i64.const 1) + ) + (i64.shr_u + (local.get $var$0) + (i64.const 63) + ) ) ) - ) - (i64.and - (local.tee $var$6 - (i64.shr_s - (i64.sub - (local.get $var$8) - (local.get $var$5) + (i64.and + (local.tee $var$6 + (i64.shr_s + (i64.sub + (local.get $var$8) + (local.get $var$5) + ) + (i64.const 63) ) - (i64.const 63) ) + (local.get $var$1) ) - (local.get $var$1) ) ) - ) - (local.set $var$0 - (i64.or - (i64.shl - (local.get $var$0) - (i64.const 1) + (local.set $var$0 + (i64.or + (i64.shl + (local.get $var$0) + (i64.const 1) + ) + (local.get $var$7) ) - (local.get $var$7) ) - ) - (local.set $var$7 - (local.tee $var$6 - (i64.and - (local.get $var$6) - (i64.const 1) + (local.set $var$7 + (local.tee $var$6 + (i64.and + (local.get $var$6) + (i64.const 1) + ) ) ) - ) - (br_if $label$15 - (local.tee $var$2 - (i32.add - (local.get $var$2) - (i32.const -1) + (br_if $label$15 + (local.tee $var$2 + (i32.add + (local.get $var$2) + (i32.const -1) + ) ) ) ) + (br $label$13) ) - (br $label$13) ) ) ) diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 41a5b188495..9270a19b0b1 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1703,12 +1703,11 @@ Expression* SExpressionWasmBuilder::makeBlock(Element& s) { // Similar to block, but the label is handled by the enclosing if (since there // might not be a then or else, ick) Expression* SExpressionWasmBuilder::makeThenOrElse(Element& s) { - auto ret = allocator.alloc(); - size_t i = 1; - if (s.size() > 1 && s[1]->isStr()) { - i++; + if (s.size() == 2) { + return parseExpression(s[1]); } - for (; i < s.size(); i++) { + auto ret = allocator.alloc(); + for (size_t i = 1; i < s.size(); i++) { ret->list.push_back(parseExpression(s[i])); } ret->finalize(); @@ -2415,8 +2414,14 @@ Expression* SExpressionWasmBuilder::makeIf(Element& s) { // if signature Type type = parseBlockType(s, i); ret->condition = parseExpression(s[i++]); + if (!elementStartsWith(*s[i], "then")) { + throw SParseException("expected 'then'", *s[i]); + } ret->ifTrue = parseExpression(*s[i++]); if (i < s.size()) { + if (!elementStartsWith(*s[i], "else")) { + throw SParseException("expected 'else'", *s[i]); + } ret->ifFalse = parseExpression(*s[i++]); } ret->finalize(type); diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index c7c45a08a1a..bd681f86dfe 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -109,7 +109,7 @@ console.log("# If"); assert( theIf.toText() == - "(if (result i32)\n (i32.const 4)\n (i32.const 5)\n (i32.const 6)\n)\n" + "(if (result i32)\n (i32.const 4)\n (then\n (i32.const 5)\n )\n (else\n (i32.const 6)\n )\n)\n" ); theIf.ifFalse = null; @@ -118,7 +118,7 @@ console.log("# If"); assert( theIf.toText() == - "(if (result i32)\n (i32.const 4)\n (i32.const 5)\n)\n" + "(if (result i32)\n (i32.const 4)\n (then\n (i32.const 5)\n )\n)\n" ); module.dispose(); diff --git a/test/binaryen.js/expressions.js.txt b/test/binaryen.js/expressions.js.txt index 7b04795ba33..5d6c37c6bc6 100644 --- a/test/binaryen.js/expressions.js.txt +++ b/test/binaryen.js/expressions.js.txt @@ -7,13 +7,19 @@ # If (if (result i32) (i32.const 4) - (i32.const 5) - (i32.const 6) + (then + (i32.const 5) + ) + (else + (i32.const 6) + ) ) (if (result i32) (i32.const 4) - (i32.const 5) + (then + (i32.const 5) + ) ) # Loop diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index bbef03377e6..b5a9b713e9d 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -1934,17 +1934,23 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) ) (drop @@ -4038,17 +4044,23 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) ) (drop @@ -4423,14 +4435,18 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) + (then + (block + (call $check + (i32.const 1) + ) ) ) - (block - (call $check - (i32.const 2) + (else + (block + (call $check + (i32.const 2) + ) ) ) ) @@ -4442,7 +4458,7 @@ raw: ) (if (i32.const 55) - (block + (then (drop (i32.const 10) ) @@ -4452,7 +4468,7 @@ raw: ) ) ) - (block + (else (drop (i32.const 20) ) @@ -4472,15 +4488,19 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) - ) + (then (block - (br $block$3$break) + (call $check + (i32.const 1) + ) + (block + (br $block$3$break) + ) ) ) - (br $block$3$break) + (else + (br $block$3$break) + ) ) ) (block @@ -4497,7 +4517,7 @@ raw: ) (if (i32.const 55) - (block + (then (drop (i32.const -1) ) @@ -4513,7 +4533,7 @@ raw: ) ) ) - (block + (else (drop (i32.const -2) ) @@ -4535,20 +4555,24 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) - ) + (then (block - (br $block$4$break) + (call $check + (i32.const 1) + ) + (block + (br $block$4$break) + ) ) ) - (block - (call $check - (i32.const 2) - ) + (else (block - (br $block$4$break) + (call $check + (i32.const 2) + ) + (block + (br $block$4$break) + ) ) ) ) @@ -4573,8 +4597,12 @@ raw: ) (if (i32.const 10) - (br $shape$0$continue) - (br $block$3$break) + (then + (br $shape$0$continue) + ) + (else + (br $block$3$break) + ) ) ) ) @@ -4607,8 +4635,10 @@ raw: ) (if (i32.const -2) - (br $block$3$break) - (block + (then + (br $block$3$break) + ) + (else (drop (i32.const 20) ) @@ -4622,8 +4652,10 @@ raw: ) (if (i32.const -6) - (br $block$4$break) - (block + (then + (br $block$4$break) + ) + (else (drop (i32.const 30) ) @@ -4640,15 +4672,19 @@ raw: ) (if (i32.const -10) - (block - (call $check - (i32.const 4) - ) + (then (block - (br $block$6$break) + (call $check + (i32.const 4) + ) + (block + (br $block$6$break) + ) ) ) - (br $block$6$break) + (else + (br $block$6$break) + ) ) ) (block @@ -4731,13 +4767,13 @@ raw: ) (if (i32.const 10) - (block + (then (local.set $3 (i32.const 2) ) (br $block$2$break) ) - (block + (else (local.set $3 (i32.const 3) ) @@ -4753,7 +4789,7 @@ raw: (local.get $3) (i32.const 2) ) - (block + (then (local.set $3 (i32.const 0) ) @@ -4767,23 +4803,25 @@ raw: (br $shape$1$continue) ) ) - (if - (i32.eq - (local.get $3) - (i32.const 3) - ) - (block - (local.set $3 - (i32.const 0) - ) - (call $check - (i32.const 2) + (else + (if + (i32.eq + (local.get $3) + (i32.const 3) ) - (block + (then (local.set $3 + (i32.const 0) + ) + (call $check (i32.const 2) ) - (br $shape$1$continue) + (block + (local.set $3 + (i32.const 2) + ) + (br $shape$1$continue) + ) ) ) ) diff --git a/test/binaryen.js/optimize-levels.js b/test/binaryen.js/optimize-levels.js index b3dd2adbd98..6d9dbc26286 100644 --- a/test/binaryen.js/optimize-levels.js +++ b/test/binaryen.js/optimize-levels.js @@ -7,8 +7,8 @@ var wast = ` (block (result i32) (if (result i32) (local.get $0) - (local.get $0) - (i32.const 0) + (then (local.get $0)) + (else (i32.const 0)) ) ) ) diff --git a/test/binaryen.js/optimize-levels.js.txt b/test/binaryen.js/optimize-levels.js.txt index 05fe2358986..ed928fbef15 100644 --- a/test/binaryen.js/optimize-levels.js.txt +++ b/test/binaryen.js/optimize-levels.js.txt @@ -7,8 +7,8 @@ (block (result i32) (if (result i32) (local.get $0) - (local.get $0) - (i32.const 0) + (then (local.get $0)) + (else (i32.const 0)) ) ) ) @@ -22,8 +22,12 @@ (func $test (param $0 i32) (result i32) (if (result i32) (local.get $0) - (local.get $0) - (i32.const 0) + (then + (local.get $0) + ) + (else + (i32.const 0) + ) ) ) ) diff --git a/test/binaryen.js/sieve.js.txt b/test/binaryen.js/sieve.js.txt index 3fad13fdf01..46e5d3b398c 100644 --- a/test/binaryen.js/sieve.js.txt +++ b/test/binaryen.js/sieve.js.txt @@ -12,17 +12,19 @@ ) (local.get $0) ) - (drop - (memory.grow - (i32.sub - (i32.div_u - (i32.add - (local.get $0) - (i32.const 65535) + (then + (drop + (memory.grow + (i32.sub + (i32.div_u + (i32.add + (local.get $0) + (i32.const 65535) + ) + (i32.const 65536) ) - (i32.const 65536) + (memory.size) ) - (memory.size) ) ) ) @@ -70,17 +72,19 @@ optimized: ) (local.get $0) ) - (drop - (memory.grow - (i32.sub - (i32.shr_u - (i32.add - (local.get $0) - (i32.const 65535) + (then + (drop + (memory.grow + (i32.sub + (i32.shr_u + (i32.add + (local.get $0) + (i32.const 65535) + ) + (i32.const 16) ) - (i32.const 16) + (memory.size) ) - (memory.size) ) ) ) diff --git a/test/binaryen.js/stackir.js b/test/binaryen.js/stackir.js index 20754e078a8..d797aa6d818 100644 --- a/test/binaryen.js/stackir.js +++ b/test/binaryen.js/stackir.js @@ -8,8 +8,8 @@ var wast = ` (block (result i32) (if (result i32) (local.get $0) - (local.get $0) - (i32.const 0) + (then (local.get $0)) + (else (i32.const 0)) ) ) ) diff --git a/test/binaryen.js/stackir.js.txt b/test/binaryen.js/stackir.js.txt index a49c6bb01c5..bd906c388b0 100644 --- a/test/binaryen.js/stackir.js.txt +++ b/test/binaryen.js/stackir.js.txt @@ -8,8 +8,8 @@ (block (result i32) (if (result i32) (local.get $0) - (local.get $0) - (i32.const 0) + (then (local.get $0)) + (else (i32.const 0)) ) ) ) diff --git a/test/ctor-eval/partial-return.wast b/test/ctor-eval/partial-return.wast index 8ca6eee7570..e74c59cb871 100644 --- a/test/ctor-eval/partial-return.wast +++ b/test/ctor-eval/partial-return.wast @@ -18,7 +18,9 @@ (i32.load8_u (i32.const 12) ) - (return) + (then + (return) + ) ) ;; This is unsafe to call, and would stop evalling here. But we exit due to diff --git a/test/ctor-eval/results.wast b/test/ctor-eval/results.wast index bfefa2756c2..dcd10ea5f38 100644 --- a/test/ctor-eval/results.wast +++ b/test/ctor-eval/results.wast @@ -41,13 +41,17 @@ ;; we should succeed. After that we should keep returning the constant 55 (if (result i32) (i32.const 1) - (block (result i32) - (global.set $global4 - (i32.const 14) + (then + (block (result i32) + (global.set $global4 + (i32.const 14) + ) + (i32.const 55) ) - (i32.const 55) ) - (i32.const 99) + (else + (i32.const 99) + ) ) ) diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 06ec3a1b7d1..75c71b4ab01 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1969,17 +1969,23 @@ BinaryenFeatureAll: 131071 ) (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) ) (drop @@ -2685,14 +2691,18 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) + (then + (block + (call $check + (i32.const 1) + ) ) ) - (block - (call $check - (i32.const 2) + (else + (block + (call $check + (i32.const 2) + ) ) ) ) @@ -2704,7 +2714,7 @@ raw: ) (if (i32.const 55) - (block + (then (drop (i32.const 10) ) @@ -2714,7 +2724,7 @@ raw: ) ) ) - (block + (else (drop (i32.const 20) ) @@ -2734,15 +2744,19 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) - ) + (then (block - (br $block$3$break) + (call $check + (i32.const 1) + ) + (block + (br $block$3$break) + ) ) ) - (br $block$3$break) + (else + (br $block$3$break) + ) ) ) (block @@ -2759,7 +2773,7 @@ raw: ) (if (i32.const 55) - (block + (then (drop (i32.const -1) ) @@ -2775,7 +2789,7 @@ raw: ) ) ) - (block + (else (drop (i32.const -2) ) @@ -2797,20 +2811,24 @@ raw: ) (if (i32.const 55) - (block - (call $check - (i32.const 1) - ) + (then (block - (br $block$4$break) + (call $check + (i32.const 1) + ) + (block + (br $block$4$break) + ) ) ) - (block - (call $check - (i32.const 2) - ) + (else (block - (br $block$4$break) + (call $check + (i32.const 2) + ) + (block + (br $block$4$break) + ) ) ) ) @@ -2835,8 +2853,12 @@ raw: ) (if (i32.const 10) - (br $shape$0$continue) - (br $block$3$break) + (then + (br $shape$0$continue) + ) + (else + (br $block$3$break) + ) ) ) ) @@ -2869,8 +2891,10 @@ raw: ) (if (i32.const -2) - (br $block$3$break) - (block + (then + (br $block$3$break) + ) + (else (drop (i32.const 20) ) @@ -2884,8 +2908,10 @@ raw: ) (if (i32.const -6) - (br $block$4$break) - (block + (then + (br $block$4$break) + ) + (else (drop (i32.const 30) ) @@ -2902,15 +2928,19 @@ raw: ) (if (i32.const -10) - (block - (call $check - (i32.const 4) - ) + (then (block - (br $block$6$break) + (call $check + (i32.const 4) + ) + (block + (br $block$6$break) + ) ) ) - (br $block$6$break) + (else + (br $block$6$break) + ) ) ) (block @@ -2993,13 +3023,13 @@ raw: ) (if (i32.const 10) - (block + (then (local.set $3 (i32.const 2) ) (br $block$2$break) ) - (block + (else (local.set $3 (i32.const 3) ) @@ -3015,7 +3045,7 @@ raw: (local.get $3) (i32.const 2) ) - (block + (then (local.set $3 (i32.const 0) ) @@ -3029,23 +3059,25 @@ raw: (br $shape$1$continue) ) ) - (if - (i32.eq - (local.get $3) - (i32.const 3) - ) - (block - (local.set $3 - (i32.const 0) - ) - (call $check - (i32.const 2) + (else + (if + (i32.eq + (local.get $3) + (i32.const 3) ) - (block + (then (local.set $3 + (i32.const 0) + ) + (call $check (i32.const 2) ) - (br $shape$1$continue) + (block + (local.set $3 + (i32.const 2) + ) + (br $shape$1$continue) + ) ) ) ) diff --git a/test/example/relooper-fuzz.txt b/test/example/relooper-fuzz.txt index c962a3e0a2a..1030fac320d 100644 --- a/test/example/relooper-fuzz.txt +++ b/test/example/relooper-fuzz.txt @@ -14,7 +14,9 @@ ) (i32.const 108) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) @@ -172,24 +174,26 @@ ) (i32.const 0) ) - (block + (then (local.set $1 (i32.const 6) ) (br $block$6$break) ) - (block + (else (block - (call $print - (i32.const 8) + (block + (call $print + (i32.const 8) + ) + (local.set $0 + (call $check) + ) ) - (local.set $0 - (call $check) + (block + (br $block$5$break) ) ) - (block - (br $block$5$break) - ) ) ) ) @@ -202,7 +206,7 @@ (local.get $1) (i32.const 6) ) - (block + (then (local.set $1 (i32.const 0) ) @@ -222,8 +226,10 @@ ) (i32.const 0) ) - (br $shape$3$continue) - (block + (then + (br $shape$3$continue) + ) + (else (local.set $1 (i32.const 6) ) @@ -251,22 +257,28 @@ ) (i32.const 0) ) - (br $shape$3$continue) - (if - (i32.eq - (i32.rem_u - (local.get $0) - (i32.const 3) + (then + (br $shape$3$continue) + ) + (else + (if + (i32.eq + (i32.rem_u + (local.get $0) + (i32.const 3) + ) + (i32.const 1) ) - (i32.const 1) - ) - (block - (local.set $1 - (i32.const 6) + (then + (local.set $1 + (i32.const 6) + ) + (br $shape$3$continue) + ) + (else + (br $block$3$break) ) - (br $shape$3$continue) ) - (br $block$3$break) ) ) ) @@ -307,7 +319,9 @@ ) (i32.const 108) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) @@ -453,7 +467,7 @@ (call $check) (i32.const 1) ) - (block + (then (call $print (i32.const 8) ) @@ -461,8 +475,10 @@ (call $check) ) ) - (local.set $0 - (i32.const 6) + (else + (local.set $0 + (i32.const 6) + ) ) ) (loop $shape$3$continue @@ -471,7 +487,7 @@ (local.get $0) (i32.const 6) ) - (block + (then (local.set $0 (i32.const 0) ) @@ -513,13 +529,13 @@ ) (i32.const 1) ) - (block + (then (local.set $0 (i32.const 6) ) (br $shape$3$continue) ) - (block + (else (call $print (i32.const 2) ) diff --git a/test/example/relooper-fuzz1.txt b/test/example/relooper-fuzz1.txt index 1fb24808ea2..3cdb12e69f1 100644 --- a/test/example/relooper-fuzz1.txt +++ b/test/example/relooper-fuzz1.txt @@ -14,7 +14,9 @@ ) (i32.const 120) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) @@ -184,37 +186,49 @@ ) (i32.const 0) ) - (br $block$3$break) - (if - (i32.eq - (i32.rem_u - (local.get $0) - (i32.const 4) - ) - (i32.const 2) - ) - (block - (block - (call $print - (i32.const 7) - ) - (local.set $0 - (call $check) + (then + (br $block$3$break) + ) + (else + (if + (i32.eq + (i32.rem_u + (local.get $0) + (i32.const 4) ) + (i32.const 2) ) - (if - (i32.eq - (i32.rem_u - (local.get $0) - (i32.const 3) + (then + (block + (block + (call $print + (i32.const 7) + ) + (local.set $0 + (call $check) + ) + ) + (if + (i32.eq + (i32.rem_u + (local.get $0) + (i32.const 3) + ) + (i32.const 0) + ) + (then + (br $block$3$break) + ) + (else + (br $block$10$break) + ) ) - (i32.const 0) ) - (br $block$3$break) - (br $block$10$break) + ) + (else + (br $block$4$break) ) ) - (br $block$4$break) ) ) ) @@ -235,8 +249,12 @@ ) (i32.const 0) ) - (br $block$4$break) - (br $block$10$break) + (then + (br $block$4$break) + ) + (else + (br $block$10$break) + ) ) ) ) @@ -283,7 +301,9 @@ ) (i32.const 120) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) @@ -444,26 +464,30 @@ ) (i32.const 3) ) - (if - (i32.eq - (i32.and - (local.get $0) - (i32.const 3) - ) - (i32.const 2) - ) - (block - (call $print - (i32.const 7) - ) - (br_if $block$10$break - (i32.rem_u - (call $check) + (then + (if + (i32.eq + (i32.and + (local.get $0) (i32.const 3) ) + (i32.const 2) + ) + (then + (call $print + (i32.const 7) + ) + (br_if $block$10$break + (i32.rem_u + (call $check) + (i32.const 3) + ) + ) + ) + (else + (br $block$4$break) ) ) - (br $block$4$break) ) ) (call $print diff --git a/test/example/relooper-fuzz2.txt b/test/example/relooper-fuzz2.txt index bee8277d750..0b3fdb2fd7b 100644 --- a/test/example/relooper-fuzz2.txt +++ b/test/example/relooper-fuzz2.txt @@ -14,7 +14,9 @@ ) (i32.const 108) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge1.txt b/test/example/relooper-merge1.txt index 1d5779259db..61816bebd0c 100644 --- a/test/example/relooper-merge1.txt +++ b/test/example/relooper-merge1.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge2.txt b/test/example/relooper-merge2.txt index 31a13192d12..a52ee20b301 100644 --- a/test/example/relooper-merge2.txt +++ b/test/example/relooper-merge2.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge3.txt b/test/example/relooper-merge3.txt index a856d10b0b6..3c8f3f5388f 100644 --- a/test/example/relooper-merge3.txt +++ b/test/example/relooper-merge3.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge4.txt b/test/example/relooper-merge4.txt index 6f0f7d5b3d8..5d3420f49f9 100644 --- a/test/example/relooper-merge4.txt +++ b/test/example/relooper-merge4.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge5.txt b/test/example/relooper-merge5.txt index c09c016b926..38aaf6a0237 100644 --- a/test/example/relooper-merge5.txt +++ b/test/example/relooper-merge5.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge6.txt b/test/example/relooper-merge6.txt index dca86d40a96..9519d024233 100644 --- a/test/example/relooper-merge6.txt +++ b/test/example/relooper-merge6.txt @@ -14,7 +14,9 @@ ) (i32.const 48) ) - (unreachable) + (then + (unreachable) + ) ) (i32.store (i32.const 4) diff --git a/test/example/relooper-merge7.txt b/test/example/relooper-merge7.txt index 23ffffb218d..fb54ddea9e4 100644 --- a/test/example/relooper-merge7.txt +++ b/test/example/relooper-merge7.txt @@ -7,8 +7,12 @@ ) (if (i32.const -10) - (br $block$3$break) - (br $block$2$break) + (then + (br $block$3$break) + ) + (else + (br $block$2$break) + ) ) ) (block diff --git a/test/fib-dbg.wasm.fromBinary b/test/fib-dbg.wasm.fromBinary index f36bd2250d1..bc90702d312 100644 --- a/test/fib-dbg.wasm.fromBinary +++ b/test/fib-dbg.wasm.fromBinary @@ -100,7 +100,7 @@ (global.get $global$7) (i32.const 0) ) - (block + (then (global.set $global$7 (local.get $0) ) @@ -136,7 +136,7 @@ ;;@ fib.c:3:0 (if (local.get $6) - (block + (then (local.set $1 (i32.const 0) ) @@ -147,7 +147,7 @@ (i32.const 0) ) ) - (block + (else (local.set $4 (i32.const 1) ) @@ -184,13 +184,13 @@ ;;@ fib.c:3:0 (if (local.get $7) - (block + (then (local.set $4 (local.get $3) ) (br $label$5) ) - (block + (else (local.set $2 (local.get $5) ) diff --git a/test/gtest/cfg.cpp b/test/gtest/cfg.cpp index bf3742bc13d..c78eb218a45 100644 --- a/test/gtest/cfg.cpp +++ b/test/gtest/cfg.cpp @@ -26,7 +26,7 @@ TEST_F(CFGTest, Print) { (drop (if (result i32) (i32.const 1) - (block + (then (loop $loop (br_if $loop (i32.const 2) @@ -34,8 +34,10 @@ TEST_F(CFGTest, Print) { ) (i32.const 3) ) - (return - (i32.const 4) + (else + (return + (i32.const 4) + ) ) ) ) @@ -65,7 +67,7 @@ TEST_F(CFGTest, Print) { ;; preds: [3], succs: [6] 4: 6: i32.const 3 - 7: block + 7: block (result i32) ;; preds: [0], succs: [7] 5: @@ -230,7 +232,7 @@ TEST_F(CFGTest, BlockIndexes) { (func $foo (if (i32.const 1) - (block + (then (drop (i32.const 2) ) @@ -343,11 +345,15 @@ TEST_F(CFGTest, ReachingDefinitionsIf) { (local.get $a) (i32.const 2) ) - (local.set $b - (i32.const 3) + (then + (local.set $b + (i32.const 3) + ) ) - (local.set $a - (i32.const 4) + (else + (local.set $a + (i32.const 4) + ) ) ) (drop diff --git a/test/gtest/stringify.cpp b/test/gtest/stringify.cpp index 3e50c6d4c53..c38c29d8063 100644 --- a/test/gtest/stringify.cpp +++ b/test/gtest/stringify.cpp @@ -20,13 +20,13 @@ TEST_F(StringifyTest, Print) { ) (block $block_b (drop (if (i32.const 0) - (i32.const 40) - (i32.const 5) + (then (i32.const 40)) + (else (i32.const 5)) )) ) (block $block_c (drop (if (i32.const 1) - (i32.const 30) + (then (i32.const 30)) )) ) (block $block_d @@ -150,13 +150,13 @@ static auto dupModuleText = R"wasm( ) (block $block_b (drop (if (i32.const 0) - (i32.const 40) - (i32.const 5) + (then (i32.const 40)) + (else (i32.const 5)) )) ) (block $block_c (drop (if (i32.const 1) - (i32.const 30) + (then (i32.const 30)) )) ) (block $block_d @@ -165,12 +165,12 @@ static auto dupModuleText = R"wasm( ) (block $block_e (drop (if (i32.const 1) - (i32.const 30) + (then (i32.const 30)) )) ) (block $block_f (drop (if (i32.const 0) - (i32.const 30) + (then (i32.const 30)) )) ) ) diff --git a/test/lit/basic/exception-handling-old.wast b/test/lit/basic/exception-handling-old.wast index c082c1977da..6fcb33ed43e 100644 --- a/test/lit/basic/exception-handling-old.wast +++ b/test/lit/basic/exception-handling-old.wast @@ -1160,8 +1160,12 @@ ;; CHECK-TEXT-NEXT: (throw $e-i32 ;; CHECK-TEXT-NEXT: (if (result i32) ;; CHECK-TEXT-NEXT: (pop i32) - ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -1176,8 +1180,12 @@ ;; CHECK-BIN-NEXT: (throw $e-i32 ;; CHECK-BIN-NEXT: (if (result i32) ;; CHECK-BIN-NEXT: (pop i32) - ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) @@ -1191,8 +1199,12 @@ (if (result i32) ;; pop is within an if condition, so this is OK. (pop i32) - (i32.const 0) - (i32.const 3) + (then + (i32.const 0) + ) + (else + (i32.const 3) + ) ) ) ) @@ -1764,8 +1776,12 @@ ;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 ;; CHECK-BIN-NODEBUG-NEXT: (if (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (pop i32) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/exception-handling.wast b/test/lit/basic/exception-handling.wast index b94f89e1aad..e1fa9c14dfb 100644 --- a/test/lit/basic/exception-handling.wast +++ b/test/lit/basic/exception-handling.wast @@ -79,12 +79,20 @@ ;; CHECK-TEXT-NEXT: (local $null-exn nullexnref) ;; CHECK-TEXT-NEXT: (if (result exnref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (if (result nullexnref) - ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (local.get $null-exn) - ;; CHECK-TEXT-NEXT: (ref.null noexn) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (if (result nullexnref) + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.get $null-exn) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null noexn) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (local.get $exn) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $exnref-nullexnref-test (type $3) (result exnref) @@ -92,23 +100,39 @@ ;; CHECK-BIN-NEXT: (local $null-exn nullexnref) ;; CHECK-BIN-NEXT: (if (result exnref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (if (result nullexnref) - ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (local.get $null-exn) - ;; CHECK-BIN-NEXT: (ref.null noexn) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (if (result nullexnref) + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (local.get $null-exn) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null noexn) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (local.get $exn) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.get $exn) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $exnref-nullexnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref) (if (result exnref) (i32.const 1) - (if (result nullexnref) - (i32.const 1) - (local.get $null-exn) - (ref.null noexn) + (then + (if (result nullexnref) + (i32.const 1) + (then + (local.get $null-exn) + ) + (else + (ref.null noexn) + ) + ) + ) + (else + (local.get $exn) ) - (local.get $exn) ) ) @@ -631,11 +655,15 @@ ;; CHECK-TEXT-NEXT: (try_table (catch $e-i32 $l-catch-inner) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (throw $e-i32 - ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (throw $e-i32 + ;; CHECK-TEXT-NEXT: (i32.const 3) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (throw $e-eqref - ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (throw $e-eqref + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -653,11 +681,15 @@ ;; CHECK-BIN-NEXT: (try_table (catch $e-i32 $label$2) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (throw $e-i32 - ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (throw $e-i32 + ;; CHECK-BIN-NEXT: (i32.const 3) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (throw $e-eqref - ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (throw $e-eqref + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) @@ -675,8 +707,12 @@ (try_table (catch $e-i32 $l-catch-inner) (if (i32.const 0) - (throw $e-i32 (i32.const 3)) - (throw $e-eqref (ref.null eq)) + (then + (throw $e-i32 (i32.const 3)) + ) + (else + (throw $e-eqref (ref.null eq)) + ) ) ) ) @@ -725,12 +761,20 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local $1 nullexnref) ;; CHECK-BIN-NODEBUG-NEXT: (if (result exnref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (if (result nullexnref) -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null noexn) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (if (result nullexnref) +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null noexn) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -988,11 +1032,15 @@ ;; CHECK-BIN-NODEBUG-NEXT: (try_table (catch $tag$0 $label$2) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$0 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$3 -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (throw $tag$3 +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/polymorphic_stack.wast b/test/lit/basic/polymorphic_stack.wast index d51117e16f9..fc743bf2aea 100644 --- a/test/lit/basic/polymorphic_stack.wast +++ b/test/lit/basic/polymorphic_stack.wast @@ -162,8 +162,10 @@ ;; CHECK-TEXT-NEXT: (local $0 f32) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 259) - ;; CHECK-TEXT-NEXT: (local.tee $0 - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.tee $0 + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -171,15 +173,19 @@ ;; CHECK-BIN-NEXT: (local $0 f32) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 259) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $tee2 (local $0 f32) (if (i32.const 259) - (local.set $0 - (unreachable) + (then + (local.set $0 + (unreachable) + ) ) ) ) @@ -245,8 +251,10 @@ ;; CHECK-TEXT: (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (i32.const 127) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 127) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (block $label$0 (result i32) @@ -261,8 +269,10 @@ ;; CHECK-BIN: (func $unreachable-in-block-but-code-before (type $FUNCSIG$ii) (param $0 i32) (result i32) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (i32.const 127) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 127) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (block $label$2 (result i32) @@ -277,8 +287,10 @@ (func $unreachable-in-block-but-code-before (param $0 i32) (result i32) (if (local.get $0) - (return - (i32.const 127) + (then + (return + (i32.const 127) + ) ) ) (block $label$0 (result i32) @@ -325,11 +337,15 @@ ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (br_if $label$8 + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br_if $label$8 + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (i32.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -340,8 +356,12 @@ ;; CHECK-BIN-NEXT: (block $label$2 ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (unreachable) @@ -353,11 +373,15 @@ (drop (if (i32.const 0) - (br_if $label$8 + (then + (br_if $label$8 + (unreachable) + (i32.const 0) + ) + ) + (else (unreachable) - (i32.const 0) ) - (unreachable) ) ) ) @@ -393,7 +417,9 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local $0 f32) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 259) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -416,8 +442,10 @@ ;; CHECK-BIN-NODEBUG: (func $6 (type $1) (param $0 i32) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 127) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 127) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 (result i32) @@ -443,8 +471,12 @@ ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast index 2b502d78939..94d4f352557 100644 --- a/test/lit/basic/reference-types.wast +++ b/test/lit/basic/reference-types.wast @@ -525,45 +525,69 @@ ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result eqref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (local.get $local_eqref) - ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result funcref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (local.get $local_funcref) - ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.get $local_funcref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result anyref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (local.get $local_anyref) - ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.get $local_anyref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result anyref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (local.get $local_eqref) - ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result anyref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (ref.null none) - ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (if (result anyref) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (ref.i31 - ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (ref.i31 + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (ref.null none) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (ref.null none) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop @@ -1036,45 +1060,69 @@ ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result eqref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (local.get $local_eqref) - ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result funcref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (local.get $local_funcref) - ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (local.get $local_funcref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result anyref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (local.get $local_anyref) - ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (local.get $local_anyref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result anyref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (local.get $local_eqref) - ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result anyref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (ref.null none) - ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (if (result anyref) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (ref.i31 - ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (ref.i31 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop @@ -1420,22 +1468,34 @@ (drop (if (result eqref) (i32.const 1) - (local.get $local_eqref) - (ref.null eq) + (then + (local.get $local_eqref) + ) + (else + (ref.null eq) + ) ) ) (drop (if (result funcref) (i32.const 1) - (local.get $local_funcref) - (ref.null func) + (then + (local.get $local_funcref) + ) + (else + (ref.null func) + ) ) ) (drop (if (result anyref) (i32.const 1) - (local.get $local_anyref) - (ref.null any) + (then + (local.get $local_anyref) + ) + (else + (ref.null any) + ) ) ) @@ -1443,24 +1503,36 @@ (drop (if (result anyref) (i32.const 1) - (local.get $local_eqref) - (local.get $local_eqref) + (then + (local.get $local_eqref) + ) + (else + (local.get $local_eqref) + ) ) ) (drop (if (result anyref) (i32.const 1) - (ref.null eq) - (ref.null i31) + (then + (ref.null eq) + ) + (else + (ref.null i31) + ) ) ) (drop (if (result anyref) (i32.const 1) - (ref.i31 - (i32.const 0) + (then + (ref.i31 + (i32.const 0) + ) + ) + (else + (ref.null eq) ) - (ref.null eq) ) ) @@ -2201,45 +2273,69 @@ ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result eqref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result funcref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (if (result anyref) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (ref.i31 -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (ref.i31 +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop diff --git a/test/lit/basic/reg_switch.wast b/test/lit/basic/reg_switch.wast index 5f9dd5d7f6b..db749451145 100644 --- a/test/lit/basic/reg_switch.wast +++ b/test/lit/basic/reg_switch.wast @@ -22,9 +22,11 @@ ;; CHECK-TEXT: (func $0 (type $0) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 0) - ;; CHECK-TEXT-NEXT: (block $A - ;; CHECK-TEXT-NEXT: (br_table $A - ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (block $A + ;; CHECK-TEXT-NEXT: (br_table $A + ;; CHECK-TEXT-NEXT: (i32.const 0) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -32,9 +34,11 @@ ;; CHECK-BIN: (func $0 (type $0) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 0) - ;; CHECK-BIN-NEXT: (block $label$2 - ;; CHECK-BIN-NEXT: (br_table $label$2 - ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (block $label$2 + ;; CHECK-BIN-NEXT: (br_table $label$2 + ;; CHECK-BIN-NEXT: (i32.const 0) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) @@ -42,9 +46,11 @@ ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) - ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 - ;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$2 - ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) + ;; CHECK-BIN-NODEBUG-NEXT: (then + ;; CHECK-BIN-NODEBUG-NEXT: (block $label$2 + ;; CHECK-BIN-NODEBUG-NEXT: (br_table $label$2 + ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) + ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -52,9 +58,11 @@ (func $0 (type $0) (if (i32.const 0) - (block $A - (br_table $A - (i32.const 0) + (then + (block $A + (br_table $A + (i32.const 0) + ) ) ) ) diff --git a/test/lit/basic/unit.wat b/test/lit/basic/unit.wat index 4fc36b3b7ea..9cdcb57927f 100644 --- a/test/lit/basic/unit.wat +++ b/test/lit/basic/unit.wat @@ -191,8 +191,10 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (i32.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if @@ -202,8 +204,10 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (f64.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (f64.const 1.2) @@ -243,8 +247,10 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (i32.const 0) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (if @@ -254,8 +260,10 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (f64.const 0) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (f64.const 1.2) @@ -295,8 +303,10 @@ ) (i32.const 0) ) - (br $topmost - (f64.const -3.4) + (then + (br $topmost + (f64.const -3.4) + ) ) ) (if @@ -306,8 +316,10 @@ ) (f64.const 0) ) - (br $topmost - (f64.const 5.6) + (then + (br $topmost + (f64.const 5.6) + ) ) ) (f64.const 1.2) @@ -323,8 +335,10 @@ ;; CHECK-TEXT-NEXT: (local.get $x) ;; CHECK-TEXT-NEXT: (f64.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (f64.const 1.2) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 1.2) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if @@ -332,8 +346,10 @@ ;; CHECK-TEXT-NEXT: (local.get $Int) ;; CHECK-TEXT-NEXT: (f64.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const -3.4) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if @@ -341,8 +357,10 @@ ;; CHECK-TEXT-NEXT: (local.get $Double) ;; CHECK-TEXT-NEXT: (i32.const 0) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (f64.const 5.6) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if @@ -350,8 +368,10 @@ ;; CHECK-TEXT-NEXT: (local.get $x) ;; CHECK-TEXT-NEXT: (local.get $y) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (br $topmost - ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (br $topmost + ;; CHECK-TEXT-NEXT: (local.get $x) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (local.get $y) @@ -367,8 +387,10 @@ ;; CHECK-BIN-NEXT: (local.get $x) ;; CHECK-BIN-NEXT: (f64.const 0) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (f64.const 1.2) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 1.2) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (if @@ -376,8 +398,10 @@ ;; CHECK-BIN-NEXT: (local.get $Int) ;; CHECK-BIN-NEXT: (f64.const 0) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const -3.4) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (if @@ -385,8 +409,10 @@ ;; CHECK-BIN-NEXT: (local.get $Double) ;; CHECK-BIN-NEXT: (i32.const 0) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (f64.const 5.6) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (if @@ -394,8 +420,10 @@ ;; CHECK-BIN-NEXT: (local.get $x) ;; CHECK-BIN-NEXT: (local.get $y) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (br $label$1 - ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (br $label$1 + ;; CHECK-BIN-NEXT: (local.get $x) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (local.get $y) @@ -411,8 +439,10 @@ (local.get $x) (f64.const 0) ) - (br $topmost - (f64.const 1.2) + (then + (br $topmost + (f64.const 1.2) + ) ) ) (if @@ -420,8 +450,10 @@ (local.get $Int) (f64.const 0) ) - (br $topmost - (f64.const -3.4) + (then + (br $topmost + (f64.const -3.4) + ) ) ) (if @@ -429,8 +461,10 @@ (local.get $Double) (i32.const 0) ) - (br $topmost - (f64.const 5.6) + (then + (br $topmost + (f64.const 5.6) + ) ) ) (if @@ -438,8 +472,10 @@ (local.get $x) (local.get $y) ) - (br $topmost - (local.get $x) + (then + (br $topmost + (local.get $x) + ) ) ) (local.get $y) @@ -1497,11 +1533,15 @@ ;; CHECK-TEXT-NEXT: (f64.abs ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 3) - ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -1509,11 +1549,15 @@ ;; CHECK-BIN: (func $unreachable-if (type $5) (result i32) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 3) - ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) @@ -1521,38 +1565,54 @@ (f64.abs (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 1)) + ) ) ) ) ;; CHECK-TEXT: (func $unreachable-if-toplevel (type $5) (result i32) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 3) - ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 2) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (return + ;; CHECK-TEXT-NEXT: (i32.const 1) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $unreachable-if-toplevel (type $5) (result i32) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 3) - ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 2) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (return + ;; CHECK-BIN-NEXT: (i32.const 1) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $unreachable-if-toplevel (result i32) (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 1)) + ) ) ) ;; CHECK-TEXT: (func $unreachable-loop (type $5) (result i32) @@ -1648,68 +1708,102 @@ ;; CHECK-TEXT: (func $unreachable-ifs (type $FUNCSIG$v) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $unreachable-ifs (type $FUNCSIG$v) ;; CHECK-BIN-NEXT: (unreachable) ;; CHECK-BIN-NEXT: ) (func $unreachable-ifs - (if (unreachable) (nop)) - (if (unreachable) (unreachable)) - (if (unreachable) (nop) (nop)) - (if (unreachable) (unreachable) (nop)) - (if (unreachable) (nop) (unreachable)) - (if (unreachable) (unreachable) (unreachable)) + (if (unreachable) (then (nop))) + (if (unreachable) (then (unreachable))) + (if (unreachable) (then (nop) )(else (nop))) + (if (unreachable) (then (unreachable) )(else (nop))) + (if (unreachable) (then (nop) )(else (unreachable))) + (if (unreachable) (then (unreachable) )(else (unreachable))) ;; - (if (i32.const 1) (unreachable) (nop)) - (if (i32.const 1) (nop) (unreachable)) - (if (i32.const 1) (unreachable) (unreachable)) + (if (i32.const 1) (then (unreachable) )(else (nop))) + (if (i32.const 1) (then (nop) )(else (unreachable))) + (if (i32.const 1) (then (unreachable) )(else (unreachable))) ) ;; CHECK-TEXT: (func $unreachable-if-arm (type $FUNCSIG$v) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: (block + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (i32.const 1) @@ -1720,20 +1814,28 @@ ;; CHECK-BIN: (func $unreachable-if-arm (type $FUNCSIG$v) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (nop) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (nop) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $unreachable-if-arm (if (i32.const 1) - (block - (nop) + (then + (block + (nop) + ) ) - (block - (unreachable) - (drop - (i32.const 1) + (else + (block + (unreachable) + (drop + (i32.const 1) + ) ) ) ) @@ -1800,8 +1902,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (if @@ -1811,8 +1915,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) @@ -1829,8 +1935,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 1.2) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (if @@ -1838,8 +1946,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) ;; CHECK-BIN-NODEBUG-NEXT: (f64.const 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const -3.4) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (if @@ -1847,8 +1957,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $4) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (f64.const 5.6) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (if @@ -1856,8 +1968,10 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (br $label$1 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) @@ -2229,11 +2343,15 @@ ;; CHECK-BIN-NODEBUG: (func $29 (type $0) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) -;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -2241,11 +2359,15 @@ ;; CHECK-BIN-NODEBUG: (func $30 (type $0) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 3) -;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 2) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (return +;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -2291,7 +2413,11 @@ ;; CHECK-BIN-NODEBUG: (func $36 (type $1) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (nop) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (nop) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/unreachable-code.wast b/test/lit/basic/unreachable-code.wast index 16ec691a56e..0dfb00c4022 100644 --- a/test/lit/basic/unreachable-code.wast +++ b/test/lit/basic/unreachable-code.wast @@ -15,7 +15,9 @@ ;; CHECK-TEXT: (func $a (type $0) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $0 (func)) @@ -23,52 +25,74 @@ ;; CHECK-BIN: (func $a (type $0) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $a (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK-TEXT: (func $b (type $0) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $b (type $0) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $b (if (i32.const 1) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ;; CHECK-TEXT: (func $a-block (type $0) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $a-block (type $0) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $a-block (block (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) ) ) @@ -76,22 +100,34 @@ ;; CHECK-TEXT: (func $b-block (type $0) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $b-block (type $0) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $b-block (block (if (i32.const 1) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -100,7 +136,9 @@ ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) @@ -108,14 +146,18 @@ ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) (func $a-prepost (nop) (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) (nop) ) @@ -124,8 +166,12 @@ ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (nop) ;; CHECK-TEXT-NEXT: ) @@ -133,15 +179,23 @@ ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $b-prepost (nop) (if (i32.const 1) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) (nop) ) @@ -151,7 +205,9 @@ ;; CHECK-TEXT-NEXT: (block ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (nop) @@ -160,7 +216,9 @@ ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) @@ -168,7 +226,9 @@ (nop) (block (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) ) (nop) @@ -179,8 +239,12 @@ ;; CHECK-TEXT-NEXT: (block ;; CHECK-TEXT-NEXT: (if ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (nop) @@ -189,16 +253,24 @@ ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: (if ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: (then + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $b-block-prepost (nop) (block (if (i32.const 1) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) (nop) @@ -272,30 +344,42 @@ ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $1 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $2 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $3 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -303,7 +387,9 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -312,8 +398,12 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -321,7 +411,9 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -330,8 +422,12 @@ ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: (if ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: (then +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/untaken-br_if.wast b/test/lit/basic/untaken-br_if.wast index 23063d79623..bf2ad1ce3db 100644 --- a/test/lit/basic/untaken-br_if.wast +++ b/test/lit/basic/untaken-br_if.wast @@ -15,11 +15,15 @@ ;; CHECK-TEXT: (func $binaryify-untaken-br_if (type $0) (result f32) ;; CHECK-TEXT-NEXT: (if (result f32) ;; CHECK-TEXT-NEXT: (i32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: (block $label$1 (result f32) - ;; CHECK-TEXT-NEXT: (br_if $label$1 - ;; CHECK-TEXT-NEXT: (f32.const 1) - ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: (then + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (else + ;; CHECK-TEXT-NEXT: (block $label$1 (result f32) + ;; CHECK-TEXT-NEXT: (br_if $label$1 + ;; CHECK-TEXT-NEXT: (f32.const 1) + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -29,23 +33,31 @@ ;; CHECK-BIN: (func $binaryify-untaken-br_if (type $0) (result f32) ;; CHECK-BIN-NEXT: (if (result f32) ;; CHECK-BIN-NEXT: (i32.const 1) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: (block $label$3 (result f32) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (f32.const 1) - ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (then ;; CHECK-BIN-NEXT: (unreachable) ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (else + ;; CHECK-BIN-NEXT: (block $label$3 (result f32) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (f32.const 1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (unreachable) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $binaryify-untaken-br_if (result f32) (if (result f32) (i32.const 1) - (unreachable) - (block $label$1 (result f32) - (br_if $label$1 - (f32.const 1) - (unreachable) + (then + (unreachable) + ) + (else + (block $label$1 (result f32) + (br_if $label$1 + (f32.const 1) + (unreachable) + ) ) ) ) @@ -56,12 +68,16 @@ ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (if (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result f32) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (f32.const 1) -;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (then ;; CHECK-BIN-NODEBUG-NEXT: (unreachable) ;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (else +;; CHECK-BIN-NODEBUG-NEXT: (block $label$3 (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (f32.const 1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (unreachable) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/if-then-else.wast b/test/lit/if-then-else.wast index 9d457bef1ec..9d13cea9226 100644 --- a/test/lit/if-then-else.wast +++ b/test/lit/if-then-else.wast @@ -6,18 +6,22 @@ ;; CHECK: (func $test (param $0 i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return diff --git a/test/lit/multivalue.wast b/test/lit/multivalue.wast index 77941f529aa..e3de5da1bf4 100644 --- a/test/lit/multivalue.wast +++ b/test/lit/multivalue.wast @@ -473,15 +473,19 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (if (type $2) (result i32 i64 externref) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (tuple.make 3 - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: (i64.const 42) - ;; CHECK-NEXT: (ref.null noextern) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (tuple.make 3 + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i64.const 42) + ;; CHECK-NEXT: (ref.null noextern) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.make 3 - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: (i64.const 42) - ;; CHECK-NEXT: (ref.null noextern) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (tuple.make 3 + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i64.const 42) + ;; CHECK-NEXT: (ref.null noextern) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -500,15 +504,19 @@ (func $mv-if (result i32 i64 externref) (if (result i32 i64 externref) (i32.const 1) - (tuple.make 3 - (i32.const 42) - (i64.const 42) - (ref.null extern) + (then + (tuple.make 3 + (i32.const 42) + (i64.const 42) + (ref.null extern) + ) ) - (tuple.make 3 - (i32.const 42) - (i64.const 42) - (ref.null extern) + (else + (tuple.make 3 + (i32.const 42) + (i64.const 42) + (ref.null extern) + ) ) ) ) diff --git a/test/lit/non-nullable-locals.wast b/test/lit/non-nullable-locals.wast index 04bc5df1adc..21c12d4ad76 100644 --- a/test/lit/non-nullable-locals.wast +++ b/test/lit/non-nullable-locals.wast @@ -123,11 +123,15 @@ ;; CHECK-NEXT: (ref.func $helper) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -140,11 +144,15 @@ (ref.func $helper) ) ) - (drop - (local.get $x) + (then + (drop + (local.get $x) + ) ) - (drop - (local.get $x) + (else + (drop + (local.get $x) + ) ) ) ) diff --git a/test/lit/passes/O.wast b/test/lit/passes/O.wast index ce2c8521155..7affbb8b7c9 100644 --- a/test/lit/passes/O.wast +++ b/test/lit/passes/O.wast @@ -26,8 +26,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $ret) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 999) @@ -36,9 +38,11 @@ (block $out (result i32) (drop (call $ret)) (if (call $ret) - (return + (then (return - (i32.const 1) + (return + (i32.const 1) + ) ) ) ) @@ -55,8 +59,12 @@ (block $label$1 (if (i32.const 0) - (br $label$1) - (unreachable) + (then + (br $label$1) + ) + (else + (unreachable) + ) ) ) ) @@ -83,16 +91,22 @@ (local.get $0) (i32.const -1073741824) ) - (local.set $0 - (i32.const -1073741824) - ) - (if - (i32.gt_s - (local.get $0) - (i32.const 1073741823) - ) + (then (local.set $0 - (i32.const 1073741823) + (i32.const -1073741824) + ) + ) + (else + (if + (i32.gt_s + (local.get $0) + (i32.const 1073741823) + ) + (then + (local.set $0 + (i32.const 1073741823) + ) + ) ) ) ) @@ -108,8 +122,10 @@ (func $end-if-else (export "end-if-else") (param $x i32) (result i32) (if (local.get $x) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) ) (local.get $x) @@ -117,15 +133,21 @@ ;; CHECK: (func $end-if-else-call (; has Stack IR ;) (param $0 i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (call $ret) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $ret) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $end-if-else-call (export "end-if-else-call") (param $x i32) (result i32) (if (local.get $x) - (local.set $x - (call $ret) + (then + (local.set $x + (call $ret) + ) ) ) (local.get $x) diff --git a/test/lit/passes/O3_inline-functions-with-loops_flexible-inline-max-function-size=30.wast b/test/lit/passes/O3_inline-functions-with-loops_flexible-inline-max-function-size=30.wast index e0045579dd6..87dec51e350 100644 --- a/test/lit/passes/O3_inline-functions-with-loops_flexible-inline-max-function-size=30.wast +++ b/test/lit/passes/O3_inline-functions-with-loops_flexible-inline-max-function-size=30.wast @@ -28,8 +28,10 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.add @@ -81,7 +83,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $0) @@ -134,7 +136,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $0) diff --git a/test/lit/passes/O3_inlining.wast b/test/lit/passes/O3_inlining.wast index a16a8b8d45d..14f54df5c2a 100644 --- a/test/lit/passes/O3_inlining.wast +++ b/test/lit/passes/O3_inlining.wast @@ -16,7 +16,9 @@ (func $0 (if (global.get $global$1) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$1 (i32.const 0) @@ -29,8 +31,12 @@ (i32.load16_u offset=3 (i32.const 0) ) - (i32.const 1) - (i32.const 0) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) ) ) (unreachable) @@ -41,7 +47,9 @@ ;; CHECK: (func $1 (param $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $global$1 ;; CHECK-NEXT: (i32.const 0) @@ -52,7 +60,9 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $1 (param $var$0 i32) diff --git a/test/lit/passes/O4_disable-bulk-memory.wast b/test/lit/passes/O4_disable-bulk-memory.wast index 051f62456b2..63bb0ea406c 100644 --- a/test/lit/passes/O4_disable-bulk-memory.wast +++ b/test/lit/passes/O4_disable-bulk-memory.wast @@ -20,14 +20,18 @@ ) (i32.const 127) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$0 (i32.const -1) ) (if (global.get $global$0) - (unreachable) + (then + (unreachable) + ) ) (unreachable) ) @@ -162,30 +166,34 @@ (i32.const 2) ) ) - (block (result i32) - (local.set $3 - (local.get $2) - ) - (local.set $4 - (local.get $1) - ) - (local.set $5 - (i32.const 0) - ) - (i32.load offset=8 - (i32.add + (then + (block (result i32) + (local.set $3 + (local.get $2) + ) + (local.set $4 + (local.get $1) + ) + (local.set $5 + (i32.const 0) + ) + (i32.load offset=8 (i32.add - (local.get $3) - (i32.shl - (local.get $4) - (i32.const 2) + (i32.add + (local.get $3) + (i32.shl + (local.get $4) + (i32.const 2) + ) ) + (local.get $5) ) - (local.get $5) ) ) ) - (unreachable) + (else + (unreachable) + ) ) ) (func $assembly/index/Body#offsetMomentum (; 5 ;) (type $2) (param $0 i32) (param $1 f64) (param $2 f64) (param $3 f64) (result i32) @@ -227,7 +235,9 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 1073741824) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.gt_u @@ -259,42 +269,48 @@ ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (memory.grow - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (memory.grow + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 65535) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: (i32.const -65536) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -65536) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (memory.grow - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (memory.grow + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -315,7 +331,9 @@ (local.get $0) (i32.const 1073741824) ) - (unreachable) + (then + (unreachable) + ) ) (local.set $1 (global.get $global$1) @@ -357,54 +375,60 @@ (i32.const 16) ) ) - (block - (local.set $2 - (i32.shr_u - (i32.and - (i32.add - (i32.sub - (local.get $4) - (local.get $1) + (then + (block + (local.set $2 + (i32.shr_u + (i32.and + (i32.add + (i32.sub + (local.get $4) + (local.get $1) + ) + (i32.const 65535) + ) + (i32.xor + (i32.const 65535) + (i32.const -1) ) - (i32.const 65535) - ) - (i32.xor - (i32.const 65535) - (i32.const -1) ) + (i32.const 16) ) - (i32.const 16) ) - ) - (local.set $3 - (select - (local.tee $3 - (local.get $5) - ) - (local.tee $6 - (local.get $2) - ) - (i32.gt_s - (local.get $3) - (local.get $6) - ) - ) - ) - (if - (i32.lt_s - (memory.grow - (local.get $3) + (local.set $3 + (select + (local.tee $3 + (local.get $5) + ) + (local.tee $6 + (local.get $2) + ) + (i32.gt_s + (local.get $3) + (local.get $6) + ) ) - (i32.const 0) ) (if (i32.lt_s (memory.grow - (local.get $2) + (local.get $3) ) (i32.const 0) ) - (unreachable) + (then + (if + (i32.lt_s + (memory.grow + (local.get $2) + ) + (i32.const 0) + ) + (then + (unreachable) + ) + ) + ) ) ) ) @@ -531,9 +555,11 @@ (i32.eqz (local.get $0) ) - (local.set $0 - (call $~lib/memory/memory.allocate - (i32.const 4) + (then + (local.set $0 + (call $~lib/memory/memory.allocate + (i32.const 4) + ) ) ) ) @@ -584,9 +610,11 @@ (i32.eqz (local.get $0) ) - (local.set $0 - (call $~lib/memory/memory.allocate - (i32.const 56) + (then + (local.set $0 + (call $~lib/memory/memory.allocate + (i32.const 56) + ) ) ) ) @@ -755,14 +783,16 @@ (i32.const 1073741816) ) ) - (block - (call $~lib/env/abort - (i32.const 0) - (i32.const 40) - (i32.const 26) - (i32.const 2) + (then + (block + (call $~lib/env/abort + (i32.const 0) + (i32.const 40) + (i32.const 26) + (i32.const 2) + ) + (unreachable) ) - (unreachable) ) ) (local.set $1 @@ -793,7 +823,9 @@ (i32.eqz (local.get $2) ) - (return) + (then + (return) + ) ) (i32.store8 (local.get $0) @@ -814,7 +846,9 @@ (local.get $2) (i32.const 2) ) - (return) + (then + (return) + ) ) (i32.store8 (i32.add @@ -855,7 +889,9 @@ (local.get $2) (i32.const 6) ) - (return) + (then + (return) + ) ) (i32.store8 (i32.add @@ -879,7 +915,9 @@ (local.get $2) (i32.const 8) ) - (return) + (then + (return) + ) ) (local.set $3 (i32.and @@ -939,7 +977,9 @@ (local.get $2) (i32.const 8) ) - (return) + (then + (return) + ) ) (i32.store (i32.add @@ -980,7 +1020,9 @@ (local.get $2) (i32.const 24) ) - (return) + (then + (return) + ) ) (i32.store (i32.add @@ -1091,47 +1133,49 @@ (local.get $2) (i32.const 32) ) - (block - (block $label$10 - (i64.store - (local.get $0) - (local.get $5) - ) - (i64.store - (i32.add + (then + (block + (block $label$10 + (i64.store (local.get $0) - (i32.const 8) + (local.get $5) ) - (local.get $5) - ) - (i64.store - (i32.add - (local.get $0) - (i32.const 16) + (i64.store + (i32.add + (local.get $0) + (i32.const 8) + ) + (local.get $5) ) - (local.get $5) - ) - (i64.store - (i32.add - (local.get $0) - (i32.const 24) + (i64.store + (i32.add + (local.get $0) + (i32.const 16) + ) + (local.get $5) ) - (local.get $5) - ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 32) + (i64.store + (i32.add + (local.get $0) + (i32.const 24) + ) + (local.get $5) ) - ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 32) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 32) + ) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 32) + ) ) ) + (br $label$8) ) - (br $label$8) ) ) ) @@ -1148,14 +1192,16 @@ (local.get $1) (i32.const 268435454) ) - (block - (call $~lib/env/abort - (i32.const 0) - (i32.const 8) - (i32.const 45) - (i32.const 39) + (then + (block + (call $~lib/env/abort + (i32.const 0) + (i32.const 8) + (i32.const 45) + (i32.const 39) + ) + (unreachable) ) - (unreachable) ) ) (local.set $2 @@ -1175,9 +1221,11 @@ (i32.eqz (local.get $0) ) - (local.set $0 - (call $~lib/memory/memory.allocate - (i32.const 8) + (then + (local.set $0 + (call $~lib/memory/memory.allocate + (i32.const 8) + ) ) ) ) @@ -1514,7 +1562,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i64.const 0) @@ -1668,7 +1716,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (f64.load offset=48 ;; CHECK-NEXT: (local.tee $1 @@ -1742,10 +1790,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load offset=8 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.load offset=8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (f64.div @@ -1854,7 +1906,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (local.get $13) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $14 ;; CHECK-NEXT: (f64.load ;; CHECK-NEXT: (local.tee $0 @@ -1914,7 +1966,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (local.get $13) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (f64.mul ;; CHECK-NEXT: (local.get $17) @@ -2701,7 +2753,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (f64.load ;; CHECK-NEXT: (local.tee $1 @@ -2784,7 +2836,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (f64.sub ;; CHECK-NEXT: (local.get $7) @@ -2946,32 +2998,40 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load offset=8 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.load offset=8 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $assembly/index/getBody (; 25 ;) (type $3) (param $0 i32) (result i32) @@ -2994,11 +3054,15 @@ ) ) ) - (call $~lib/array/Array#__get - (local.get $1) - (local.get $0) + (then + (call $~lib/array/Array#__get + (local.get $1) + (local.get $0) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) ;; CHECK: (func $start (; has Stack IR ;) diff --git a/test/lit/passes/Oz.wast b/test/lit/passes/Oz.wast index 85a722737a4..42295ec2308 100644 --- a/test/lit/passes/Oz.wast +++ b/test/lit/passes/Oz.wast @@ -166,8 +166,10 @@ ;; CHECK: (func $11 (type $1) (; has Stack IR ;) (param $0 i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -175,9 +177,13 @@ (func $11 (export "eliminate-redundant-checks-1") (param $0 i32) (result i32) (if (local.get $0) - (if - (local.get $0) - (return (local.get $0)) + (then + (if + (local.get $0) + (then + (return (local.get $0)) + ) + ) ) ) (i32.const 0) @@ -189,15 +195,19 @@ (i32.const 0) (local.get $0) ) - (return (local.get $0)) + (then + (return (local.get $0)) + ) ) (i32.const 0) ) ;; CHECK: (func $12 (type $0) (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -205,9 +215,13 @@ (func $12 (export "eliminate-redundant-checks-2") (param $0 i32) (param $1 i32) (result i32) (if (local.tee $1 (local.get $0)) - (if - (local.get $1) - (return (local.get $1)) + (then + (if + (local.get $1) + (then + (return (local.get $1)) + ) + ) ) ) (i32.const 0) @@ -219,7 +233,9 @@ (i32.const 0) (local.get $1) ) - (return (local.get $1)) + (then + (return (local.get $1)) + ) ) (i32.const 0) ) @@ -230,8 +246,10 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -243,7 +261,9 @@ (i32.const 0) (local.tee $1 (local.get $0)) ) - (return (local.get $1)) + (then + (return (local.get $1)) + ) ) (i32.const 0) ) @@ -255,8 +275,10 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -268,7 +290,9 @@ (local.get $1) (local.tee $1 (local.get $0)) ) - (return (local.get $1)) + (then + (return (local.get $1)) + ) ) (i32.const 0) ) diff --git a/test/lit/passes/asyncify-wasm64.wast b/test/lit/passes/asyncify-wasm64.wast index 8349eedf268..07d1942e4af 100644 --- a/test/lit/passes/asyncify-wasm64.wast +++ b/test/lit/passes/asyncify-wasm64.wast @@ -55,7 +55,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -91,7 +91,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -116,7 +116,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -145,15 +145,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -163,7 +165,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -254,7 +256,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -290,7 +292,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -315,7 +317,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -344,15 +346,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -362,7 +366,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -451,7 +455,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -487,7 +491,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -518,15 +522,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -536,7 +542,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -557,15 +563,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -575,7 +583,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $live1) ;; CHECK-NEXT: ) @@ -652,7 +660,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -683,7 +691,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -711,28 +719,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -741,7 +753,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -797,7 +809,9 @@ ;; CHECK-NEXT: ) (func $liveness4 (param $live0 i32) (param $dead0 i32) (if (i32.const 0) - (call $import) + (then + (call $import) + ) ) (drop (local.get $live0)) ) @@ -811,7 +825,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -822,7 +838,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -847,7 +863,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -865,28 +881,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -895,7 +915,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $dead0 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -937,7 +957,9 @@ (func $liveness5 (param $dead0 i32) (drop (local.get $dead0)) (if (i32.const 0) - (call $import) ;; live before and after call, but not during + (then + (call $import) ;; live before and after call, but not during + ) ) (local.set $dead0 (i32.const 1)) (drop (local.get $dead0)) @@ -953,7 +975,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -984,7 +1006,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -1009,8 +1031,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $live) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $live) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1024,7 +1048,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -1033,8 +1057,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1098,7 +1124,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -1134,7 +1160,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i64.add @@ -1159,7 +1185,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -1180,7 +1206,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call_indirect (type $f) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) @@ -1190,8 +1216,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1264,7 +1292,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1281,7 +1311,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1301,7 +1333,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1318,7 +1352,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast b/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast index 35692883e76..1a8f6dfef5e 100644 --- a/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast +++ b/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast @@ -48,7 +48,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store $asyncify_memory ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -84,7 +84,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store $asyncify_memory ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -109,7 +109,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -138,15 +138,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -156,7 +158,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -248,7 +250,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -265,7 +269,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -285,7 +291,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -302,7 +310,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify.wast b/test/lit/passes/asyncify.wast index 236f29fa56d..968cc571673 100644 --- a/test/lit/passes/asyncify.wast +++ b/test/lit/passes/asyncify.wast @@ -54,7 +54,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -90,7 +90,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -115,7 +115,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -144,15 +144,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -162,7 +164,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -253,7 +255,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -289,7 +291,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -314,7 +316,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -343,15 +345,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -361,7 +365,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -450,7 +454,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -486,7 +490,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -517,15 +521,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -535,7 +541,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -556,15 +562,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -574,7 +582,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $live1) ;; CHECK-NEXT: ) @@ -651,7 +659,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -682,7 +690,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -710,28 +718,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -740,7 +752,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -796,7 +808,9 @@ ;; CHECK-NEXT: ) (func $liveness4 (param $live0 i32) (param $dead0 i32) (if (i32.const 0) - (call $import) + (then + (call $import) + ) ) (drop (local.get $live0)) ) @@ -810,7 +824,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -821,7 +837,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -846,7 +862,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -864,28 +880,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -894,7 +914,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $dead0 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -936,7 +956,9 @@ (func $liveness5 (param $dead0 i32) (drop (local.get $dead0)) (if (i32.const 0) - (call $import) ;; live before and after call, but not during + (then + (call $import) ;; live before and after call, but not during + ) ) (local.set $dead0 (i32.const 1)) (drop (local.get $dead0)) @@ -952,7 +974,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -983,7 +1005,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1008,8 +1030,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $live) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $live) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1023,7 +1047,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -1032,8 +1056,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1097,7 +1123,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1133,7 +1159,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1158,7 +1184,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -1179,7 +1205,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call_indirect (type $f) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) @@ -1189,8 +1215,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1263,7 +1291,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1280,7 +1310,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1300,7 +1332,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1317,7 +1351,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_enable-multivalue.wast b/test/lit/passes/asyncify_enable-multivalue.wast index 04b0a470788..69ae2efc6d0 100644 --- a/test/lit/passes/asyncify_enable-multivalue.wast +++ b/test/lit/passes/asyncify_enable-multivalue.wast @@ -41,7 +41,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $sleeping) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $sleeping ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -49,7 +49,7 @@ ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (global.set $sleeping ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -60,14 +60,18 @@ (func $do_sleep (if (i32.eqz (global.get $sleeping)) - (block - (global.set $sleeping (i32.const 1)) - ;; we should set up the data at address 4 around here - (call $asyncify_start_unwind (i32.const 4)) + (then + (block + (global.set $sleeping (i32.const 1)) + ;; we should set up the data at address 4 around here + (call $asyncify_start_unwind (i32.const 4)) + ) ) - (block - (global.set $sleeping (i32.const 0)) - (call $asyncify_stop_rewind) + (else + (block + (global.set $sleeping (i32.const 0)) + (call $asyncify_stop_rewind) + ) ) ) ) @@ -80,7 +84,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -91,7 +97,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -116,7 +122,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -129,15 +137,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $do_sleep) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -147,7 +157,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -192,7 +204,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -203,7 +217,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -233,15 +247,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $work) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -318,7 +334,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -335,7 +353,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -355,7 +375,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -372,7 +394,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -423,7 +447,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -434,7 +460,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -464,15 +490,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -520,7 +548,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -551,7 +579,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -583,7 +611,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -592,11 +620,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -606,7 +638,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -684,7 +716,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -715,7 +747,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -746,7 +778,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -755,11 +787,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -769,8 +805,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -850,7 +888,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -881,7 +919,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -907,36 +945,38 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $l - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $l + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $y - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -951,15 +991,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -969,7 +1011,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) @@ -1050,7 +1092,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1061,7 +1105,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1086,8 +1130,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1098,28 +1144,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1150,7 +1200,9 @@ ;; CHECK-NEXT: ) (func $calls-import2-if (param $x i32) (if (local.get $x) - (call $import) + (then + (call $import) + ) ) ) ;; CHECK: (func $calls-import2-if-else (param $x i32) @@ -1165,7 +1217,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1196,7 +1248,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1221,8 +1273,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -1231,8 +1285,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1243,30 +1299,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1280,30 +1340,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1354,8 +1418,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else (param $x i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) ) ;; CHECK: (func $calls-import2-if-else-oneside (param $x i32) (result i32) @@ -1370,7 +1438,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1381,7 +1451,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1408,8 +1478,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -1418,8 +1490,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1430,13 +1504,17 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1450,30 +1528,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1484,8 +1566,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1518,8 +1602,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside (param $x i32) (result i32) (if (local.get $x) - (return (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (return (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) (return (i32.const 3)) ) @@ -1537,7 +1625,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1568,7 +1656,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1595,8 +1683,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -1605,8 +1695,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1617,30 +1709,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1654,13 +1750,17 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1671,8 +1771,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1724,8 +1826,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside2 (param $x i32) (result i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (return (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (return (i32.const 2)) + ) ) (return (i32.const 3)) ) @@ -1742,7 +1848,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1778,7 +1884,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1809,7 +1915,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (call $import-mv) ;; CHECK-NEXT: ) @@ -1818,11 +1924,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1832,8 +1942,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1905,7 +2017,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1936,7 +2048,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1967,7 +2079,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import3 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -1976,8 +2088,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1987,7 +2101,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -2079,7 +2193,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -2110,7 +2224,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -2141,7 +2255,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -2150,11 +2264,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2164,8 +2282,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2227,7 +2347,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -2238,7 +2360,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -2263,7 +2385,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -2276,15 +2400,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2294,7 +2420,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -2307,15 +2435,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2363,7 +2493,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -2374,7 +2506,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -2399,7 +2531,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -2412,15 +2546,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import-deep) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2430,7 +2566,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -2443,15 +2581,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2501,7 +2641,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -2512,7 +2654,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -2542,15 +2684,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2600,7 +2744,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2617,7 +2763,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2637,7 +2785,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2654,7 +2804,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2701,7 +2853,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2718,7 +2872,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2738,7 +2894,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2755,7 +2913,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind.wast b/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind.wast index 59817d3be8b..dcb4ead34f3 100644 --- a/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind.wast +++ b/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind.wast @@ -38,7 +38,9 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -46,7 +48,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -76,12 +78,14 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -126,7 +130,7 @@ ;; CHECK-NEXT: (local $9 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -154,7 +158,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -186,17 +190,21 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -206,7 +214,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -281,7 +289,7 @@ ;; CHECK-NEXT: (local $5 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -309,7 +317,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -340,17 +348,21 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -360,8 +372,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -438,7 +452,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -455,7 +471,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -475,7 +493,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -492,7 +512,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind_O.wast b/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind_O.wast index b9ee2146368..7d53b6cbb9d 100644 --- a/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind_O.wast +++ b/test/lit/passes/asyncify_mod-asyncify-always-and-only-unwind_O.wast @@ -89,7 +89,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -106,7 +108,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -126,7 +130,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_mod-asyncify-never-unwind.wast b/test/lit/passes/asyncify_mod-asyncify-never-unwind.wast index 6e0e5885c4e..1ac962eb91e 100644 --- a/test/lit/passes/asyncify_mod-asyncify-never-unwind.wast +++ b/test/lit/passes/asyncify_mod-asyncify-never-unwind.wast @@ -41,7 +41,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -52,7 +54,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -82,12 +84,14 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -135,7 +139,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -166,7 +170,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -198,17 +202,21 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -218,7 +226,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -296,7 +304,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -327,7 +335,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -358,17 +366,21 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -378,8 +390,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -456,7 +470,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -473,7 +489,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -493,7 +511,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -510,7 +530,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_mod-asyncify-never-unwind_O.wast b/test/lit/passes/asyncify_mod-asyncify-never-unwind_O.wast index ec16b6d9c2e..112d750ba37 100644 --- a/test/lit/passes/asyncify_mod-asyncify-never-unwind_O.wast +++ b/test/lit/passes/asyncify_mod-asyncify-never-unwind_O.wast @@ -51,7 +51,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -67,11 +67,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $calls-import @@ -105,7 +109,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -122,7 +128,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -142,7 +150,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_optimize-level=1.wast b/test/lit/passes/asyncify_optimize-level=1.wast index d745c4bc49b..0eefc7ffa82 100644 --- a/test/lit/passes/asyncify_optimize-level=1.wast +++ b/test/lit/passes/asyncify_optimize-level=1.wast @@ -50,7 +50,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -66,11 +66,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -113,7 +115,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -145,7 +147,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -161,11 +163,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -187,8 +191,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) @@ -246,7 +252,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -262,11 +268,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -321,7 +329,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -347,7 +355,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -370,15 +378,17 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $l - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $l + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -393,7 +403,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -410,8 +420,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) @@ -487,7 +499,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -503,12 +515,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -542,7 +556,9 @@ ;; CHECK-NEXT: ) (func $calls-import2-if (param $x i32) (if (local.get $x) - (call $import) + (then + (call $import) + ) ) ) ;; CHECK: (func $calls-import2-if-else (param $0 i32) @@ -560,7 +576,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -576,7 +592,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (global.get $__asyncify_state) @@ -594,7 +612,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -623,7 +641,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import3 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -648,26 +666,28 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_if $__asyncify_unwind + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_if $__asyncify_unwind ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -710,8 +730,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else (param $x i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) ) ;; CHECK: (func $calls-import2-if-else-oneside (param $0 i32) (result i32) @@ -724,7 +748,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -761,8 +785,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -785,7 +811,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import3 ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -804,8 +830,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) @@ -830,8 +858,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside (param $x i32) (result i32) (if (local.get $x) - (return (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (return (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) (return (i32.const 3)) ) @@ -850,7 +882,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -866,7 +898,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (global.get $__asyncify_state) @@ -888,7 +922,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -904,12 +938,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import3 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -939,16 +975,20 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) @@ -988,8 +1028,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside2 (param $x i32) (result i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (return (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (return (i32.const 2)) + ) ) (return (i32.const 3)) ) @@ -1000,7 +1044,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1026,7 +1070,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1055,7 +1099,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import3 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -1074,11 +1118,13 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1138,7 +1184,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1164,7 +1210,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1193,7 +1239,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -1271,7 +1317,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1294,7 +1340,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1305,7 +1353,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -1322,7 +1370,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1334,7 +1384,7 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -1385,7 +1435,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1408,7 +1458,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1419,7 +1471,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import-deep) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -1436,7 +1488,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1448,7 +1502,7 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -1507,7 +1561,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.sub @@ -1523,11 +1577,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $__asyncify_unwind @@ -1580,7 +1636,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1597,7 +1655,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1617,7 +1677,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1634,7 +1696,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo.wast b/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo.wast index 3c67158d3af..6a002645923 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo.wast @@ -37,7 +37,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (block $__asyncify_unwind @@ -48,7 +50,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -72,7 +74,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return) @@ -130,7 +134,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -147,7 +153,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -167,7 +175,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -184,7 +194,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo_pass-arg=asyncify-ignore-indirect.wast b/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo_pass-arg=asyncify-ignore-indirect.wast index adaea8343fd..217feb3581a 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo_pass-arg=asyncify-ignore-indirect.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-addlist@foo_pass-arg=asyncify-ignore-indirect.wast @@ -43,7 +43,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -54,7 +56,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -79,7 +81,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -92,7 +96,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call_indirect (type $t) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -101,8 +105,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -169,7 +175,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -186,7 +194,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -206,7 +216,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -223,7 +235,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast b/test/lit/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast index b7edc038cd7..e86fe988e41 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-asserts_pass-arg=asyncify-onlylist@waka.wast @@ -55,7 +55,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -78,7 +80,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -105,7 +109,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -132,7 +138,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -159,7 +167,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -176,7 +186,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -196,7 +208,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -213,7 +227,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-blacklist@foo,bar.wast b/test/lit/passes/asyncify_pass-arg=asyncify-blacklist@foo,bar.wast index dcc86471357..d89ff3a1a5b 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-blacklist@foo,bar.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-blacklist@foo,bar.wast @@ -50,7 +50,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -61,7 +63,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -91,15 +93,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -145,7 +149,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -156,7 +162,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -186,15 +192,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $baz) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -244,7 +252,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -261,7 +271,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -281,7 +293,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -298,7 +312,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-ignore-imports.wast b/test/lit/passes/asyncify_pass-arg=asyncify-ignore-imports.wast index 05fccc63fef..dc99a09d037 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-ignore-imports.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-ignore-imports.wast @@ -55,18 +55,26 @@ ;; CHECK: (func $calls-import2-if-else (param $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $calls-import2-if-else (param $x i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) ) ;; CHECK: (func $calls-indirect (param $x i32) @@ -80,7 +88,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -111,7 +119,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -136,8 +144,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -151,7 +161,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call_indirect (type $f) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -160,8 +170,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -233,7 +245,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -250,7 +264,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -270,7 +286,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -287,7 +305,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-ignore-indirect.wast b/test/lit/passes/asyncify_pass-arg=asyncify-ignore-indirect.wast index 0811e2a9e3e..519c6ea2f60 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-ignore-indirect.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-ignore-indirect.wast @@ -46,7 +46,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -57,7 +59,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -87,15 +89,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -139,7 +143,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -170,7 +174,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -201,7 +205,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -210,11 +214,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -224,8 +232,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -287,7 +297,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -318,7 +328,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -343,8 +353,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -353,8 +365,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -365,30 +379,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -402,30 +420,34 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -476,8 +498,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else (param $x i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) ) ;; CHECK: (func $calls-indirect (param $x i32) @@ -508,7 +534,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -525,7 +553,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -545,7 +575,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -562,7 +594,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.wast b/test/lit/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.wast index fd214582efb..ba781e12a07 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.wast @@ -40,7 +40,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $sleeping) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $sleeping ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -48,7 +48,7 @@ ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (global.set $sleeping ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -59,14 +59,18 @@ (func $do_sleep (if (i32.eqz (global.get $sleeping)) - (block - (global.set $sleeping (i32.const 1)) - ;; we should set up the data at address 4 around here - (call $asyncify_start_unwind (i32.const 4)) + (then + (block + (global.set $sleeping (i32.const 1)) + ;; we should set up the data at address 4 around here + (call $asyncify_start_unwind (i32.const 4)) + ) ) - (block - (global.set $sleeping (i32.const 0)) - (call $asyncify_stop_rewind) + (else + (block + (global.set $sleeping (i32.const 0)) + (call $asyncify_stop_rewind) + ) ) ) ) @@ -79,7 +83,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -90,7 +96,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -115,7 +121,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -128,15 +136,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $do_sleep) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -146,7 +156,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $stuff) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -191,7 +203,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -202,7 +216,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -232,15 +246,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $work) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -314,7 +330,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -331,7 +349,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -351,7 +371,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -368,7 +390,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -415,7 +439,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -426,7 +452,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -456,15 +482,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -512,7 +540,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -543,7 +571,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -575,7 +603,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -584,11 +612,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -598,7 +630,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -676,7 +708,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -707,7 +739,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -738,7 +770,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -747,11 +779,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -761,8 +797,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -841,7 +879,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -872,7 +910,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -898,36 +936,38 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $l - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $l + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $y - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -942,15 +982,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -960,7 +1002,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) @@ -1040,7 +1082,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1051,7 +1095,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1076,8 +1120,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -1088,28 +1134,32 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1140,34 +1190,48 @@ ;; CHECK-NEXT: ) (func $calls-import2-if (param $x i32) (if (local.get $x) - (call $import) + (then + (call $import) + ) ) ) ;; CHECK: (func $calls-import2-if-else (param $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $calls-import2-if-else (param $x i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) ) ;; CHECK: (func $calls-import2-if-else-oneside (param $x i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return @@ -1176,19 +1240,27 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside (param $x i32) (result i32) (if (local.get $x) - (return (i32.const 1)) - (call $import3 (i32.const 2)) + (then + (return (i32.const 1)) + ) + (else + (call $import3 (i32.const 2)) + ) ) (return (i32.const 3)) ) ;; CHECK: (func $calls-import2-if-else-oneside2 (param $x i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $import3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return @@ -1197,8 +1269,12 @@ ;; CHECK-NEXT: ) (func $calls-import2-if-else-oneside2 (param $x i32) (result i32) (if (local.get $x) - (call $import3 (i32.const 1)) - (return (i32.const 2)) + (then + (call $import3 (i32.const 1)) + ) + (else + (return (i32.const 2)) + ) ) (return (i32.const 3)) ) @@ -1241,7 +1317,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1272,7 +1348,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1303,7 +1379,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call $import2) ;; CHECK-NEXT: ) @@ -1312,11 +1388,15 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1326,8 +1406,10 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $l - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1389,7 +1471,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1400,7 +1484,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1425,7 +1509,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1438,15 +1524,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1456,7 +1544,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1469,15 +1559,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1525,7 +1617,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1536,7 +1630,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1561,7 +1655,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring-deep) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1574,15 +1670,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import-deep) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1592,7 +1690,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $boring) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or @@ -1605,15 +1705,17 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1663,7 +1765,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -1674,7 +1778,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -1704,15 +1808,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1762,7 +1868,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1779,7 +1887,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1799,7 +1909,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1816,7 +1928,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast b/test/lit/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast index ba5c59cd1ec..d5dd3775aeb 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-onlylist@foo,bar.wast @@ -38,7 +38,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -49,7 +51,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -79,15 +81,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -127,7 +131,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -138,7 +144,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -168,15 +174,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -244,7 +252,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -261,7 +271,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -281,7 +293,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -298,7 +312,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-side-module.wast b/test/lit/passes/asyncify_pass-arg=asyncify-side-module.wast index 5afc9a83ba5..9dee0f8c011 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-side-module.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-side-module.wast @@ -43,7 +43,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -60,7 +62,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -80,7 +84,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -97,7 +103,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=asyncify-verbose.wast b/test/lit/passes/asyncify_pass-arg=asyncify-verbose.wast index 8e932d4943e..035c460597b 100644 --- a/test/lit/passes/asyncify_pass-arg=asyncify-verbose.wast +++ b/test/lit/passes/asyncify_pass-arg=asyncify-verbose.wast @@ -37,7 +37,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -48,7 +50,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -78,15 +80,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -126,7 +130,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -137,7 +143,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -167,15 +173,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $calls-import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -215,7 +223,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) @@ -226,7 +236,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -256,15 +266,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $calls-calls-import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -320,7 +332,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -337,7 +351,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -357,7 +373,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -374,7 +392,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast b/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast index e1f8178a0c1..7772d68f55b 100644 --- a/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast +++ b/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast @@ -58,7 +58,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store $asyncify_memory ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -94,7 +94,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store $asyncify_memory ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: (i32.add @@ -119,7 +119,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $dead0) ;; CHECK-NEXT: ) @@ -148,15 +148,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__asyncify_unwind - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -166,7 +168,7 @@ ;; CHECK-NEXT: (global.get $__asyncify_state) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $live0) ;; CHECK-NEXT: ) @@ -266,7 +268,7 @@ ;; SIZE-NEXT: (global.get $__asyncify_state) ;; SIZE-NEXT: (i32.const 2) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (then ;; SIZE-NEXT: (i32.store $asyncify_memory ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: (i32.add @@ -302,7 +304,7 @@ ;; SIZE-NEXT: (global.get $__asyncify_state) ;; SIZE-NEXT: (i32.const 2) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (then ;; SIZE-NEXT: (i32.store $asyncify_memory ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: (i32.add @@ -327,7 +329,7 @@ ;; SIZE-NEXT: (global.get $__asyncify_state) ;; SIZE-NEXT: (i32.const 0) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (then ;; SIZE-NEXT: (local.set $4 ;; SIZE-NEXT: (local.get $dead0) ;; SIZE-NEXT: ) @@ -356,15 +358,17 @@ ;; SIZE-NEXT: (i32.const 0) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (then ;; SIZE-NEXT: (call $import) ;; SIZE-NEXT: (if ;; SIZE-NEXT: (i32.eq ;; SIZE-NEXT: (global.get $__asyncify_state) ;; SIZE-NEXT: (i32.const 1) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (br $__asyncify_unwind - ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: (then + ;; SIZE-NEXT: (br $__asyncify_unwind + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) @@ -374,7 +378,7 @@ ;; SIZE-NEXT: (global.get $__asyncify_state) ;; SIZE-NEXT: (i32.const 0) ;; SIZE-NEXT: ) - ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (then ;; SIZE-NEXT: (local.set $6 ;; SIZE-NEXT: (local.get $live0) ;; SIZE-NEXT: ) @@ -466,7 +470,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -483,7 +489,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -503,7 +511,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -520,7 +530,9 @@ ;; CHECK-NEXT: (global.get $__asyncify_data) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -544,7 +556,9 @@ ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) -;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: (then +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) @@ -561,7 +575,9 @@ ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) -;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: (then +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) @@ -581,7 +597,9 @@ ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) -;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: (then +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) @@ -598,7 +616,9 @@ ;; SIZE-NEXT: (global.get $__asyncify_data) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) -;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: (then +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) ;; SIZE-NEXT: ) ;; SIZE-NEXT: ) diff --git a/test/lit/passes/catch-pop-fixup-eh.wast b/test/lit/passes/catch-pop-fixup-eh.wast index 685a0768536..5aba0f73df0 100644 --- a/test/lit/passes/catch-pop-fixup-eh.wast +++ b/test/lit/passes/catch-pop-fixup-eh.wast @@ -250,8 +250,12 @@ ;; CHECK-NEXT: (catch $e-i32 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (pop i32) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -287,8 +291,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $l0) diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index b61f2c6a681..7fb2a7f1391 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -417,8 +417,12 @@ ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: (if (result f32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (f32.const 42) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (f32.const 42) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -428,8 +432,12 @@ ;; Fall though a 42 via an if. (if (result f32) (local.get $x) - (unreachable) - (f32.const 42) + (then + (unreachable) + ) + (else + (f32.const 42) + ) ) ) ) diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast index 8af0d218743..f5ec6bc39ad 100644 --- a/test/lit/passes/coalesce-locals-gc.wast +++ b/test/lit/passes/coalesce-locals-gc.wast @@ -293,16 +293,20 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (tuple.make 2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (tuple.make 2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -311,25 +315,29 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (if (type $1) (result (ref any) i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (tuple.make 2 - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (tuple.extract 2 1 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 1 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.make 2 - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (tuple.extract 2 1 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (tuple.extract 2 1 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -369,16 +377,20 @@ (if (i32.const 0) ;; These two sets will remain. - (local.set $x - (tuple.make 2 - (local.get $any) - (i32.const 1) + (then + (local.set $x + (tuple.make 2 + (local.get $any) + (i32.const 1) + ) ) ) - (local.set $x - (tuple.make 2 - (local.get $any) - (i32.const 2) + (else + (local.set $x + (tuple.make 2 + (local.get $any) + (i32.const 2) + ) ) ) ) @@ -388,8 +400,12 @@ (if (result (ref any) i32) (i32.const 0) ;; These gets will be invalid, so the local will have to be made nullable. - (local.get $x) - (local.get $x) + (then + (local.get $x) + ) + (else + (local.get $x) + ) ) ) ) diff --git a/test/lit/passes/coalesce-locals-learning.wast b/test/lit/passes/coalesce-locals-learning.wast index b8871ddf52a..aa20e87c5a2 100644 --- a/test/lit/passes/coalesce-locals-learning.wast +++ b/test/lit/passes/coalesce-locals-learning.wast @@ -342,11 +342,15 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -355,11 +359,15 @@ (local $y i32) (if (i32.const 0) - (drop - (local.get $x) + (then + (drop + (local.get $x) + ) ) - (drop - (local.get $y) + (else + (drop + (local.get $y) + ) ) ) ) @@ -367,20 +375,24 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -390,20 +402,24 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) ) ) - (block $block3 - (local.set $y - (i32.const 1) - ) - (drop - (local.get $y) + (else + (block $block3 + (local.set $y + (i32.const 1) + ) + (drop + (local.get $y) + ) ) ) ) @@ -413,11 +429,15 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -432,11 +452,15 @@ (local $y i32) (if (i32.const 0) - (local.set $x - (i32.const 0) + (then + (local.set $x + (i32.const 0) + ) ) - (local.set $y - (i32.const 1) + (else + (local.set $y + (i32.const 1) + ) ) ) (drop @@ -457,11 +481,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -482,11 +510,15 @@ ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (drop @@ -507,8 +539,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -529,8 +563,10 @@ ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (drop @@ -548,8 +584,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -567,8 +605,10 @@ ) (if (i32.const 0) - (local.set $y - (i32.const 1) + (then + (local.set $y + (i32.const 1) + ) ) ) (drop @@ -586,12 +626,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -604,12 +646,14 @@ ) (if (i32.const 0) - (block $block1 - (drop - (local.get $x) - ) - (drop - (local.get $y) + (then + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) ) ) ) @@ -621,12 +665,14 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -638,12 +684,14 @@ (local.tee $x (i32.const 1) ) - (block $block1 - (drop - (local.get $x) - ) - (drop - (local.get $y) + (then + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) ) ) ) @@ -653,12 +701,14 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -671,12 +721,14 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) ) ) ) @@ -688,15 +740,17 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -709,15 +763,17 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.const 1) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) ) ) ) @@ -729,12 +785,14 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -747,12 +805,14 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (drop - (local.get $x) - ) - (local.set $y - (i32.const 1) + (then + (block $block1 + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) ) ) ) @@ -983,102 +1043,122 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block5 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 103) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (block $block8 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 104) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 105) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block10 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 106) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 107) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: (block $block13 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 108) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 109) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block15 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 110) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 111) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $greedy-can-be-happy (type $2) @@ -1090,102 +1170,122 @@ (local $y3 i32) (if (i32.const 0) - (if - (i32.const 1) + (then (if - (i32.const 2) - (block $block3 - (local.set $x1 - (i32.const 100) - ) - (local.set $y2 - (i32.const 101) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y2) + (i32.const 1) + (then + (if + (i32.const 2) + (then + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + ) + (else + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) - (block $block5 - (local.set $x1 - (i32.const 102) - ) - (local.set $y3 - (i32.const 103) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y3) + (else + (if + (i32.const 3) + (then + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + ) + (else + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) ) + ) + (else (if - (i32.const 3) - (block $block8 - (local.set $x2 - (i32.const 104) - ) - (local.set $y1 - (i32.const 105) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y1) + (i32.const 4) + (then + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) ) ) - (block $block10 - (local.set $x2 - (i32.const 106) - ) - (local.set $y3 - (i32.const 107) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y3) + (else + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) ) ) ) ) - (if - (i32.const 4) - (block $block13 - (local.set $x3 - (i32.const 108) - ) - (local.set $y1 - (i32.const 109) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y1) - ) - ) - (block $block15 - (local.set $x3 - (i32.const 110) - ) - (local.set $y2 - (i32.const 111) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y2) - ) - ) - ) ) ) ;; CHECK: (func $greedy-can-be-sad @@ -1193,102 +1293,122 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block5 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 103) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (block $block8 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 104) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 105) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block10 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 106) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 107) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: (block $block13 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 108) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 109) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block15 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 110) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 111) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $greedy-can-be-sad (type $2) @@ -1300,102 +1420,122 @@ (local $y3 i32) (if (i32.const 0) - (if - (i32.const 1) + (then (if - (i32.const 2) - (block $block3 - (local.set $x1 - (i32.const 100) - ) - (local.set $y2 - (i32.const 101) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y2) + (i32.const 1) + (then + (if + (i32.const 2) + (then + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + ) + (else + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) - (block $block5 - (local.set $x1 - (i32.const 102) - ) - (local.set $y3 - (i32.const 103) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y3) + (else + (if + (i32.const 3) + (then + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + ) + (else + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) ) + ) + (else (if - (i32.const 3) - (block $block8 - (local.set $x2 - (i32.const 104) - ) - (local.set $y1 - (i32.const 105) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y1) + (i32.const 4) + (then + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) ) ) - (block $block10 - (local.set $x2 - (i32.const 106) - ) - (local.set $y3 - (i32.const 107) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y3) + (else + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) ) ) ) ) - (if - (i32.const 4) - (block $block13 - (local.set $x3 - (i32.const 108) - ) - (local.set $y1 - (i32.const 109) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y1) - ) - ) - (block $block15 - (local.set $x3 - (i32.const 110) - ) - (local.set $y2 - (i32.const 111) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y2) - ) - ) - ) ) ) ;; CHECK: (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32) @@ -1405,8 +1545,10 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 4096) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $3 @@ -1423,93 +1565,101 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block2 - ;; CHECK-NEXT: (block $while-out$0 - ;; CHECK-NEXT: (loop $while-in$1 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block2 + ;; CHECK-NEXT: (block $while-out$0 + ;; CHECK-NEXT: (loop $while-in$1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.store8 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $while-out$2 - ;; CHECK-NEXT: (loop $while-in$3 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $while-out$2 + ;; CHECK-NEXT: (loop $while-in$3 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block7 - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (block $block7 + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in$3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1523,7 +1673,9 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $block9 ;; CHECK-NEXT: (i32.store8 @@ -1565,8 +1717,10 @@ (local.get $i3) (i32.const 4096) ) - (drop - (local.get $i1) + (then + (drop + (local.get $i1) + ) ) ) (local.set $i4 @@ -1583,93 +1737,101 @@ (i32.const 3) ) ) - (block $block2 - (block $while-out$0 - (loop $while-in$1 - (if - (i32.eqz - (i32.and - (local.get $i1) - (i32.const 3) - ) - ) - (br $while-out$0) - ) - (block $block4 + (then + (block $block2 + (block $while-out$0 + (loop $while-in$1 (if (i32.eqz - (local.get $i3) + (i32.and + (local.get $i1) + (i32.const 3) + ) ) - (return - (local.get $i4) + (then + (br $while-out$0) ) ) - (i32.store8 - (local.get $i1) - (i32.load8_s - (local.get $i2) + (block $block4 + (if + (i32.eqz + (local.get $i3) + ) + (then + (return + (local.get $i4) + ) + ) ) - ) - (local.set $i1 - (i32.add + (i32.store8 (local.get $i1) - (i32.const 1) + (i32.load8_s + (local.get $i2) + ) ) - ) - (local.set $i2 - (i32.add - (local.get $i2) - (i32.const 1) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) ) - ) - (local.set $i3 - (i32.sub - (local.get $i3) - (i32.const 1) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) ) ) + (br $while-in$1) ) - (br $while-in$1) ) - ) - (block $while-out$2 - (loop $while-in$3 - (if - (i32.eqz - (i32.ge_s - (local.get $i3) - (i32.const 4) + (block $while-out$2 + (loop $while-in$3 + (if + (i32.eqz + (i32.ge_s + (local.get $i3) + (i32.const 4) + ) ) - ) - (br $while-out$2) - ) - (block $block7 - (i32.store - (local.get $i1) - (i32.load - (local.get $i2) + (then + (br $while-out$2) ) ) - (local.set $i1 - (i32.add + (block $block7 + (i32.store (local.get $i1) - (i32.const 4) + (i32.load + (local.get $i2) + ) ) - ) - (local.set $i2 - (i32.add - (local.get $i2) - (i32.const 4) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 4) + ) ) - ) - (local.set $i3 - (i32.sub - (local.get $i3) - (i32.const 4) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 4) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 4) + ) ) ) + (br $while-in$3) ) - (br $while-in$3) ) ) ) @@ -1683,7 +1845,9 @@ (i32.const 0) ) ) - (br $while-out$4) + (then + (br $while-out$4) + ) ) (block $block9 (i32.store8 @@ -1721,16 +1885,22 @@ ;; CHECK: (func $this-is-effective-i-tell-you (param $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) @@ -1739,16 +1909,22 @@ (func $this-is-effective-i-tell-you (type $4) (param $x i32) (if (i32.const -1) - (block $block1 - (if - (i32.const 0) - (nop) - ) - (local.set $x - (i32.const 1) + (then + (block $block1 + (if + (i32.const 0) + (then + (nop) + ) + ) + (local.set $x + (i32.const 1) + ) ) ) - (nop) + (else + (nop) + ) ) (drop (local.get $x) diff --git a/test/lit/passes/coalesce-locals.wast b/test/lit/passes/coalesce-locals.wast index aa76ca82373..9666c02fa6b 100644 --- a/test/lit/passes/coalesce-locals.wast +++ b/test/lit/passes/coalesce-locals.wast @@ -359,11 +359,15 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -372,11 +376,15 @@ (local $y i32) (if (i32.const 0) - (drop - (local.get $x) + (then + (drop + (local.get $x) + ) ) - (drop - (local.get $y) + (else + (drop + (local.get $y) + ) ) ) ) @@ -384,20 +392,24 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -407,20 +419,24 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) ) ) - (block $block3 - (local.set $y - (i32.const 1) - ) - (drop - (local.get $y) + (else + (block $block3 + (local.set $y + (i32.const 1) + ) + (drop + (local.get $y) + ) ) ) ) @@ -430,11 +446,15 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -449,11 +469,15 @@ (local $y i32) (if (i32.const 0) - (local.set $x - (i32.const 0) + (then + (local.set $x + (i32.const 0) + ) ) - (local.set $y - (i32.const 1) + (else + (local.set $y + (i32.const 1) + ) ) ) (drop @@ -474,11 +498,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -499,11 +527,15 @@ ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (drop @@ -524,8 +556,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -546,8 +580,10 @@ ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (drop @@ -565,8 +601,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -584,8 +622,10 @@ ) (if (i32.const 0) - (local.set $y - (i32.const 1) + (then + (local.set $y + (i32.const 1) + ) ) ) (drop @@ -603,12 +643,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -621,12 +663,14 @@ ) (if (i32.const 0) - (block $block1 - (drop - (local.get $x) - ) - (drop - (local.get $y) + (then + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) ) ) ) @@ -638,12 +682,14 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -655,12 +701,14 @@ (local.tee $x (i32.const 1) ) - (block $block1 - (drop - (local.get $x) - ) - (drop - (local.get $y) + (then + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) ) ) ) @@ -670,12 +718,14 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -688,12 +738,14 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) ) ) ) @@ -705,15 +757,17 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -726,15 +780,17 @@ (local $y i32) (if (i32.const 0) - (block $block1 - (local.set $x - (i32.const 0) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.const 1) + (then + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) ) ) ) @@ -746,12 +802,14 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -764,15 +822,17 @@ (local $y i32) (if (i32.const 0) - (block $block1 - ;; These locals can be coalesced together: $x's live range ends here, - ;; and $y's begins right after it, so they do not have an overlap with - ;; a different value. - (drop - (local.get $x) - ) - (local.set $y - (i32.const 1) + (then + (block $block1 + ;; These locals can be coalesced together: $x's live range ends here, + ;; and $y's begins right after it, so they do not have an overlap with + ;; a different value. + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) ) ) ) @@ -785,12 +845,14 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -803,13 +865,15 @@ (local $y i32) (if (i32.const 0) - (block $block1 - ;; As above, but flipping these two instructions causes a conflict. - (local.set $y - (i32.const 1) - ) - (drop - (local.get $x) + (then + (block $block1 + ;; As above, but flipping these two instructions causes a conflict. + (local.set $y + (i32.const 1) + ) + (drop + (local.get $x) + ) ) ) ) @@ -1036,102 +1100,122 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block5 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 103) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (block $block8 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 104) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 105) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block10 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 106) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 107) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: (block $block13 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 108) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 109) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block15 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 110) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 111) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $greedy-can-be-happy (type $2) @@ -1143,102 +1227,122 @@ (local $y3 i32) (if (i32.const 0) - (if - (i32.const 1) + (then (if - (i32.const 2) - (block $block3 - (local.set $x1 - (i32.const 100) - ) - (local.set $y2 - (i32.const 101) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y2) + (i32.const 1) + (then + (if + (i32.const 2) + (then + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + ) + (else + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) - (block $block5 - (local.set $x1 - (i32.const 102) - ) - (local.set $y3 - (i32.const 103) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y3) + (else + (if + (i32.const 3) + (then + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + ) + (else + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) ) + ) + (else (if - (i32.const 3) - (block $block8 - (local.set $x2 - (i32.const 104) - ) - (local.set $y1 - (i32.const 105) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y1) + (i32.const 4) + (then + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) ) ) - (block $block10 - (local.set $x2 - (i32.const 106) - ) - (local.set $y3 - (i32.const 107) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y3) + (else + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) ) ) ) ) - (if - (i32.const 4) - (block $block13 - (local.set $x3 - (i32.const 108) - ) - (local.set $y1 - (i32.const 109) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y1) - ) - ) - (block $block15 - (local.set $x3 - (i32.const 110) - ) - (local.set $y2 - (i32.const 111) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y2) - ) - ) - ) ) ) ;; CHECK: (func $greedy-can-be-sad @@ -1247,99 +1351,119 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (block $block3 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block5 - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 103) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (block $block8 - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 104) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 105) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block10 - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 106) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 107) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: (block $block13 - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 108) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 109) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block15 - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 110) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 111) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1354,102 +1478,122 @@ (local $y3 i32) (if (i32.const 0) - (if - (i32.const 1) + (then (if - (i32.const 2) - (block $block3 - (local.set $x1 - (i32.const 100) - ) - (local.set $y2 - (i32.const 101) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y2) + (i32.const 1) + (then + (if + (i32.const 2) + (then + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + ) + (else + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) - (block $block5 - (local.set $x1 - (i32.const 102) - ) - (local.set $y3 - (i32.const 103) - ) - (drop - (local.get $x1) - ) - (drop - (local.get $y3) + (else + (if + (i32.const 3) + (then + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + ) + (else + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) ) ) ) + ) + (else (if - (i32.const 3) - (block $block8 - (local.set $x2 - (i32.const 104) - ) - (local.set $y1 - (i32.const 105) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y1) + (i32.const 4) + (then + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) ) ) - (block $block10 - (local.set $x2 - (i32.const 106) - ) - (local.set $y3 - (i32.const 107) - ) - (drop - (local.get $x2) - ) - (drop - (local.get $y3) + (else + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) ) ) ) ) - (if - (i32.const 4) - (block $block13 - (local.set $x3 - (i32.const 108) - ) - (local.set $y1 - (i32.const 109) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y1) - ) - ) - (block $block15 - (local.set $x3 - (i32.const 110) - ) - (local.set $y2 - (i32.const 111) - ) - (drop - (local.get $x3) - ) - (drop - (local.get $y2) - ) - ) - ) ) ) ;; CHECK: (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32) @@ -1459,8 +1603,10 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 4096) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $3 @@ -1477,93 +1623,101 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block2 - ;; CHECK-NEXT: (block $while-out$0 - ;; CHECK-NEXT: (loop $while-in$1 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block2 + ;; CHECK-NEXT: (block $while-out$0 + ;; CHECK-NEXT: (loop $while-in$1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.store8 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $while-out$2 - ;; CHECK-NEXT: (loop $while-in$3 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $while-out$2 + ;; CHECK-NEXT: (loop $while-in$3 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $block7 - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (block $block7 + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in$3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1577,7 +1731,9 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $block9 ;; CHECK-NEXT: (i32.store8 @@ -1619,8 +1775,10 @@ (local.get $i3) (i32.const 4096) ) - (drop - (local.get $i1) + (then + (drop + (local.get $i1) + ) ) ) (local.set $i4 @@ -1637,93 +1795,101 @@ (i32.const 3) ) ) - (block $block2 - (block $while-out$0 - (loop $while-in$1 - (if - (i32.eqz - (i32.and - (local.get $i1) - (i32.const 3) - ) - ) - (br $while-out$0) - ) - (block $block4 + (then + (block $block2 + (block $while-out$0 + (loop $while-in$1 (if (i32.eqz - (local.get $i3) + (i32.and + (local.get $i1) + (i32.const 3) + ) ) - (return - (local.get $i4) + (then + (br $while-out$0) ) ) - (i32.store8 - (local.get $i1) - (i32.load8_s - (local.get $i2) + (block $block4 + (if + (i32.eqz + (local.get $i3) + ) + (then + (return + (local.get $i4) + ) + ) ) - ) - (local.set $i1 - (i32.add + (i32.store8 (local.get $i1) - (i32.const 1) + (i32.load8_s + (local.get $i2) + ) ) - ) - (local.set $i2 - (i32.add - (local.get $i2) - (i32.const 1) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) ) - ) - (local.set $i3 - (i32.sub - (local.get $i3) - (i32.const 1) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) ) ) + (br $while-in$1) ) - (br $while-in$1) ) - ) - (block $while-out$2 - (loop $while-in$3 - (if - (i32.eqz - (i32.ge_s - (local.get $i3) - (i32.const 4) + (block $while-out$2 + (loop $while-in$3 + (if + (i32.eqz + (i32.ge_s + (local.get $i3) + (i32.const 4) + ) ) - ) - (br $while-out$2) - ) - (block $block7 - (i32.store - (local.get $i1) - (i32.load - (local.get $i2) + (then + (br $while-out$2) ) ) - (local.set $i1 - (i32.add + (block $block7 + (i32.store (local.get $i1) - (i32.const 4) + (i32.load + (local.get $i2) + ) ) - ) - (local.set $i2 - (i32.add - (local.get $i2) - (i32.const 4) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 4) + ) ) - ) - (local.set $i3 - (i32.sub - (local.get $i3) - (i32.const 4) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 4) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 4) + ) ) ) + (br $while-in$3) ) - (br $while-in$3) ) ) ) @@ -1737,7 +1903,9 @@ (i32.const 0) ) ) - (br $while-out$4) + (then + (br $while-out$4) + ) ) (block $block9 (i32.store8 @@ -1775,16 +1943,22 @@ ;; CHECK: (func $this-is-effective-i-tell-you (param $0 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: (block $block1 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) @@ -1793,16 +1967,22 @@ (func $this-is-effective-i-tell-you (type $4) (param $x i32) (if (i32.const -1) - (block $block1 - (if - (i32.const 0) - (nop) - ) - (local.set $x - (i32.const 1) + (then + (block $block1 + (if + (i32.const 0) + (then + (nop) + ) + ) + (local.set $x + (i32.const 1) + ) ) ) - (nop) + (else + (nop) + ) ) (drop (local.get $x) @@ -2004,8 +2184,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $get) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $out @@ -2037,7 +2219,9 @@ ) ) (if (call $get) - (local.set $2 (local.get $1)) ;; copy for 1/2 + (then + (local.set $2 (local.get $1)) ;; copy for 1/2 + ) ) (br_if $out (local.get $2)) (local.set $1 (i32.const 100)) @@ -2053,8 +2237,12 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2073,8 +2261,12 @@ (local.set $x (if (result i32) (i32.const 1) - (local.get $x) - (local.get $y) + (then + (local.get $x) + ) + (else + (local.get $y) + ) ) ) (drop (local.get $x)) @@ -2089,8 +2281,12 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2109,8 +2305,12 @@ (local.set $x (if (result i32) (i32.const 1) - (local.get $y) - (local.get $x) + (then + (local.get $y) + ) + (else + (local.get $x) + ) ) ) (drop (local.get $x)) @@ -2125,8 +2325,12 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2145,8 +2349,12 @@ (local.set $x (if (result i32) (i32.const 1) - (unreachable) - (local.get $x) + (then + (unreachable) + ) + (else + (local.get $x) + ) ) ) (drop (local.get $x)) @@ -2161,8 +2369,12 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2181,8 +2393,12 @@ (local.set $x (if (result i32) (i32.const 1) - (unreachable) - (local.get $y) + (then + (unreachable) + ) + (else + (local.get $y) + ) ) ) (drop (local.get $x)) @@ -2198,8 +2414,12 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2220,8 +2440,12 @@ (local.tee $x (if (result i32) (i32.const 1) - (local.get $x) - (i32.const 2) + (then + (local.get $x) + ) + (else + (i32.const 2) + ) ) ) ) @@ -2253,7 +2477,9 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (br $label$0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2264,7 +2490,9 @@ (local.tee $0 (if (br $label$0) - (nop) + (then + (nop) + ) ) ) ) @@ -2275,8 +2503,12 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (if (result f64) ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (f64.lt @@ -2290,8 +2522,12 @@ (local.tee $0 (if (result f64) (local.get $1) - (local.get $0) - (unreachable) + (then + (local.get $0) + ) + (else + (unreachable) + ) ) ) (f64.lt @@ -2305,8 +2541,12 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (if (result f64) ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (f64.lt @@ -2320,8 +2560,12 @@ (local.tee $0 (if (result f64) (local.get $1) - (unreachable) - (local.get $0) + (then + (unreachable) + ) + (else + (local.get $0) + ) ) ) (f64.lt @@ -2335,8 +2579,10 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -2347,7 +2593,9 @@ (local $y i32) (local.set $x (local.get $y)) (if (i32.const 1) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) ) (local.set $x (local.get $y)) (local.set $x (local.get $y)) @@ -2357,8 +2605,10 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -2369,7 +2619,9 @@ (local $y i32) (local.set $y (local.get $x)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $y (local.get $x)) @@ -2382,15 +2634,19 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -2402,8 +2658,10 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -2424,11 +2682,15 @@ (local.set $w (local.get $z)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -2436,7 +2698,9 @@ (local.set $z (i32.const 2)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -2797,11 +3061,15 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2840,11 +3108,15 @@ ;; next testcase for more on this.) (if (local.get $0) - (local.set $3 - (local.get $1) + (then + (local.set $3 + (local.get $1) + ) ) - (local.set $3 - (local.get $2) + (else + (local.set $3 + (local.get $2) + ) ) ) (drop @@ -2868,8 +3140,12 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) @@ -2901,11 +3177,15 @@ (nop) (if (local.get $0) - (local.set $1 - (local.get $0) + (then + (local.set $1 + (local.get $0) + ) ) - (local.set $1 - (local.get $0) + (else + (local.set $1 + (local.get $0) + ) ) ) (drop diff --git a/test/lit/passes/code-folding_enable-threads.wast b/test/lit/passes/code-folding_enable-threads.wast index 487fbd3acda..b07000278ed 100644 --- a/test/lit/passes/code-folding_enable-threads.wast +++ b/test/lit/passes/code-folding_enable-threads.wast @@ -19,7 +19,7 @@ ;; CHECK-NEXT: (block $label$1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $label$3 ;; CHECK-NEXT: (call_indirect (type $13) ;; CHECK-NEXT: (block $label$4 @@ -37,15 +37,17 @@ (block $label$1 (if (i32.const 1) - (block $label$3 - (call_indirect (type $13) - (block $label$4 (result f32) ;; but this type may change dangerously - (nop) ;; fold this - (br $label$3) + (then + (block $label$3 + (call_indirect (type $13) + (block $label$4 (result f32) ;; but this type may change dangerously + (nop) ;; fold this + (br $label$3) + ) + (i32.const 105) ) - (i32.const 105) + (nop) ;; with this ) - (nop) ;; with this ) ) ) @@ -53,22 +55,30 @@ ;; CHECK: (func $negative-zero (result f32) ;; CHECK-NEXT: (if (result f32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $label$0 (result f32) - ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$0 (result f32) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$1 (result f32) - ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $label$1 (result f32) + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $negative-zero (result f32) (if (result f32) (i32.const 0) - (block $label$0 (result f32) - (f32.const 0) + (then + (block $label$0 (result f32) + (f32.const 0) + ) ) - (block $label$1 (result f32) - (f32.const -0) + (else + (block $label$1 (result f32) + (f32.const -0) + ) ) ) ) @@ -83,11 +93,15 @@ (func $negative-zero-b (result f32) (if (result f32) (i32.const 0) - (block $label$0 (result f32) - (f32.const -0) + (then + (block $label$0 (result f32) + (f32.const -0) + ) ) - (block $label$1 (result f32) - (f32.const -0) + (else + (block $label$1 (result f32) + (f32.const -0) + ) ) ) ) @@ -102,11 +116,15 @@ (func $negative-zero-c (result f32) (if (result f32) (i32.const 0) - (block $label$0 (result f32) - (f32.const 0) + (then + (block $label$0 (result f32) + (f32.const 0) + ) ) - (block $label$1 (result f32) - (f32.const 0) + (else + (block $label$1 (result f32) + (f32.const 0) + ) ) ) ) @@ -114,23 +132,29 @@ ;; CHECK-NEXT: (block $label$A ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $label$B - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (br_table $label$A $label$B + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $label$B + ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_table $label$A $label$B + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block $label$C ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (br_table $label$A $label$C - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_table $label$A $label$C + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -143,29 +167,37 @@ (block $label$A (if (unreachable) - (block + (then (block - (block $label$B - (if - (unreachable) - (br_table $label$A $label$B + (block + (block $label$B + (if (unreachable) + (then + (br_table $label$A $label$B + (unreachable) + ) + ) ) ) + (return) ) - (return) ) ) - (block - (block $label$C - (if - (unreachable) - (br_table $label$A $label$C ;; this all looks mergeable, but $label$A is outside + (else + (block + (block $label$C + (if (unreachable) + (then + (br_table $label$A $label$C ;; this all looks mergeable, but $label$A is outside + (unreachable) + ) + ) ) ) + (return) ) - (return) ) ) ) @@ -175,18 +207,24 @@ ;; CHECK-NEXT: (block $label$A ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (br $folding-inner0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $folding-inner0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $label$B ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (br_table $label$B $label$B - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_table $label$B $label$B + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -196,29 +234,37 @@ (block $label$A (if (unreachable) - (block + (then (block - (block $label$B - (if - (unreachable) - (br_table $label$B $label$B + (block + (block $label$B + (if (unreachable) + (then + (br_table $label$B $label$B + (unreachable) + ) + ) ) ) + (return) ) - (return) ) ) - (block - (block $label$C - (if - (unreachable) - (br_table $label$C $label$C ;; this all looks mergeable, and is, B ~~ C + (else + (block + (block $label$C + (if (unreachable) + (then + (br_table $label$C $label$C ;; this all looks mergeable, and is, B ~~ C + (unreachable) + ) + ) ) ) + (return) ) - (return) ) ) ) @@ -270,11 +316,15 @@ ;; CHECK-NEXT: (local $var$0 i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.load offset=22 - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.load offset=22 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.atomic.load offset=22 - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.atomic.load offset=22 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -282,11 +332,15 @@ (local $var$0 i32) (if (result i32) (i32.const 0) - (i32.load offset=22 - (local.get $var$0) + (then + (i32.load offset=22 + (local.get $var$0) + ) ) - (i32.atomic.load offset=22 - (local.get $var$0) + (else + (i32.atomic.load offset=22 + (local.get $var$0) + ) ) ) ) @@ -313,13 +367,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -351,28 +409,32 @@ ) (if (global.get $global$0) - (block - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (then + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) + (unreachable) ) - (unreachable) ) ) (unreachable) ) (if (global.get $global$0) - (block - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (then + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) + (unreachable) ) - (unreachable) ) ) (unreachable) diff --git a/test/lit/passes/code-pushing-eh.wast b/test/lit/passes/code-pushing-eh.wast index 60d9f907ff3..bfda0dd16b7 100644 --- a/test/lit/passes/code-pushing-eh.wast +++ b/test/lit/passes/code-pushing-eh.wast @@ -329,8 +329,10 @@ ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $x @@ -351,7 +353,9 @@ (local.set $x (i32.const 1)) (if (local.get $param) - (throw $e (i32.const 0)) + (then + (throw $e (i32.const 0)) + ) ) (drop (local.get $x)) ) @@ -365,8 +369,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -385,7 +391,9 @@ (local.set $x (i32.const 1)) (if (local.get $param) - (throw $e (i32.const 0)) + (then + (throw $e (i32.const 0)) + ) ) (drop (local.get $x)) ) diff --git a/test/lit/passes/code-pushing_ignore-implicit-traps.wast b/test/lit/passes/code-pushing_ignore-implicit-traps.wast index d8fadefd77b..b275e58e25a 100644 --- a/test/lit/passes/code-pushing_ignore-implicit-traps.wast +++ b/test/lit/passes/code-pushing_ignore-implicit-traps.wast @@ -200,7 +200,9 @@ ;; CHECK-NEXT: (block $out ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -214,7 +216,7 @@ (local $x i32) (block $out (local.set $x (i32.const 1)) - (if (i32.const 2) (nop)) + (if (i32.const 2) (then (nop))) (drop (local.get $x)) ) ) @@ -510,7 +512,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $value-interferes) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $value-interferes) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) @@ -522,7 +526,9 @@ (block $out (local.set $x (i32.load (i32.const 0))) (if (i32.const 1) - (call $value-interferes) + (then + (call $value-interferes) + ) ) (drop (local.get $x)) ) @@ -696,7 +702,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -707,7 +715,9 @@ (br_if $out (i32.const 1)) (if (local.get $x) - (nop) + (then + (nop) + ) ) ) ) diff --git a/test/lit/passes/code-pushing_into_if.wast b/test/lit/passes/code-pushing_into_if.wast index 3ef905dd518..ec10bb226dd 100644 --- a/test/lit/passes/code-pushing_into_if.wast +++ b/test/lit/passes/code-pushing_into_if.wast @@ -12,7 +12,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-nop (param $p i32) @@ -21,7 +23,9 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (nop) + (then + (nop) + ) ) ) @@ -32,8 +36,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-nop-nop (param $p i32) @@ -41,8 +49,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (nop) - (nop) ;; add a nop here compared to the last testcase (no output change) + (then + (nop) + ) + (else + (nop) ;; add a nop here compared to the last testcase (no output change) + ) ) ) @@ -51,7 +63,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -67,7 +79,9 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -76,7 +90,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -84,7 +98,9 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-use-nop (param $p i32) @@ -92,8 +108,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) - (nop) ;; add a nop here compared to the last testcase (no output change) + (then + (drop (local.get $x)) + ) + (else + (nop) ;; add a nop here compared to the last testcase (no output change) + ) ) ) @@ -102,8 +122,10 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -119,8 +141,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (nop) - (drop (local.get $x)) + (then + (nop) + ) + (else + (drop (local.get $x)) + ) ) ) @@ -135,8 +161,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -150,7 +178,9 @@ (local.set $y (local.get $x)) (if (local.get $p) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -161,11 +191,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -175,8 +209,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) + (else + (drop (local.get $x)) + ) ) ) @@ -187,8 +225,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -201,7 +241,9 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) (drop (local.get $x)) ) @@ -213,10 +255,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) @@ -227,8 +273,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) - (nop) ;; add a nop here compared to the last testcase (no output change) + (then + (drop (local.get $x)) + ) + (else + (nop) ;; add a nop here compared to the last testcase (no output change) + ) ) (drop (local.get $x)) ) @@ -240,9 +290,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -254,8 +308,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (nop) - (drop (local.get $x)) ;; now the use in the if is in the else arm + (then + (nop) + ) + (else + (drop (local.get $x)) ;; now the use in the if is in the else arm + ) ) (drop (local.get $x)) ) @@ -265,7 +323,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -273,7 +331,9 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) @@ -285,8 +345,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (drop (local.get $x)) - (return) + (then + (drop (local.get $x)) + ) + (else + (return) + ) ) (drop (local.get $x)) ) @@ -296,8 +360,10 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -315,8 +381,12 @@ (local.set $x (i32.const 1)) (if (local.get $p) - (return) ;; as above, but with arms flipped - (drop (local.get $x)) + (then + (return) ;; as above, but with arms flipped + ) + (else + (drop (local.get $x)) + ) ) (drop (local.get $x)) ) @@ -330,7 +400,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -344,7 +414,7 @@ ;; CHECK-NEXT: (local.get $z) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -364,11 +434,15 @@ (local.set $z (i32.const 3)) (if (local.get $p) - (block - (drop (local.get $x)) - (drop (local.get $z)) + (then + (block + (drop (local.get $x)) + (drop (local.get $z)) + ) + ) + (else + (drop (local.get $y)) ) - (drop (local.get $y)) ) ) @@ -381,7 +455,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (local.get $t) ;; CHECK-NEXT: ) @@ -399,7 +473,9 @@ (drop (i32.const 2)) (if (local.get $p) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -416,8 +492,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -429,7 +507,9 @@ (drop (local.tee $t (i32.const 2))) (if (local.get $p) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -443,8 +523,10 @@ ;; CHECK-NEXT: (local.tee $t ;; CHECK-NEXT: (local.get $p) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -455,7 +537,9 @@ (local.set $x (local.get $t)) (if (local.tee $t (local.get $p)) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -467,8 +551,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -479,7 +565,9 @@ (local.set $x (local.get $t)) (if (local.get $x) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -493,8 +581,10 @@ ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (local.get $p) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -505,7 +595,9 @@ (local.set $x (local.get $t)) (if (local.tee $x (local.get $p)) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -517,7 +609,7 @@ ;; CHECK-NEXT: (return) ;; CHECK-NEXT: (local.get $p) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -537,7 +629,9 @@ ;; anyhow. (local.get $p) ) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) ) @@ -552,8 +646,10 @@ ;; CHECK-NEXT: (br $out) ;; CHECK-NEXT: (local.get $p) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return) @@ -573,7 +669,9 @@ (br $out) (local.get $p) ) - (drop (local.get $x)) + (then + (drop (local.get $x)) + ) ) (return) ) @@ -589,10 +687,12 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -611,8 +711,12 @@ (local.set $y (local.get $x)) (if (local.get $p) - (drop (local.get $x)) - (drop (local.get $y)) + (then + (drop (local.get $x)) + ) + (else + (drop (local.get $y)) + ) ) ) @@ -625,7 +729,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $y ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -633,8 +737,10 @@ ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -647,8 +753,12 @@ (local.set $y (local.get $x)) (if (local.get $p) - (drop (local.get $y)) - (drop (local.get $x)) + (then + (drop (local.get $y)) + ) + (else + (drop (local.get $x)) + ) ) ) @@ -657,7 +767,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (call $call.without.effects ;; CHECK-NEXT: (i32.const 1234) @@ -684,8 +794,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (i32.const 0) @@ -701,8 +813,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $temp) @@ -721,8 +835,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (local.get $temp) ;; this line changed. @@ -738,8 +854,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -758,8 +876,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (nop) ;; this line was added. @@ -776,8 +896,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -800,8 +922,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (nop) @@ -817,7 +941,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (call $call.without.effects ;; CHECK-NEXT: (i32.const 1234) @@ -850,8 +974,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (nop) @@ -875,8 +1001,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -897,8 +1025,10 @@ ) (if (local.get $p) - (return - (local.get $temp) + (then + (return + (local.get $temp) + ) ) ) (i32.const 0) @@ -909,14 +1039,18 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block $label$3 - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -938,10 +1072,14 @@ ) (if (i32.const 1) - (unreachable) - (block $label$3 - (drop - (local.get $1) + (then + (unreachable) + ) + (else + (block $label$3 + (drop + (local.get $1) + ) ) ) ) diff --git a/test/lit/passes/code-pushing_tnh.wast b/test/lit/passes/code-pushing_tnh.wast index 1dcf725ad57..74791aca91c 100644 --- a/test/lit/passes/code-pushing_tnh.wast +++ b/test/lit/passes/code-pushing_tnh.wast @@ -13,7 +13,9 @@ ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $temp ;; CHECK-NEXT: (i32.div_u @@ -39,7 +41,9 @@ ) (if (local.get $y) - (return) + (then + (return) + ) ) (drop (local.get $temp) @@ -54,8 +58,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -68,8 +74,10 @@ ) (if (i32.const 0) - (drop - (local.get $x) + (then + (drop + (local.get $x) + ) ) ) ) diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast index aa474d7f393..11638b62faa 100644 --- a/test/lit/passes/dae-gc-refine-return.wast +++ b/test/lit/passes/dae-gc-refine-return.wast @@ -78,8 +78,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result i31ref) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $refine-return-flow) - ;; CHECK-NEXT: (call $refine-return-flow) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $refine-return-flow) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $refine-return-flow) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call-refine-return-flow (result anyref) @@ -91,8 +95,12 @@ ;; function's return value. (if (result anyref) (i32.const 1) - (call $refine-return-flow) - (call $refine-return-flow) + (then + (call $refine-return-flow) + ) + (else + (call $refine-return-flow) + ) ) ) @@ -125,14 +133,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $i31) @@ -145,11 +157,15 @@ (if (i32.const 1) - (return (local.get $i31)) + (then + (return (local.get $i31)) + ) ) (if (i32.const 2) - (return (local.get $i31)) + (then + (return (local.get $i31)) + ) ) (local.get $i31) ) @@ -163,14 +179,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $i31) @@ -184,12 +204,16 @@ (if (i32.const 1) - (return (local.get $i31)) + (then + (return (local.get $i31)) + ) ) (if (i32.const 2) ;; The refined return type has to be a supertype of struct. - (return (local.get $struct)) + (then + (return (local.get $struct)) + ) ) (local.get $i31) ) @@ -203,14 +227,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $i31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $struct) @@ -224,11 +252,15 @@ (if (i32.const 1) - (return (local.get $i31)) + (then + (return (local.get $i31)) + ) ) (if (i32.const 2) - (return (local.get $i31)) + (then + (return (local.get $i31)) + ) ) ;; The refined return type has to be a supertype of struct. (local.get $struct) @@ -301,8 +333,10 @@ ;; CHECK-NEXT: (local $any anyref) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call $tail-callee) @@ -313,7 +347,9 @@ ;; This function's return type cannot be refined because of another return ;; whose type prevents it. (if (i32.const 1) - (return (local.get $any)) + (then + (return (local.get $any)) + ) ) (return_call $tail-callee) ) @@ -354,8 +390,10 @@ ;; CHECK-NEXT: (local $any anyref) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_indirect $0 (type $return_{}) @@ -366,7 +404,9 @@ (local $any anyref) (if (i32.const 1) - (return (local.get $any)) + (then + (return (local.get $any)) + ) ) (return_call_indirect (type $return_{}) (i32.const 0)) ) @@ -410,8 +450,10 @@ ;; CHECK-NEXT: (local $"return_{}" (ref null $return_{})) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_ref $return_{} @@ -423,7 +465,9 @@ (local $return_{} (ref null $return_{})) (if (i32.const 1) - (return (local.get $any)) + (then + (return (local.get $any)) + ) ) (return_call_ref $return_{} (local.get $return_{})) ) @@ -466,18 +510,26 @@ ;; CHECK: (func $update-null (type $10) (param $x i32) (param $y i32) (result (ref null ${i32})) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (struct.new_default ${i32_f32}) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (struct.new_default ${i32_f32}) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (struct.new_default ${i32_i64}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (struct.new_default ${i32_i64}) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $update-null (param $x i32) (param $y i32) (result anyref) @@ -485,12 +537,20 @@ ;; determined by the other two, and is their shared parent ${}. (if (local.get $x) - (if - (local.get $y) - (return (struct.new ${i32_f32})) - (return (ref.null any)) + (then + (if + (local.get $y) + (then + (return (struct.new ${i32_f32})) + ) + (else + (return (ref.null any)) + ) + ) + ) + (else + (return (struct.new ${i32_i64})) ) - (return (struct.new ${i32_i64})) ) ) diff --git a/test/lit/passes/dae-optimizing.wast b/test/lit/passes/dae-optimizing.wast index ddffbacfe46..cb15d55cb07 100644 --- a/test/lit/passes/dae-optimizing.wast +++ b/test/lit/passes/dae-optimizing.wast @@ -20,25 +20,31 @@ ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.const 33554432) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $label$2 (result f32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $label$2 (result f32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $label$2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -11) @@ -50,33 +56,39 @@ (local.tee $7 (i32.const 33554432) ) - (drop - (loop $label$2 (result f32) - (if - (global.get $global$0) - (return - (local.get $7) + (then + (drop + (loop $label$2 (result f32) + (if + (global.get $global$0) + (then + (return + (local.get $7) + ) + ) ) - ) - (local.set $8 - (block $label$4 (result i32) - (drop - (local.tee $7 - (local.get $8) + (local.set $8 + (block $label$4 (result i32) + (drop + (local.tee $7 + (local.get $8) + ) ) + (i32.const 0) ) - (i32.const 0) ) + (br_if $label$2 + (local.get $7) + ) + (f32.const 1) ) - (br_if $label$2 - (local.get $7) - ) - (f32.const 1) ) ) - (drop - (call $1 - (f32.const 1) + (else + (drop + (call $1 + (f32.const 1) + ) ) ) ) diff --git a/test/lit/passes/dce-eh.wast b/test/lit/passes/dce-eh.wast index f05f5122e45..123f7a42d72 100644 --- a/test/lit/passes/dce-eh.wast +++ b/test/lit/passes/dce-eh.wast @@ -94,7 +94,9 @@ (throw $e) ) ) - (nop) + (then + (nop) + ) ) (ref.null extern) ) diff --git a/test/lit/passes/dce_all-features.wast b/test/lit/passes/dce_all-features.wast index 255ca82fd51..3eb683676f2 100644 --- a/test/lit/passes/dce_all-features.wast +++ b/test/lit/passes/dce_all-features.wast @@ -43,12 +43,16 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $out3 - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $out3 + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $out4 @@ -66,25 +70,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block4 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $out16 ;; CHECK-NEXT: (block $in @@ -96,14 +112,16 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block11 - ;; CHECK-NEXT: (block $out18 - ;; CHECK-NEXT: (block $in19 - ;; CHECK-NEXT: (br_if $in19 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block11 + ;; CHECK-NEXT: (block $out18 + ;; CHECK-NEXT: (block $in19 + ;; CHECK-NEXT: (br_if $in19 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -125,32 +143,38 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block13 - ;; CHECK-NEXT: (block $out25 - ;; CHECK-NEXT: (block $in26 - ;; CHECK-NEXT: (br_table $in26 $in26 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (block $out25 + ;; CHECK-NEXT: (block $in26 + ;; CHECK-NEXT: (br_table $in26 $in26 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block15 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $out29 ;; CHECK-NEXT: (loop $in30 @@ -162,18 +186,20 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block $block20 - ;; CHECK-NEXT: (loop $in32 - ;; CHECK-NEXT: (br_if $in32 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $block20 + ;; CHECK-NEXT: (loop $in32 + ;; CHECK-NEXT: (br_if $in32 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 123) ;; CHECK-NEXT: ) @@ -182,15 +208,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 123) ;; CHECK-NEXT: ) @@ -202,7 +232,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 139) ;; CHECK-NEXT: ) @@ -211,7 +241,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 246) ;; CHECK-NEXT: ) @@ -220,19 +250,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -4) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 22) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 33) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -241,23 +277,31 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 44) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 55) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 66) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 77) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 88) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -266,11 +310,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 99) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 123) ;; CHECK-NEXT: ) @@ -282,7 +328,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 123) ;; CHECK-NEXT: ) @@ -291,7 +337,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 1337) @@ -306,8 +354,10 @@ ) (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) ) (br_table $out $out $out $out @@ -317,19 +367,23 @@ ) (if (i32.const 0) - (block $out - (unreachable) - (drop - (i32.const 0) + (then + (block $out + (unreachable) + (drop + (i32.const 0) + ) ) ) ) (if (i32.const 0) - (block $out - (return) - (drop - (i32.const 0) + (then + (block $out + (return) + (drop + (i32.const 0) + ) ) ) ) @@ -351,68 +405,80 @@ ) (if (i32.const 0) - (block $block4 - (if - (i32.const 0) - (block $out - (unreachable) - (drop - (i32.const 0) + (then + (block $block4 + (if + (i32.const 0) + (then + (block $out + (unreachable) + (drop + (i32.const 0) + ) + ) ) - ) - (block $out - (unreachable) - (drop - (i32.const 0) + (else + (block $out + (unreachable) + (drop + (i32.const 0) + ) + ) ) ) - ) - (drop - (i32.const 0) + (drop + (i32.const 0) + ) ) ) ) (if (i32.const 0) - (drop - (block $out (result i32) - (br $out + (then + (drop + (block $out (result i32) + (br $out + (unreachable) + ) + (drop + (i32.const 0) + ) (unreachable) ) - (drop - (i32.const 0) - ) - (unreachable) ) ) ) (if (i32.const 0) - (drop - (block $out (result i32) - (br_if $out + (then + (drop + (block $out (result i32) + (br_if $out + (unreachable) + (i32.const 0) + ) + (drop + (i32.const 0) + ) (unreachable) - (i32.const 0) ) - (drop - (i32.const 0) - ) - (unreachable) ) ) ) (if (i32.const 0) - (drop - (block $out (result i32) - (br_if $out - (unreachable) + (then + (drop + (block $out (result i32) + (br_if $out + (unreachable) + (unreachable) + ) + (drop + (i32.const 0) + ) (unreachable) ) - (drop - (i32.const 0) - ) - (unreachable) ) ) ) @@ -426,17 +492,19 @@ ) (if (i32.const 0) - (block $block11 - (block $out - (block $in - (br_if $in - (i32.const 1) + (then + (block $block11 + (block $out + (block $in + (br_if $in + (i32.const 1) + ) ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) @@ -458,41 +526,47 @@ ) (if (i32.const 0) - (block $block13 - (block $out - (block $in - (br_table $in $in - (i32.const 1) + (then + (block $block13 + (block $out + (block $in + (br_table $in $in + (i32.const 1) + ) ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) (if (i32.const 0) - (block $block15 - (drop - (i32.const 10) - ) - (drop - (i32.const 42) - ) - (unreachable) - (return + (then + (block $block15 + (drop + (i32.const 10) + ) + (drop + (i32.const 42) + ) (unreachable) + (return + (unreachable) + ) + (unreachable) + (return) ) - (unreachable) - (return) ) ) (if (i32.const 0) - (loop $loop-in18 - (unreachable) + (then + (loop $loop-in18 + (unreachable) + ) ) ) (block $out @@ -505,166 +579,206 @@ ) (if (i32.const 0) - (block $block20 - (loop $in - (br_if $in - (i32.const 1) + (then + (block $block20 + (loop $in + (br_if $in + (i32.const 1) + ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) (if (i32.const 1) - (call $call-me - (i32.const 123) - (unreachable) + (then + (call $call-me + (i32.const 123) + (unreachable) + ) ) ) (if (i32.const 2) - (call $call-me - (unreachable) - (i32.const 0) + (then + (call $call-me + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const 3) - (call $call-me - (unreachable) - (unreachable) + (then + (call $call-me + (unreachable) + (unreachable) + ) ) ) (if (i32.const -1) - (call_indirect (type $ii) - (i32.const 123) - (i32.const 456) - (unreachable) + (then + (call_indirect (type $ii) + (i32.const 123) + (i32.const 456) + (unreachable) + ) ) ) (if (i32.const -2) - (call_indirect (type $ii) - (i32.const 139) - (unreachable) - (i32.const 0) + (then + (call_indirect (type $ii) + (i32.const 139) + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const -3) - (call_indirect (type $ii) - (i32.const 246) - (unreachable) - (unreachable) + (then + (call_indirect (type $ii) + (i32.const 246) + (unreachable) + (unreachable) + ) ) ) (if (i32.const -4) - (call_indirect (type $ii) - (unreachable) - (unreachable) - (unreachable) + (then + (call_indirect (type $ii) + (unreachable) + (unreachable) + (unreachable) + ) ) ) (if (i32.const 11) - (local.set $x - (unreachable) + (then + (local.set $x + (unreachable) + ) ) ) (if (i32.const 22) - (drop - (i32.load - (unreachable) + (then + (drop + (i32.load + (unreachable) + ) ) ) ) (if (i32.const 33) - (i32.store - (i32.const 0) - (unreachable) + (then + (i32.store + (i32.const 0) + (unreachable) + ) ) ) (if (i32.const 44) - (i32.store - (unreachable) - (i32.const 0) + (then + (i32.store + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const 55) - (i32.store - (unreachable) - (unreachable) + (then + (i32.store + (unreachable) + (unreachable) + ) ) ) (if (i32.const 66) - (drop - (i32.eqz - (unreachable) + (then + (drop + (i32.eqz + (unreachable) + ) ) ) ) (if (i32.const 77) - (drop - (i32.add - (unreachable) - (i32.const 0) + (then + (drop + (i32.add + (unreachable) + (i32.const 0) + ) ) ) ) (if (i32.const 88) - (drop - (i32.add - (i32.const 0) - (unreachable) + (then + (drop + (i32.add + (i32.const 0) + (unreachable) + ) ) ) ) (if (i32.const 99) - (i32.add - (unreachable) - (unreachable) + (then + (i32.add + (unreachable) + (unreachable) + ) ) ) (if (i32.const 100) - (drop - (select - (i32.const 123) - (i32.const 456) - (unreachable) + (then + (drop + (select + (i32.const 123) + (i32.const 456) + (unreachable) + ) ) ) ) (if (i32.const 101) - (drop - (select - (i32.const 123) - (unreachable) - (i32.const 456) + (then + (drop + (select + (i32.const 123) + (unreachable) + (i32.const 456) + ) ) ) ) (if (i32.const 102) - (drop - (select - (unreachable) - (i32.const 123) - (i32.const 456) + (then + (drop + (select + (unreachable) + (i32.const 123) + (i32.const 456) + ) ) ) ) @@ -898,28 +1012,32 @@ ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $var$0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$0 (result i64) - ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$0 (result i64) + ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$1 - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i64.sub - ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (i64.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $label$1 ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result i64) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i64) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -931,24 +1049,28 @@ (i64.eqz (local.get $var$0) ) - (block $label$0 (result i64) - (local.get $var$1) + (then + (block $label$0 (result i64) + (local.get $var$1) + ) ) - (block $label$1 (result i64) - (call $call-unreach - (i64.sub - (local.get $var$0) - (i64.const 1) - ) - (i64.mul - (block (result i64) - (local.set $2 - (local.get $var$0) + (else + (block $label$1 (result i64) + (call $call-unreach + (i64.sub + (local.get $var$0) + (i64.const 1) + ) + (i64.mul + (block (result i64) + (local.set $2 + (local.get $var$0) + ) + (nop) + (local.get $2) ) - (nop) - (local.get $2) + (unreachable) ) - (unreachable) ) ) ) @@ -1033,8 +1155,10 @@ (unreachable) (if (unreachable) - (br_if $label$0 - (local.get $var$1) + (then + (br_if $label$0 + (local.get $var$1) + ) ) ) ) @@ -1061,8 +1185,12 @@ ;; CHECK-NEXT: (block $label$0 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1071,8 +1199,12 @@ (br $label$0 (if (result i32) (local.get $var$0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -1157,8 +1289,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1177,8 +1313,12 @@ ) (i32.const 1) ) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -1227,8 +1367,12 @@ (i32.load16_s offset=22 align=1 (i32.const 0) ) - (br $top) ;; this keeps the block none after the inner block gets unreachable. but it will vanish into unreachable itself - (unreachable) + (then + (br $top) ;; this keeps the block none after the inner block gets unreachable. but it will vanish into unreachable itself + ) + (else + (unreachable) + ) ) ) ) @@ -1248,16 +1392,24 @@ ;; CHECK: (func $0 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 (global.set $global (if (result f64) (i32.const 0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -1269,8 +1421,12 @@ ;; CHECK-NEXT: (local $local f64) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 @@ -1278,8 +1434,12 @@ (local.set $local (if (result f64) (i32.const 0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -1318,17 +1478,25 @@ ;; CHECK: (func $unnecessary-concrete-if (type $0) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $unnecessary-concrete-if (result i32) (if (result i32) ;; unnecessary type (i32.const 0) - (return (i32.const 1)) - (unreachable) + (then + (return (i32.const 1)) + ) + (else + (unreachable) + ) ) ) ;; CHECK: (func $unnecessary-concrete-try (type $0) (result i32) @@ -1368,8 +1536,12 @@ (nop) (unreachable) ) - (unreachable) - (br $label$1) + (then + (unreachable) + ) + (else + (br $label$1) + ) ) ) ) @@ -1436,9 +1608,13 @@ ;; CHECK-NEXT: (ref.cast i31ref ;; CHECK-NEXT: (if (result i31ref) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (ref.i31 + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1454,11 +1630,15 @@ (ref.cast i31ref (if (result i31ref) (i32.const 0) - (block (result i31ref) - (unreachable) + (then + (block (result i31ref) + (unreachable) + ) ) - (ref.i31 - (i32.const 42) + (else + (ref.i31 + (i32.const 42) + ) ) ) ) diff --git a/test/lit/passes/dce_vacuum_remove-unused-names.wast b/test/lit/passes/dce_vacuum_remove-unused-names.wast index b7a53d61b1e..492029191ff 100644 --- a/test/lit/passes/dce_vacuum_remove-unused-names.wast +++ b/test/lit/passes/dce_vacuum_remove-unused-names.wast @@ -49,8 +49,12 @@ ;; CHECK-NEXT: (local.get $var$1) ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $set-unreachable (param $var$0 i64) (result i64) @@ -64,11 +68,15 @@ (local.get $var$1) (i64.const 0) ) - (unreachable) - (local.set $var$2 - (i64.mul - (unreachable) - (local.get $var$2) + (then + (unreachable) + ) + (else + (local.set $var$2 + (i64.mul + (unreachable) + (local.get $var$2) + ) ) ) ) diff --git a/test/lit/passes/denan.wast b/test/lit/passes/denan.wast index 1932ce534aa..7baabc36977 100644 --- a/test/lit/passes/denan.wast +++ b/test/lit/passes/denan.wast @@ -186,8 +186,12 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (f32.const 0) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (f32.const 0) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -197,8 +201,12 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (f64.const 0) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (f64.const 0) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (module @@ -255,8 +263,12 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (f32.const 0) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (f32.const 0) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -266,7 +278,11 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: (f64.const 0) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (f64.const 0) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/directize_all-features.wast b/test/lit/passes/directize_all-features.wast index 53ff29ab6e7..c560baf0e8c 100644 --- a/test/lit/passes/directize_all-features.wast +++ b/test/lit/passes/directize_all-features.wast @@ -785,13 +785,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (call $foo1 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $foo1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $foo2 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $foo2 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -806,13 +810,17 @@ ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: (if ;; IMMUT-NEXT: (local.get $z) - ;; IMMUT-NEXT: (call $foo1 - ;; IMMUT-NEXT: (local.get $3) - ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: (then + ;; IMMUT-NEXT: (call $foo1 + ;; IMMUT-NEXT: (local.get $3) + ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) - ;; IMMUT-NEXT: (call $foo2 - ;; IMMUT-NEXT: (local.get $3) - ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: (else + ;; IMMUT-NEXT: (call $foo2 + ;; IMMUT-NEXT: (local.get $3) + ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) @@ -908,10 +916,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (call $foo2 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $foo2 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -926,10 +938,14 @@ ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: (if ;; IMMUT-NEXT: (local.get $z) - ;; IMMUT-NEXT: (unreachable) - ;; IMMUT-NEXT: (call $foo2 - ;; IMMUT-NEXT: (local.get $3) - ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: (then + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: (else + ;; IMMUT-NEXT: (call $foo2 + ;; IMMUT-NEXT: (local.get $3) + ;; IMMUT-NEXT: (local.get $4) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) @@ -957,8 +973,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; IMMUT: (func $select-both-out-of-range (type $0) (param $x i32) (param $y i32) (param $z i32) @@ -972,8 +992,12 @@ ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: (if ;; IMMUT-NEXT: (local.get $z) - ;; IMMUT-NEXT: (unreachable) - ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: (then + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: (else + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) (func $select-both-out-of-range (param $x i32) (param $y i32) (param $z i32) @@ -1060,15 +1084,23 @@ ;; CHECK: (func $select-bad-type (type $2) (param $z i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; IMMUT: (func $select-bad-type (type $2) (param $z i32) ;; IMMUT-NEXT: (if ;; IMMUT-NEXT: (local.get $z) - ;; IMMUT-NEXT: (unreachable) - ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: (then + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: (else + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) (func $select-bad-type (param $z i32) @@ -1129,11 +1161,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $foo-ref - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $foo-ref + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $foo-ref - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $foo-ref + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1144,11 +1180,15 @@ ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: (if ;; IMMUT-NEXT: (local.get $x) - ;; IMMUT-NEXT: (call $foo-ref - ;; IMMUT-NEXT: (local.get $1) + ;; IMMUT-NEXT: (then + ;; IMMUT-NEXT: (call $foo-ref + ;; IMMUT-NEXT: (local.get $1) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) - ;; IMMUT-NEXT: (call $foo-ref - ;; IMMUT-NEXT: (local.get $1) + ;; IMMUT-NEXT: (else + ;; IMMUT-NEXT: (call $foo-ref + ;; IMMUT-NEXT: (local.get $1) + ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) ;; IMMUT-NEXT: ) diff --git a/test/lit/passes/flatten_all-features.wast b/test/lit/passes/flatten_all-features.wast index 3ce8496863e..fd73326090b 100644 --- a/test/lit/passes/flatten_all-features.wast +++ b/test/lit/passes/flatten_all-features.wast @@ -568,14 +568,18 @@ ;; CHECK: (func $a11 (type $1) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a11 (if (i32.const 0) - (drop (i32.const 1)) + (then + (drop (i32.const 1)) + ) ) ) ;; CHECK: (func $a12 (type $2) (result i32) @@ -583,11 +587,15 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $1 @@ -599,8 +607,12 @@ ;; CHECK-NEXT: ) (func $a12 (result i32) (if (result i32) (i32.const 0) - (i32.const 1) - (i32.const 2) + (then + (i32.const 1) + ) + (else + (i32.const 2) + ) ) ) ;; CHECK: (func $a13 (type $2) (result i32) @@ -622,11 +634,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -648,8 +664,12 @@ (block $x i32 (if i32 (br_table $x (i32.const 2) (i32.const 0)) - (i32.const 0) - (i32.const 1) + (then + (i32.const 0) + ) + (else + (i32.const 1) + ) ) ) ) @@ -700,11 +720,11 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block $label$3 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -725,10 +745,14 @@ (i32.load16_u (i32.const 53) ) - (unreachable) - (drop - (block $label$3 (result f32) - (unreachable) + (then + (unreachable) + ) + (else + (drop + (block $label$3 (result f32) + (unreachable) + ) ) ) ) @@ -955,8 +979,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_table $out $out $out $out @@ -967,7 +993,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out1 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -980,7 +1006,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out3 ;; CHECK-NEXT: (return) ;; CHECK-NEXT: (unreachable) @@ -1010,11 +1036,11 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $block4 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out8 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1024,7 +1050,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block $out9 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1045,7 +1071,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out11 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1066,7 +1092,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out13 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1087,7 +1113,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $out15 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1118,7 +1144,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $block11 ;; CHECK-NEXT: (block $out18 ;; CHECK-NEXT: (block $in19 @@ -1159,7 +1185,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $block13 ;; CHECK-NEXT: (block $out25 ;; CHECK-NEXT: (block $in26 @@ -1181,7 +1207,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $block15 ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 10) @@ -1206,7 +1232,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (loop $loop-in18 ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1229,7 +1255,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $block20 ;; CHECK-NEXT: (loop $in32 ;; CHECK-NEXT: (block @@ -1251,7 +1277,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call $call-me ;; CHECK-NEXT: (i32.const 123) @@ -1262,7 +1288,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call $call-me ;; CHECK-NEXT: (unreachable) @@ -1273,7 +1299,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call $call-me @@ -1285,7 +1311,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call_indirect $0 (type $ii) ;; CHECK-NEXT: (i32.const 123) @@ -1297,7 +1323,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call_indirect $0 (type $ii) ;; CHECK-NEXT: (i32.const 139) @@ -1309,7 +1335,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (call_indirect $0 (type $ii) @@ -1322,7 +1348,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -4) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1336,7 +1362,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) @@ -1344,7 +1370,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 22) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (unreachable) @@ -1357,7 +1383,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 33) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 0) @@ -1368,7 +1394,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 44) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (unreachable) @@ -1379,7 +1405,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 55) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.store @@ -1391,7 +1417,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 66) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (unreachable) @@ -1404,7 +1430,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 77) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (unreachable) @@ -1418,7 +1444,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 88) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.const 0) @@ -1432,7 +1458,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 99) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (i32.add @@ -1444,7 +1470,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (select ;; CHECK-NEXT: (i32.const 123) @@ -1459,7 +1485,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 101) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (select ;; CHECK-NEXT: (i32.const 123) @@ -1474,7 +1500,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 102) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (select ;; CHECK-NEXT: (unreachable) @@ -1500,8 +1526,10 @@ ) (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) ) (br_table $out $out $out $out @@ -1511,19 +1539,23 @@ ) (if (i32.const 0) - (block $out1 - (unreachable) - (drop - (i32.const 0) + (then + (block $out1 + (unreachable) + (drop + (i32.const 0) + ) ) ) ) (if (i32.const 0) - (block $out3 - (return) - (drop - (i32.const 0) + (then + (block $out3 + (return) + (drop + (i32.const 0) + ) ) ) ) @@ -1545,68 +1577,80 @@ ) (if (i32.const 0) - (block $block4 - (if - (i32.const 0) - (block $out8 - (unreachable) - (drop - (i32.const 0) + (then + (block $block4 + (if + (i32.const 0) + (then + (block $out8 + (unreachable) + (drop + (i32.const 0) + ) + ) ) - ) - (block $out9 - (unreachable) - (drop - (i32.const 0) + (else + (block $out9 + (unreachable) + (drop + (i32.const 0) + ) + ) ) ) - ) - (drop - (i32.const 0) + (drop + (i32.const 0) + ) ) ) ) (if (i32.const 0) - (drop - (block $out11 (result i32) - (br $out11 + (then + (drop + (block $out11 (result i32) + (br $out11 + (unreachable) + ) + (drop + (i32.const 0) + ) (unreachable) ) - (drop - (i32.const 0) - ) - (unreachable) ) ) ) (if (i32.const 0) - (drop - (block $out13 (result i32) - (br_if $out13 + (then + (drop + (block $out13 (result i32) + (br_if $out13 + (unreachable) + (i32.const 0) + ) + (drop + (i32.const 0) + ) (unreachable) - (i32.const 0) - ) - (drop - (i32.const 0) ) - (unreachable) ) ) ) (if (i32.const 0) - (drop - (block $out15 (result i32) - (br_if $out15 - (unreachable) + (then + (drop + (block $out15 (result i32) + (br_if $out15 + (unreachable) + (unreachable) + ) + (drop + (i32.const 0) + ) (unreachable) ) - (drop - (i32.const 0) - ) - (unreachable) ) ) ) @@ -1620,17 +1664,19 @@ ) (if (i32.const 0) - (block $block11 - (block $out18 - (block $in19 - (br_if $in19 - (i32.const 1) + (then + (block $block11 + (block $out18 + (block $in19 + (br_if $in19 + (i32.const 1) + ) ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) @@ -1652,41 +1698,47 @@ ) (if (i32.const 0) - (block $block13 - (block $out25 - (block $in26 - (br_table $in26 $in26 - (i32.const 1) + (then + (block $block13 + (block $out25 + (block $in26 + (br_table $in26 $in26 + (i32.const 1) + ) ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) (if (i32.const 0) - (block $block15 - (drop - (i32.const 10) - ) - (drop - (i32.const 42) - ) - (unreachable) - (return + (then + (block $block15 + (drop + (i32.const 10) + ) + (drop + (i32.const 42) + ) (unreachable) + (return + (unreachable) + ) + (unreachable) + (return) ) - (unreachable) - (return) ) ) (if (i32.const 0) - (loop $loop-in18 - (unreachable) + (then + (loop $loop-in18 + (unreachable) + ) ) ) (block $out29 @@ -1699,166 +1751,206 @@ ) (if (i32.const 0) - (block $block20 - (loop $in32 - (br_if $in32 - (i32.const 1) + (then + (block $block20 + (loop $in32 + (br_if $in32 + (i32.const 1) + ) + (unreachable) + ) + (drop + (i32.const 10) ) - (unreachable) - ) - (drop - (i32.const 10) ) ) ) (if (i32.const 1) - (call $call-me - (i32.const 123) - (unreachable) + (then + (call $call-me + (i32.const 123) + (unreachable) + ) ) ) (if (i32.const 2) - (call $call-me - (unreachable) - (i32.const 0) + (then + (call $call-me + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const 3) - (call $call-me - (unreachable) - (unreachable) + (then + (call $call-me + (unreachable) + (unreachable) + ) ) ) (if (i32.const -1) - (call_indirect (type $ii) - (i32.const 123) - (i32.const 456) - (unreachable) + (then + (call_indirect (type $ii) + (i32.const 123) + (i32.const 456) + (unreachable) + ) ) ) (if (i32.const -2) - (call_indirect (type $ii) - (i32.const 139) - (unreachable) - (i32.const 0) + (then + (call_indirect (type $ii) + (i32.const 139) + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const -3) - (call_indirect (type $ii) - (i32.const 246) - (unreachable) - (unreachable) + (then + (call_indirect (type $ii) + (i32.const 246) + (unreachable) + (unreachable) + ) ) ) (if (i32.const -4) - (call_indirect (type $ii) - (unreachable) - (unreachable) - (unreachable) + (then + (call_indirect (type $ii) + (unreachable) + (unreachable) + (unreachable) + ) ) ) (if (i32.const 11) - (local.set $x - (unreachable) + (then + (local.set $x + (unreachable) + ) ) ) (if (i32.const 22) - (drop - (i32.load - (unreachable) + (then + (drop + (i32.load + (unreachable) + ) ) ) ) (if (i32.const 33) - (i32.store - (i32.const 0) - (unreachable) + (then + (i32.store + (i32.const 0) + (unreachable) + ) ) ) (if (i32.const 44) - (i32.store - (unreachable) - (i32.const 0) + (then + (i32.store + (unreachable) + (i32.const 0) + ) ) ) (if (i32.const 55) - (i32.store - (unreachable) - (unreachable) + (then + (i32.store + (unreachable) + (unreachable) + ) ) ) (if (i32.const 66) - (drop - (i32.eqz - (unreachable) + (then + (drop + (i32.eqz + (unreachable) + ) ) ) ) (if (i32.const 77) - (drop - (i32.add - (unreachable) - (i32.const 0) + (then + (drop + (i32.add + (unreachable) + (i32.const 0) + ) ) ) ) (if (i32.const 88) - (drop - (i32.add - (i32.const 0) - (unreachable) + (then + (drop + (i32.add + (i32.const 0) + (unreachable) + ) ) ) ) (if (i32.const 99) - (i32.add - (unreachable) - (unreachable) + (then + (i32.add + (unreachable) + (unreachable) + ) ) ) (if (i32.const 100) - (drop - (select - (i32.const 123) - (i32.const 456) - (unreachable) + (then + (drop + (select + (i32.const 123) + (i32.const 456) + (unreachable) + ) ) ) ) (if (i32.const 101) - (drop - (select - (i32.const 123) - (unreachable) - (i32.const 456) + (then + (drop + (select + (i32.const 123) + (unreachable) + (i32.const 456) + ) ) ) ) (if (i32.const 102) - (drop - (select - (unreachable) - (i32.const 123) - (i32.const 456) + (then + (drop + (select + (unreachable) + (i32.const 123) + (i32.const 456) + ) ) ) ) @@ -2296,7 +2388,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $label$0 ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $var$1) @@ -2312,7 +2404,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block $label$1 ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $var$0) @@ -2374,24 +2466,28 @@ (i64.eqz (local.get $var$0) ) - (block $label$0 (result i64) - (local.get $var$1) + (then + (block $label$0 (result i64) + (local.get $var$1) + ) ) - (block $label$1 (result i64) - (call $call-unreach - (i64.sub - (local.get $var$0) - (i64.const 1) - ) - (i64.mul - (block $block (result i64) - (local.set $2 - (local.get $var$0) + (else + (block $label$1 (result i64) + (call $call-unreach + (i64.sub + (local.get $var$0) + (i64.const 1) + ) + (i64.mul + (block $block (result i64) + (local.set $2 + (local.get $var$0) + ) + (nop) + (local.get $2) ) - (nop) - (local.get $2) + (unreachable) ) - (unreachable) ) ) ) @@ -2564,11 +2660,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 6) - ;; CHECK-NEXT: (local.set $13 - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $13 - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $14 @@ -2625,11 +2725,15 @@ ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $18 @@ -2647,11 +2751,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $21 @@ -2669,11 +2777,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (local.set $23 - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $23 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $23 - ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $23 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $24 @@ -2691,11 +2803,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (local.set $26 - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $26 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $26 - ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $26 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $27 @@ -2703,11 +2819,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: (local.set $28 - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $28 + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $28 - ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $28 + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $29 @@ -2744,11 +2864,15 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 5) - ;; CHECK-NEXT: (local.set $31 - ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $31 + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $31 - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $31 + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $32 @@ -2756,17 +2880,23 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $32) - ;; CHECK-NEXT: (local.set $35 - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $35 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: (local.set $33 - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $33 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $33 - ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $33 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $34 @@ -2838,8 +2968,12 @@ (drop (i32.add (i32.const 1) (if (result i32) (i32.const 6) - (i32.const 7) - (i32.const 8) + (then + (i32.const 7) + ) + (else + (i32.const 8) + ) ) )) (drop @@ -2874,8 +3008,12 @@ (select (if (result i32) (i32.const 11) - (i32.const 12) - (i32.const 13) + (then + (i32.const 12) + ) + (else + (i32.const 13) + ) ) (i32.const 9) (i32.const 10) @@ -2886,8 +3024,12 @@ (i32.const 9) (if (result i32) (i32.const 11) - (i32.const 12) - (i32.const 13) + (then + (i32.const 12) + ) + (else + (i32.const 13) + ) ) (i32.const 10) ) @@ -2898,8 +3040,12 @@ (i32.const 10) (if (result i32) (i32.const 11) - (i32.const 12) - (i32.const 13) + (then + (i32.const 12) + ) + (else + (i32.const 13) + ) ) ) ) @@ -2907,14 +3053,22 @@ (select (if (result i32) (i32.const 11) - (i32.const 12) - (i32.const 13) + (then + (i32.const 12) + ) + (else + (i32.const 13) + ) ) (i32.const 14) (if (result i32) (i32.const 15) - (i32.const 16) - (i32.const 17) + (then + (i32.const 16) + ) + (else + (i32.const 17) + ) ) ) ) @@ -2924,14 +3078,26 @@ (if (result i32) (if (result i32) (i32.const 5) - (i32.const 6) - (i32.const 7) + (then + (i32.const 6) + ) + (else + (i32.const 7) + ) ) - (i32.const 8) - (if (result i32) - (i32.const 9) - (i32.const 10) - (i32.const 11) + (then + (i32.const 8) + ) + (else + (if (result i32) + (i32.const 9) + (then + (i32.const 10) + ) + (else + (i32.const 11) + ) + ) ) ) ) @@ -3012,7 +3178,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $label$78 ;; CHECK-NEXT: (local.set $430 ;; CHECK-NEXT: (i32.const 0) @@ -3025,7 +3191,7 @@ ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block $label$79 ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (local.get $9) @@ -3113,35 +3279,39 @@ (local.get $12) (i32.const 65535) ) - (block - (block $label$78 - (local.set $430 - (i32.const 0) + (then + (block + (block $label$78 + (local.set $430 + (i32.const 0) + ) + ) + (local.set $432 + (local.get $430) ) - ) - (local.set $432 - (local.get $430) ) ) - (block - (block $label$79 - (local.set $431 - (i32.lt_u - (local.get $9) - (i32.load16_u offset=2 - (i32.add - (local.get $5) - (i32.mul - (local.get $12) - (i32.const 12) + (else + (block + (block $label$79 + (local.set $431 + (i32.lt_u + (local.get $9) + (i32.load16_u offset=2 + (i32.add + (local.get $5) + (i32.mul + (local.get $12) + (i32.const 12) + ) ) ) ) ) ) - ) - (local.set $432 - (local.get $431) + (local.set $432 + (local.get $431) + ) ) ) ) diff --git a/test/lit/passes/flatten_dfo_O3_enable-threads.wast b/test/lit/passes/flatten_dfo_O3_enable-threads.wast index ccb029060be..34142b73f58 100644 --- a/test/lit/passes/flatten_dfo_O3_enable-threads.wast +++ b/test/lit/passes/flatten_dfo_O3_enable-threads.wast @@ -67,39 +67,43 @@ (nop) (if (i32.const 0) - (i32.store8 - (i32.const 8) - (block $label$2 (result i32) - (drop - (br_if $label$2 - (i32.const 1) - (i32.const 0) - ) - ) - (if - (i32.const 0) + (then + (i32.store8 + (i32.const 8) + (block $label$2 (result i32) (drop (br_if $label$2 (i32.const 1) - (i32.const 1) + (i32.const 0) ) ) - ) - (block $label$4 - (br_if $label$4 - (i32.const 0) - ) - (br_if $label$4 + (if (i32.const 0) + (then + (drop + (br_if $label$2 + (i32.const 1) + (i32.const 1) + ) + ) + ) ) - (drop - (br_if $label$2 - (i32.const 1) + (block $label$4 + (br_if $label$4 + (i32.const 0) + ) + (br_if $label$4 (i32.const 0) ) + (drop + (br_if $label$2 + (i32.const 1) + (i32.const 0) + ) + ) ) + (i32.const 6704) ) - (i32.const 6704) ) ) ) @@ -121,44 +125,58 @@ (i32.wrap_i64 (if (result i64) (i32.const 0) - (i64.const 1) - (if (result i64) - (if (result i32) - (i32.const 0) - (unreachable) - (block $label$6 (result i32) - (block $label$7 - (loop $label$8 - (br_if $label$8 - (br_if $label$6 - (local.tee $var$2 - (block $label$9 (result i32) - (local.get $var$1) + (then + (i64.const 1) + ) + (else + (if (result i64) + (if (result i32) + (i32.const 0) + (then + (unreachable) + ) + (else + (block $label$6 (result i32) + (block $label$7 + (loop $label$8 + (br_if $label$8 + (br_if $label$6 + (local.tee $var$2 + (block $label$9 (result i32) + (local.get $var$1) + ) + ) + (i32.const 0) ) ) - (i32.const 0) - ) - ) - (loop $label$10 - (if - (i32.const 0) - (local.set $var$2 - (local.get $var$1) + (loop $label$10 + (if + (i32.const 0) + (then + (local.set $var$2 + (local.get $var$1) + ) + ) + ) + ) + (drop + (i32.eqz + (local.get $var$2) + ) ) ) ) - (drop - (i32.eqz - (local.get $var$2) - ) - ) + (unreachable) ) ) + ) + (then (unreachable) ) + (else + (i64.const 1) + ) ) - (unreachable) - (i64.const 1) ) ) ) @@ -180,27 +198,31 @@ (local.set $var$4 (if (result i32) (i32.const 0) - (block (result i32) - (local.set $var$4 - (local.tee $var$2 - (i32.xor - (i32.const 0) - (i32.const -1) + (then + (block (result i32) + (local.set $var$4 + (local.tee $var$2 + (i32.xor + (i32.const 0) + (i32.const -1) + ) ) ) + (i32.const 0) ) - (i32.const 0) ) - (block (result i32) - (local.set $var$4 - (local.tee $var$2 - (i32.xor - (i32.const 0) - (i32.const -1) + (else + (block (result i32) + (local.set $var$4 + (local.tee $var$2 + (i32.xor + (i32.const 0) + (i32.const -1) + ) ) ) + (i32.const 0) ) - (i32.const 0) ) ) ) @@ -230,14 +252,18 @@ (local.get $var$1) ) ) - (if - (local.get $var$2) - (i64.atomic.store32 offset=3 - (i32.and - (local.get $var$1) ;; only dfo can figure out that this is 0 - (i32.const 15) + (then + (if + (local.get $var$2) + (then + (i64.atomic.store32 offset=3 + (i32.and + (local.get $var$1) ;; only dfo can figure out that this is 0 + (i32.const 15) + ) + (i64.const -32768) + ) ) - (i64.const -32768) ) ) ) @@ -253,14 +279,18 @@ (local.tee $0 (i32.const 1) ) - (loop $label$2 (result i32) - (select - (i32.const 1) - (i32.const -1709605511) - (local.get $0) + (then + (loop $label$2 (result i32) + (select + (i32.const 1) + (i32.const -1709605511) + (local.get $0) + ) ) ) - (unreachable) + (else + (unreachable) + ) ) ) ) diff --git a/test/lit/passes/flatten_i64-to-i32-lowering.wast b/test/lit/passes/flatten_i64-to-i32-lowering.wast index 16ebaf8829b..d2fc16a58b2 100644 --- a/test/lit/passes/flatten_i64-to-i32-lowering.wast +++ b/test/lit/passes/flatten_i64-to-i32-lowering.wast @@ -62,10 +62,12 @@ ;; CHECK-NEXT: (local.get $i64toi32_i32$4) ;; CHECK-NEXT: (local.get $i64toi32_i32$3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $i64toi32_i32$5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $i64toi32_i32$5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $i64toi32_i32$5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $i64toi32_i32$5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/flatten_rereloop.wast b/test/lit/passes/flatten_rereloop.wast index 17a8e8125d1..07230ca47a4 100644 --- a/test/lit/passes/flatten_rereloop.wast +++ b/test/lit/passes/flatten_rereloop.wast @@ -29,19 +29,23 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f64.const -nan:0xfffffd63e4e5a) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const -nan:0xfffffd63e4e5a) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -50,8 +54,10 @@ (func $0 (result f64) (if (i32.const 0) - (loop $label$2 - (unreachable) + (then + (loop $label$2 + (unreachable) + ) ) ) (f64.const -nan:0xfffffd63e4e5a) @@ -302,25 +308,29 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (f32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -329,7 +339,9 @@ (func $skipping (param $0 i32) (result f32) (if (i32.const 0) - (unreachable) + (then + (unreachable) + ) ) ;; branches joining here lead to skip opportunities (loop $label$2 (result f32) (f32.const 1) @@ -346,7 +358,9 @@ (func $merging (if (i32.const 0) - (return) + (then + (return) + ) ;; no else, but the else ends up with a return too, and we can merge them ) ) @@ -377,15 +391,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (global.set $global - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: (global.set $global + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -395,8 +413,10 @@ (func $skip-only-empty (if (i32.const 1) - (global.set $global - (i32.const 0) + (then + (global.set $global + (i32.const 0) + ) ) ) ) @@ -412,19 +432,23 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -436,7 +460,9 @@ ) (if (i32.const 1) - (unreachable) ;; blocks a path through + (then + (unreachable) ;; blocks a path through + ) ) (i32.const 0) ) @@ -451,28 +477,32 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f32.const 9223372036854775808) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f32.const 9223372036854775808) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$6$break) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$6$break) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (f32.const 65505) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$6$break) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (f32.const 65505) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$6$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -491,15 +521,19 @@ (func $multipass-for-skips (result f32) (if (result f32) (i32.const 0) - (block (result f32) - (block $label$2 - (br_if $label$2 - (i32.const 536870912) + (then + (block (result f32) + (block $label$2 + (br_if $label$2 + (i32.const 536870912) + ) ) + (f32.const 9223372036854775808) ) - (f32.const 9223372036854775808) ) - (f32.const 65505) + (else + (f32.const 65505) + ) ) ) ;; CHECK: (func $branch-merge-vs-replace @@ -508,18 +542,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $branch-merge-vs-replace (if (i32.const 0) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $unswitch-amount @@ -529,29 +569,33 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const -23) - ;; CHECK-NEXT: (br $block$2$break) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $block$5$break - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $switch$4$leave - ;; CHECK-NEXT: (block $switch$4$default - ;; CHECK-NEXT: (block $switch$4$case$2 - ;; CHECK-NEXT: (br_table $switch$4$case$2 $switch$4$default - ;; CHECK-NEXT: (i32.const 44064) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $block$2$break) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $block$5$break + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $switch$4$leave + ;; CHECK-NEXT: (block $switch$4$default + ;; CHECK-NEXT: (block $switch$4$case$2 + ;; CHECK-NEXT: (br_table $switch$4$case$2 $switch$4$default + ;; CHECK-NEXT: (i32.const 44064) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$2$break) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$2$break) + ;; CHECK-NEXT: (br $block$5$break) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$5$break) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -564,14 +608,18 @@ (block $label$1 (if (i32.const -23) - (nop) - (block - (block $label$4 - (br_table $label$1 $label$4 - (i32.const 44064) + (then + (nop) + ) + (else + (block + (block $label$4 + (br_table $label$1 $label$4 + (i32.const 44064) + ) ) + (unreachable) ) - (unreachable) ) ) ) @@ -665,54 +713,66 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -732,28 +792,34 @@ ) (if (local.get $1) - (block + (then (block - (local.set $2 - (local.get $x) - ) - (if - (local.get $2) - (block - (return - (i32.const 2) - ) - (unreachable) + (block + (local.set $2 + (local.get $x) ) - (block - (return - (i32.const 3) + (if + (local.get $2) + (then + (block + (return + (i32.const 2) + ) + (unreachable) + ) + ) + (else + (block + (return + (i32.const 3) + ) + (unreachable) + ) ) - (unreachable) ) ) + (unreachable) ) - (unreachable) ) ) ) @@ -764,11 +830,13 @@ ) (if (local.get $3) - (block - (return - (i32.const 4) + (then + (block + (return + (i32.const 4) + ) + (unreachable) ) - (unreachable) ) ) ) @@ -810,13 +878,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (loop $shape$2$continue - ;; CHECK-NEXT: (call $trivial) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $shape$2$continue) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $shape$2$continue + ;; CHECK-NEXT: (call $trivial) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $shape$2$continue) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $block$17$break) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$17$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -836,8 +908,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (br $shape$4$continue) - ;; CHECK-NEXT: (br $block$19$break) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $shape$4$continue) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$19$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -858,8 +934,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (br $shape$6$continue) - ;; CHECK-NEXT: (br $block$26$break) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $shape$6$continue) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$26$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -880,17 +960,19 @@ ) (if (local.get $1) - (block - (loop $top - (block - (call $trivial) - (nop) - (br $top) + (then + (block + (loop $top + (block + (call $trivial) + (nop) + (br $top) + (unreachable) + ) (unreachable) ) (unreachable) ) - (unreachable) ) ) ) @@ -920,9 +1002,11 @@ ) (if (local.get $3) - (block - (br $top3) - (unreachable) + (then + (block + (br $top3) + (unreachable) + ) ) ) ) @@ -981,19 +1065,23 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (br $block$2$break) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $block$30$break - ;; CHECK-NEXT: (call $unreachable - ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $block$2$break) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $block$30$break + ;; CHECK-NEXT: (call $unreachable + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$30$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$30$break) + ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1011,20 +1099,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $unreachable - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $unreachable + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $unreachable - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $unreachable + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1040,46 +1132,52 @@ ) (if (local.get $1) - (block + (then (block - (local.set $2 - (local.get $x) - ) - (if - (local.get $2) - (block - (block $block - (call $unreachable - (i32.const 1) - ) - (nop) - (unreachable) - (unreachable) - (call $unreachable - (i32.const 2) - ) - (nop) - ) - (unreachable) + (block + (local.set $2 + (local.get $x) ) - (block - (block $block4 - (call $unreachable - (i32.const 3) + (if + (local.get $2) + (then + (block + (block $block + (call $unreachable + (i32.const 1) + ) + (nop) + (unreachable) + (unreachable) + (call $unreachable + (i32.const 2) + ) + (nop) + ) + (unreachable) ) - (nop) - (return) - (unreachable) - (call $unreachable - (i32.const 4) + ) + (else + (block + (block $block4 + (call $unreachable + (i32.const 3) + ) + (nop) + (return) + (unreachable) + (call $unreachable + (i32.const 4) + ) + (nop) + ) + (unreachable) ) - (nop) ) - (unreachable) ) ) + (unreachable) ) - (unreachable) ) ) ) @@ -1171,13 +1269,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (br $block$3$break) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $before-and-after - ;; CHECK-NEXT: (i32.const 5) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: (call $before-and-after + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$3$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1220,8 +1322,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (br $shape$4$continue) - ;; CHECK-NEXT: (br $block$8$break) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $shape$4$continue) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$8$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1246,15 +1352,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $before-and-after - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$10$break) + ;; CHECK-NEXT: (call $before-and-after + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$10$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $block$10$break) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$10$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -1275,20 +1385,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $13) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $before-and-after - ;; CHECK-NEXT: (i32.const 14) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$13$break) + ;; CHECK-NEXT: (call $before-and-after + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$13$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $before-and-after - ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$13$break) + ;; CHECK-NEXT: (call $before-and-after + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$13$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1308,15 +1422,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $before-and-after - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$16$break) + ;; CHECK-NEXT: (call $before-and-after + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$16$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $block$16$break) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$16$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block @@ -1472,11 +1590,13 @@ ) (if (local.get $3) - (block - (call $before-and-after - (i32.const 12) + (then + (block + (call $before-and-after + (i32.const 12) + ) + (nop) ) - (nop) ) ) ) @@ -1491,17 +1611,21 @@ ) (if (local.get $4) - (block - (call $before-and-after - (i32.const 14) + (then + (block + (call $before-and-after + (i32.const 14) + ) + (nop) ) - (nop) ) - (block - (call $before-and-after - (i32.const 15) + (else + (block + (call $before-and-after + (i32.const 15) + ) + (nop) ) - (nop) ) ) ) @@ -1512,14 +1636,16 @@ ) (if (local.get $5) - (block - (block $block8 - (call $before-and-after - (i32.const 16) + (then + (block + (block $block8 + (call $before-and-after + (i32.const 16) + ) + (nop) ) (nop) ) - (nop) ) ) ) @@ -1703,20 +1829,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$4$break) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$4$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$4$break) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$4$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1728,17 +1858,21 @@ (func $no-return (; 11 ;) (type $0) (if (i32.const 1) - (block - (drop - (i32.const 2) + (then + (block + (drop + (i32.const 2) + ) + (nop) ) - (nop) ) - (block - (drop - (i32.const 3) + (else + (block + (drop + (i32.const 3) + ) + (nop) ) - (nop) ) ) (nop) @@ -1769,31 +1903,39 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $if-br-wat - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br $block$12$break) + ;; CHECK-NEXT: (call $if-br-wat + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (br $block$12$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $block$2$break) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $block$12$break) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (br $block$2$break) - ;; CHECK-NEXT: (br $block$12$break) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1830,26 +1972,32 @@ ) (if (local.get $1) - (block - (call $if-br-wat - (i32.const 1) + (then + (block + (call $if-br-wat + (i32.const 1) + ) + (nop) ) - (nop) ) - (block + (else (block - (local.set $2 - (local.get $x) - ) - (if - (local.get $2) - (block - (br $label$2) - (unreachable) + (block + (local.set $2 + (local.get $x) + ) + (if + (local.get $2) + (then + (block + (br $label$2) + (unreachable) + ) + ) ) ) + (nop) ) - (nop) ) ) ) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast index 011ea86e9e5..4f1aa8ec382 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast @@ -38,8 +38,12 @@ (i32.const 1) (local.get $var$0) ) - (i32.const -2405046) - (i32.const 1) + (then + (i32.const -2405046) + ) + (else + (i32.const 1) + ) ) ) ) @@ -51,7 +55,9 @@ (i32.eqz (i32.const 0) ) - (unreachable) + (then + (unreachable) + ) ) (f64.const -9223372036854775808) ) @@ -63,22 +69,28 @@ (block $label$2 (if (i32.const 1) - (block - (drop - (loop $label$5 (result i64) - (if (result i64) - (i32.const 0) - (i64.load offset=22 - (i32.and - (br_if $label$1 - (i32.const 0) - (i32.const 0) + (then + (block + (drop + (loop $label$5 (result i64) + (if (result i64) + (i32.const 0) + (then + (i64.load offset=22 + (i32.and + (br_if $label$1 + (i32.const 0) + (i32.const 0) + ) + (i32.const 15) + ) + (i64.const 1) ) - (i32.const 15) ) - (i64.const 1) + (else + (i64.const 1) + ) ) - (i64.const 1) ) ) ) @@ -102,8 +114,12 @@ (i32.eqz (if (result i32) (i32.const 0) - (i32.const 0) - (local.get $var$2) + (then + (i32.const 0) + ) + (else + (local.get $var$2) + ) ) ) ) @@ -122,7 +138,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const -2147483648) ;; CHECK-NEXT: ) @@ -149,15 +165,17 @@ (i32.eqz (local.get $var$4) ) - (block - (local.set $var$4 - (select - (local.get $var$3) - (i32.const -2147483648) - (local.get $var$2) + (then + (block + (local.set $var$4 + (select + (local.get $var$3) + (i32.const -2147483648) + (local.get $var$2) + ) ) + (br $label$1) ) - (br $label$1) ) ) ) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast index ea693d50230..76b4e6e51f0 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify-single-use_enable-threads.wast @@ -143,7 +143,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -180,7 +180,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -197,28 +197,32 @@ (local.get $x) (local.get $y) ) - (block - (local.set $i - (i64.eq - (local.get $a) - (local.get $x) + (then + (block + (local.set $i + (i64.eq + (local.get $a) + (local.get $x) + ) ) - ) - (local.set $j - (i64.ne - (local.get $a) - (local.get $y) + (local.set $j + (i64.ne + (local.get $a) + (local.get $y) + ) ) - ) - (local.set $r - (i32.and - (local.get $i) - (local.get $j) + (local.set $r + (i32.and + (local.get $i) + (local.get $j) + ) ) + (return (local.get $r)) ) - (return (local.get $r)) ) - (unreachable) + (else + (unreachable) + ) ) ) ;; Figure 3, simplified to an if @@ -244,7 +248,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -254,7 +258,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -289,16 +293,20 @@ (local.get $x) (i32.const 1) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (else + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -377,7 +385,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -392,10 +400,12 @@ (func $various-conditions-1 (param $x i32) (if (local.get $x) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) ) @@ -414,7 +424,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -432,10 +442,12 @@ (local.get $x) (i32.const 0) ) - (local.set $x - (i32.sub - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.sub + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -451,7 +463,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -466,10 +478,12 @@ (func $various-conditions-3 (param $x i32) (if (i32.reinterpret_f32 (f32.const 0)) - (local.set $x - (i32.sub - (local.get $x) - (i32.const 4) + (then + (local.set $x + (i32.sub + (local.get $x) + (i32.const 4) + ) ) ) ) @@ -481,7 +495,7 @@ ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -498,10 +512,12 @@ (func $various-conditions-4 (param $x i32) (if (unreachable) - (local.set $x - (i32.add - (local.get $x) - (i32.const 3) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 3) + ) ) ) ) @@ -525,7 +541,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.ctz @@ -565,18 +581,20 @@ (i32.eqz (local.get $x) ) - (local.set $x - (i32.add - (i32.ctz - (local.get $y) - ) - (i32.sub - (i32.clz - (local.get $x) - ) - (i32.popcnt + (then + (local.set $x + (i32.add + (i32.ctz (local.get $y) ) + (i32.sub + (i32.clz + (local.get $x) + ) + (i32.popcnt + (local.get $y) + ) + ) ) ) ) @@ -602,7 +620,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -622,10 +640,12 @@ (i32.const 1) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -650,7 +670,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -670,10 +690,12 @@ (i32.const 1) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -700,7 +722,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -710,7 +732,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -745,16 +767,20 @@ (local.get $x) (i32.const 1) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (else + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -818,7 +844,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.load @@ -826,18 +852,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -850,13 +882,21 @@ (if (result i32) (if (result i32) (i32.const 1) - (i32.load + (then + (i32.load + (i32.const 0) + ) + ) + (else (i32.const 0) ) + ) + (then (i32.const 0) ) - (i32.const 0) - (i32.const 1) + (else + (i32.const 1) + ) ) ) ;; CHECK: (func $bad-phi-value-2 (param $x i32) (result i32) @@ -870,7 +910,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.load @@ -878,18 +918,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -905,13 +951,21 @@ (if (if (result i32) (i32.const 1) - (i32.load + (then + (i32.load + (i32.const 0) + ) + ) + (else (i32.const 0) ) - (i32.const 0) ) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 2)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 2)) + ) ) (local.get $x) ) @@ -1123,8 +1177,10 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -1139,8 +1195,10 @@ (local $x f64) (if (i32.const 0) - (local.set $x - (f64.const 1) + (then + (local.set $x + (f64.const 1) + ) ) ) (local.get $x) @@ -1153,11 +1211,15 @@ ;; CHECK-NEXT: (block $label$1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -1172,8 +1234,12 @@ (block $label$1 (result f64) (if (result f64) (i32.const 0) - (f64.const 0) - (f64.const 1) + (then + (f64.const 0) + ) + (else + (f64.const 1) + ) ) ) ) @@ -1203,7 +1269,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1214,7 +1280,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1242,16 +1308,20 @@ (local.get $x) (local.get $y) ) - (local.set $i - (i32.eq - (local.get $x) - (local.get $y) + (then + (local.set $i + (i32.eq + (local.get $x) + (local.get $y) + ) ) ) - (local.set $i - (i32.add - (local.get $x) - (local.get $y) + (else + (local.set $i + (i32.add + (local.get $x) + (local.get $y) + ) ) ) ) @@ -1321,7 +1391,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1334,8 +1404,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1353,14 +1425,18 @@ (func $in-unreachable-1 (param $x i32) (param $y i32) (result i32) (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (return (local.get $x)) ) - (return (local.get $x)) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1378,7 +1454,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1388,8 +1464,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1407,14 +1485,18 @@ (func $in-unreachable-2 (param $x i32) (param $y i32) (result i32) (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (unreachable) ) - (unreachable) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1434,7 +1516,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1444,8 +1526,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1470,14 +1554,18 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (br $out) ) - (br $out) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1501,7 +1589,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1513,8 +1601,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1539,14 +1629,18 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (br_table $out $out $out (i32.const 1)) ) - (br_table $out $out $out (i32.const 1)) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1571,7 +1665,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -1580,8 +1674,10 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1606,16 +1702,20 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) - ) - (br_if $out - (local.get $x) + (then + (block + (local.set $x + (i32.const 1) + ) + (br_if $out + (local.get $x) + ) ) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; there *IS* a phi here since it was a br_if @@ -1639,12 +1739,12 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const -8531) @@ -1654,7 +1754,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const -8531) @@ -1703,19 +1803,25 @@ (block $label$3 (if (local.get $2) - (if - (local.get $0) - (block - (local.set $1 - (i32.const -8531) + (then + (if + (local.get $0) + (then + (block + (local.set $1 + (i32.const -8531) + ) + (br $label$3) + ) ) - (br $label$3) - ) - (block - (local.set $1 - (i32.const -8531) + (else + (block + (local.set $1 + (i32.const -8531) + ) + (br $label$1) + ) ) - (br $label$1) ) ) ) @@ -1749,11 +1855,15 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1770,11 +1880,15 @@ (unreachable) (if (local.get $x) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) (return @@ -2215,7 +2329,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (i64.eqz @@ -2224,7 +2338,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2235,7 +2349,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2248,7 +2362,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $15 ;; CHECK-NEXT: (i64.eqz @@ -2257,7 +2371,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2268,7 +2382,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2300,37 +2414,49 @@ (local.get $x) (local.get $y) ) - (if - (i64.eqz - (local.get $x) - ) - (local.set $t - (i64.add + (then + (if + (i64.eqz (local.get $x) - (local.get $y) ) - ) - (local.set $t - (i64.sub - (local.get $x) - (local.get $y) + (then + (local.set $t + (i64.add + (local.get $x) + (local.get $y) + ) + ) + ) + (else + (local.set $t + (i64.sub + (local.get $x) + (local.get $y) + ) + ) ) ) ) - (if - (i64.eqz - (local.get $y) - ) - (local.set $t - (i64.mul - (local.get $x) + (else + (if + (i64.eqz (local.get $y) ) - ) - (local.set $t - (i64.div_s - (local.get $x) - (local.get $y) + (then + (local.set $t + (i64.mul + (local.get $x) + (local.get $y) + ) + ) + ) + (else + (local.set $t + (i64.div_s + (local.get $x) + (local.get $y) + ) + ) ) ) ) @@ -3376,14 +3502,14 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (loop $label$2 ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block $label$3 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3396,7 +3522,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3423,23 +3549,29 @@ (func $bad-phi-type (param $var$0 i64) (param $var$1 i64) (param $var$2 i32) (param $var$3 f32) (if (local.get $var$2) - (drop - (loop $label$2 (result f64) - (if - (block $label$3 (result i32) - (if + (then + (drop + (loop $label$2 (result f64) + (if + (block $label$3 (result i32) + (if + (i32.const 0) + (then + (unreachable) + ) + ) + (nop) (i32.const 0) + ) + (then (unreachable) ) - (nop) - (i32.const 0) ) - (unreachable) - ) - (br_if $label$2 - (local.get $var$2) + (br_if $label$2 + (local.get $var$2) + ) + (f64.const 0) ) - (f64.const 0) ) ) ) @@ -3466,7 +3598,7 @@ ;; CHECK-NEXT: (block $label$4 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3532,7 +3664,9 @@ (block $label$4 (result i32) (if (i32.const 1337) - (unreachable) + (then + (unreachable) + ) ) (local.get $var$0) ) @@ -3594,11 +3728,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block ;; CHECK-NEXT: (loop $label$3 @@ -3624,7 +3758,9 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -3658,22 +3794,28 @@ (i32.const 0) ) ) - (unreachable) - (block (result f32) - (if - (loop $label$3 (result i32) - (block $label$4 (result i32) - (i32.clz - (br_if $label$4 - (local.get $var$0) - (i32.const 1) + (then + (unreachable) + ) + (else + (block (result f32) + (if + (loop $label$3 (result i32) + (block $label$4 (result i32) + (i32.clz + (br_if $label$4 + (local.get $var$0) + (i32.const 1) + ) ) ) ) + (then + (nop) + ) ) - (nop) + (f32.const 1) ) - (f32.const 1) ) ) ) @@ -3852,54 +3994,56 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (block $label$2 - ;; CHECK-NEXT: (block $label$3 - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $var$1 - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$2 + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $var$1 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $label$3 + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$3 - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (br_if $label$2 + ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$2 - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $13 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $13) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $13) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3914,33 +4058,37 @@ (i32.const -7) ) ) - (block $label$2 - (block $label$3 - (local.set $var$1 - (local.get $var$0) - ) - (br_if $label$3 - (local.tee $var$3 - (i32.const 12) + (then + (block $label$2 + (block $label$3 + (local.set $var$1 + (local.get $var$0) ) + (br_if $label$3 + (local.tee $var$3 + (i32.const 12) + ) + ) + (unreachable) ) - (unreachable) - ) - (br_if $label$2 - (i32.eqz - (local.get $var$1) + (br_if $label$2 + (i32.eqz + (local.get $var$1) + ) ) - ) - (if - (i32.ne - (i32.load - (i32.const 0) + (if + (i32.ne + (i32.load + (i32.const 0) + ) + (local.get $var$0) + ) + (then + (unreachable) ) - (local.get $var$0) ) (unreachable) ) - (unreachable) ) ) ) @@ -4164,7 +4312,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4189,7 +4337,9 @@ ) ) ) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $zext-numGets-hasAnotherUse (param $var$0 i32) (param $var$1 i32) @@ -4247,7 +4397,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4279,7 +4429,9 @@ (local.get $temp) ) ) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $flipped-needs-right-origin (param $var$0 i32) (result i32) @@ -4320,7 +4472,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4355,7 +4507,9 @@ (i32.const 4) ) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 5) ) @@ -4427,7 +4581,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $var$2 @@ -4457,14 +4611,16 @@ (loop $label$1 (if (i32.const 0) - (block - (local.set $var$2 - (i32.add - (i32.const 0) - (i32.const 1) + (then + (block + (local.set $var$2 + (i32.add + (i32.const 0) + (i32.const 1) + ) ) + (br $label$1) ) - (br $label$1) ) ) (local.set $var$3 @@ -4497,36 +4653,42 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (loop $label$2 - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $label$2 + ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $var$3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $var$1 - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.set $var$3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $var$1 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $var$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $label$2 ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $var$3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$1) - ;; CHECK-NEXT: (local.set $var$3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $var$3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4565,28 +4727,34 @@ ) (if (i32.const 0) - (loop $label$2 - (if - (local.get $var$1) - (nop) - ) - (local.set $var$1 - (i32.sub - (i32.const 0) - (local.tee $var$3 - (i32.const 1) + (then + (loop $label$2 + (if + (local.get $var$1) + (then + (nop) ) ) - ) - (br_if $label$2 - (i32.const 0) + (local.set $var$1 + (i32.sub + (i32.const 0) + (local.tee $var$3 + (i32.const 1) + ) + ) + ) + (br_if $label$2 + (i32.const 0) + ) ) ) ) (if (local.get $var$1) - (local.set $var$3 - (i32.const 1) + (then + (local.set $var$3 + (i32.const 1) + ) ) ) (i32.store diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast index e8d423058ac..5c11e34e364 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast @@ -143,7 +143,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -180,7 +180,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -197,28 +197,32 @@ (local.get $x) (local.get $y) ) - (block - (local.set $i - (i64.eq - (local.get $a) - (local.get $x) + (then + (block + (local.set $i + (i64.eq + (local.get $a) + (local.get $x) + ) ) - ) - (local.set $j - (i64.ne - (local.get $a) - (local.get $y) + (local.set $j + (i64.ne + (local.get $a) + (local.get $y) + ) ) - ) - (local.set $r - (i32.and - (local.get $i) - (local.get $j) + (local.set $r + (i32.and + (local.get $i) + (local.get $j) + ) ) + (return (local.get $r)) ) - (return (local.get $r)) ) - (unreachable) + (else + (unreachable) + ) ) ) ;; Figure 3, simplified to an if @@ -244,7 +248,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -254,7 +258,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -289,16 +293,20 @@ (local.get $x) (i32.const 1) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (else + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -445,7 +453,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -460,10 +468,12 @@ (func $various-conditions-1 (param $x i32) (if (local.get $x) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) ) @@ -482,7 +492,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -500,10 +510,12 @@ (local.get $x) (i32.const 0) ) - (local.set $x - (i32.sub - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.sub + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -519,7 +531,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -534,10 +546,12 @@ (func $various-conditions-3 (param $x i32) (if (i32.reinterpret_f32 (f32.const 0)) - (local.set $x - (i32.sub - (local.get $x) - (i32.const 4) + (then + (local.set $x + (i32.sub + (local.get $x) + (i32.const 4) + ) ) ) ) @@ -549,7 +563,7 @@ ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -566,10 +580,12 @@ (func $various-conditions-4 (param $x i32) (if (unreachable) - (local.set $x - (i32.add - (local.get $x) - (i32.const 3) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 3) + ) ) ) ) @@ -593,7 +609,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.ctz @@ -633,18 +649,20 @@ (i32.eqz (local.get $x) ) - (local.set $x - (i32.add - (i32.ctz - (local.get $y) - ) - (i32.sub - (i32.clz - (local.get $x) - ) - (i32.popcnt + (then + (local.set $x + (i32.add + (i32.ctz (local.get $y) ) + (i32.sub + (i32.clz + (local.get $x) + ) + (i32.popcnt + (local.get $y) + ) + ) ) ) ) @@ -670,7 +688,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -690,10 +708,12 @@ (i32.const 1) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -718,7 +738,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -738,10 +758,12 @@ (i32.const 1) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -768,7 +790,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -778,7 +800,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $x @@ -813,16 +835,20 @@ (local.get $x) (i32.const 1) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 1) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) ) ) - (local.set $x - (i32.add - (local.get $x) - (i32.const 2) + (else + (local.set $x + (i32.add + (local.get $x) + (i32.const 2) + ) ) ) ) @@ -886,7 +912,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.load @@ -894,18 +920,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -918,13 +950,21 @@ (if (result i32) (if (result i32) (i32.const 1) - (i32.load + (then + (i32.load + (i32.const 0) + ) + ) + (else (i32.const 0) ) + ) + (then (i32.const 0) ) - (i32.const 0) - (i32.const 1) + (else + (i32.const 1) + ) ) ) ;; CHECK: (func $bad-phi-value-2 (param $x i32) (result i32) @@ -938,7 +978,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.load @@ -946,18 +986,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -973,13 +1019,21 @@ (if (if (result i32) (i32.const 1) - (i32.load + (then + (i32.load + (i32.const 0) + ) + ) + (else (i32.const 0) ) - (i32.const 0) ) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 2)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 2)) + ) ) (local.get $x) ) @@ -1191,8 +1245,10 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -1207,8 +1263,10 @@ (local $x f64) (if (i32.const 0) - (local.set $x - (f64.const 1) + (then + (local.set $x + (f64.const 1) + ) ) ) (local.get $x) @@ -1221,11 +1279,15 @@ ;; CHECK-NEXT: (block $label$1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -1240,8 +1302,12 @@ (block $label$1 (result f64) (if (result f64) (i32.const 0) - (f64.const 0) - (f64.const 1) + (then + (f64.const 0) + ) + (else + (f64.const 1) + ) ) ) ) @@ -1271,7 +1337,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1282,7 +1348,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1310,16 +1376,20 @@ (local.get $x) (local.get $y) ) - (local.set $i - (i32.eq - (local.get $x) - (local.get $y) + (then + (local.set $i + (i32.eq + (local.get $x) + (local.get $y) + ) ) ) - (local.set $i - (i32.add - (local.get $x) - (local.get $y) + (else + (local.set $i + (i32.add + (local.get $x) + (local.get $y) + ) ) ) ) @@ -1389,7 +1459,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1402,8 +1472,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1421,14 +1493,18 @@ (func $in-unreachable-1 (param $x i32) (param $y i32) (result i32) (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (return (local.get $x)) ) - (return (local.get $x)) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1446,7 +1522,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1456,8 +1532,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1475,14 +1553,18 @@ (func $in-unreachable-2 (param $x i32) (param $y i32) (result i32) (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (unreachable) ) - (unreachable) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1502,7 +1584,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1512,8 +1594,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1538,14 +1622,18 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (br $out) ) - (br $out) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1569,7 +1657,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -1581,8 +1669,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1607,14 +1697,18 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) + (then + (block + (local.set $x + (i32.const 1) + ) + (br_table $out $out $out (i32.const 1)) ) - (br_table $out $out $out (i32.const 1)) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; no phi here! @@ -1639,7 +1733,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -1648,8 +1742,10 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1674,16 +1770,20 @@ (block $out (if (local.get $x) - (block - (local.set $x - (i32.const 1) - ) - (br_if $out - (local.get $x) + (then + (block + (local.set $x + (i32.const 1) + ) + (br_if $out + (local.get $x) + ) ) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) ;; there *IS* a phi here since it was a br_if @@ -1707,12 +1807,12 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const -8531) @@ -1722,7 +1822,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const -8531) @@ -1771,19 +1871,25 @@ (block $label$3 (if (local.get $2) - (if - (local.get $0) - (block - (local.set $1 - (i32.const -8531) + (then + (if + (local.get $0) + (then + (block + (local.set $1 + (i32.const -8531) + ) + (br $label$3) + ) ) - (br $label$3) - ) - (block - (local.set $1 - (i32.const -8531) + (else + (block + (local.set $1 + (i32.const -8531) + ) + (br $label$1) + ) ) - (br $label$1) ) ) ) @@ -1817,11 +1923,15 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1838,11 +1948,15 @@ (unreachable) (if (local.get $x) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) (return @@ -2283,7 +2397,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (i64.eqz @@ -2292,7 +2406,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2303,7 +2417,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2316,7 +2430,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $15 ;; CHECK-NEXT: (i64.eqz @@ -2325,7 +2439,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2336,7 +2450,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -2368,37 +2482,49 @@ (local.get $x) (local.get $y) ) - (if - (i64.eqz - (local.get $x) - ) - (local.set $t - (i64.add + (then + (if + (i64.eqz (local.get $x) - (local.get $y) ) - ) - (local.set $t - (i64.sub - (local.get $x) - (local.get $y) + (then + (local.set $t + (i64.add + (local.get $x) + (local.get $y) + ) + ) + ) + (else + (local.set $t + (i64.sub + (local.get $x) + (local.get $y) + ) + ) ) ) ) - (if - (i64.eqz - (local.get $y) - ) - (local.set $t - (i64.mul - (local.get $x) + (else + (if + (i64.eqz (local.get $y) ) - ) - (local.set $t - (i64.div_s - (local.get $x) - (local.get $y) + (then + (local.set $t + (i64.mul + (local.get $x) + (local.get $y) + ) + ) + ) + (else + (local.set $t + (i64.div_s + (local.get $x) + (local.get $y) + ) + ) ) ) ) @@ -3444,14 +3570,14 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$2) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (loop $label$2 ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block $label$3 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3464,7 +3590,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3491,23 +3617,29 @@ (func $bad-phi-type (param $var$0 i64) (param $var$1 i64) (param $var$2 i32) (param $var$3 f32) (if (local.get $var$2) - (drop - (loop $label$2 (result f64) - (if - (block $label$3 (result i32) - (if + (then + (drop + (loop $label$2 (result f64) + (if + (block $label$3 (result i32) + (if + (i32.const 0) + (then + (unreachable) + ) + ) + (nop) (i32.const 0) + ) + (then (unreachable) ) - (nop) - (i32.const 0) ) - (unreachable) - ) - (br_if $label$2 - (local.get $var$2) + (br_if $label$2 + (local.get $var$2) + ) + (f64.const 0) ) - (f64.const 0) ) ) ) @@ -3534,7 +3666,7 @@ ;; CHECK-NEXT: (block $label$4 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -3600,7 +3732,9 @@ (block $label$4 (result i32) (if (i32.const 1337) - (unreachable) + (then + (unreachable) + ) ) (local.get $var$0) ) @@ -3662,11 +3796,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block ;; CHECK-NEXT: (loop $label$3 @@ -3692,7 +3826,9 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) @@ -3726,22 +3862,28 @@ (i32.const 0) ) ) - (unreachable) - (block (result f32) - (if - (loop $label$3 (result i32) - (block $label$4 (result i32) - (i32.clz - (br_if $label$4 - (local.get $var$0) - (i32.const 1) + (then + (unreachable) + ) + (else + (block (result f32) + (if + (loop $label$3 (result i32) + (block $label$4 (result i32) + (i32.clz + (br_if $label$4 + (local.get $var$0) + (i32.const 1) + ) ) ) ) + (then + (nop) + ) ) - (nop) + (f32.const 1) ) - (f32.const 1) ) ) ) @@ -3920,54 +4062,56 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$0) - ;; CHECK-NEXT: (block $label$2 - ;; CHECK-NEXT: (block $label$3 - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $var$1 - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$2 + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $var$1 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $label$3 + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$3 - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (br_if $label$2 + ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$2 - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $13 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $13) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $13) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3982,33 +4126,37 @@ (i32.const -7) ) ) - (block $label$2 - (block $label$3 - (local.set $var$1 - (local.get $var$0) - ) - (br_if $label$3 - (local.tee $var$3 - (i32.const 12) + (then + (block $label$2 + (block $label$3 + (local.set $var$1 + (local.get $var$0) ) + (br_if $label$3 + (local.tee $var$3 + (i32.const 12) + ) + ) + (unreachable) ) - (unreachable) - ) - (br_if $label$2 - (i32.eqz - (local.get $var$1) + (br_if $label$2 + (i32.eqz + (local.get $var$1) + ) ) - ) - (if - (i32.ne - (i32.load - (i32.const 0) + (if + (i32.ne + (i32.load + (i32.const 0) + ) + (local.get $var$0) + ) + (then + (unreachable) ) - (local.get $var$0) ) (unreachable) ) - (unreachable) ) ) ) @@ -4232,7 +4380,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4257,7 +4405,9 @@ ) ) ) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $zext-numGets-hasAnotherUse (param $var$0 i32) (param $var$1 i32) @@ -4315,7 +4465,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4347,7 +4497,9 @@ (local.get $temp) ) ) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $flipped-needs-right-origin (param $var$0 i32) (result i32) @@ -4388,7 +4540,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -4423,7 +4575,9 @@ (i32.const 4) ) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 5) ) @@ -4495,7 +4649,7 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $var$2 @@ -4525,14 +4679,16 @@ (loop $label$1 (if (i32.const 0) - (block - (local.set $var$2 - (i32.add - (i32.const 0) - (i32.const 1) + (then + (block + (local.set $var$2 + (i32.add + (i32.const 0) + (i32.const 1) + ) ) + (br $label$1) ) - (br $label$1) ) ) (local.set $var$3 @@ -4565,36 +4721,42 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (loop $label$2 - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $label$2 + ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $var$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $var$3 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (local.set $var$1 - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.set $var$3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $var$1 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $var$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $label$2 ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $var$3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $var$1) - ;; CHECK-NEXT: (local.set $var$3 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $var$3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4633,28 +4795,34 @@ ) (if (i32.const 0) - (loop $label$2 - (if - (local.get $var$1) - (nop) - ) - (local.set $var$1 - (i32.sub - (i32.const 0) - (local.tee $var$3 - (i32.const 1) + (then + (loop $label$2 + (if + (local.get $var$1) + (then + (nop) ) ) - ) - (br_if $label$2 - (i32.const 0) + (local.set $var$1 + (i32.sub + (i32.const 0) + (local.tee $var$3 + (i32.const 1) + ) + ) + ) + (br_if $label$2 + (i32.const 0) + ) ) ) ) (if (local.get $var$1) - (local.set $var$3 - (i32.const 1) + (then + (local.set $var$3 + (i32.const 1) + ) ) ) (i32.store diff --git a/test/lit/passes/global-effects.wast b/test/lit/passes/global-effects.wast index 06660467948..00c9a77ff71 100644 --- a/test/lit/passes/global-effects.wast +++ b/test/lit/passes/global-effects.wast @@ -330,8 +330,12 @@ ;; WITHOUT-NEXT: (do ;; WITHOUT-NEXT: (if ;; WITHOUT-NEXT: (local.get $x) - ;; WITHOUT-NEXT: (call $throw) - ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: (then + ;; WITHOUT-NEXT: (call $throw) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (else + ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: (catch_all @@ -344,8 +348,12 @@ ;; INCLUDE-NEXT: (do ;; INCLUDE-NEXT: (if ;; INCLUDE-NEXT: (local.get $x) - ;; INCLUDE-NEXT: (call $throw) - ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: (then + ;; INCLUDE-NEXT: (call $throw) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (else + ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: (catch_all @@ -358,8 +366,12 @@ ;; DISCARD-NEXT: (do ;; DISCARD-NEXT: (if ;; DISCARD-NEXT: (local.get $x) - ;; DISCARD-NEXT: (call $throw) - ;; DISCARD-NEXT: (call $unreachable) + ;; DISCARD-NEXT: (then + ;; DISCARD-NEXT: (call $throw) + ;; DISCARD-NEXT: ) + ;; DISCARD-NEXT: (else + ;; DISCARD-NEXT: (call $unreachable) + ;; DISCARD-NEXT: ) ;; DISCARD-NEXT: ) ;; DISCARD-NEXT: ) ;; DISCARD-NEXT: (catch_all @@ -374,8 +386,12 @@ (do (if (local.get $x) - (call $throw) - (call $unreachable) + (then + (call $throw) + ) + (else + (call $unreachable) + ) ) ) (catch_all) @@ -407,8 +423,12 @@ (func $throw-and-import (if (i32.const 1) - (throw $tag) - (call $import) + (then + (throw $tag) + ) + (else + (call $import) + ) ) ) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index 6aa741eb1b7..6d997dfa547 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -1396,11 +1396,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $parent - ;; CHECK-NEXT: (local.tee $child - ;; CHECK-NEXT: (struct.new $child - ;; CHECK-NEXT: (i32.const 20) - ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $parent + ;; CHECK-NEXT: (local.tee $child + ;; CHECK-NEXT: (struct.new $child + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1432,11 +1434,13 @@ ;; Another, optional, set to $parent. (if (local.get $x) - (local.set $parent - (local.tee $child - (struct.new $child - (i32.const 20) - (i32.const 30) + (then + (local.set $parent + (local.tee $child + (struct.new $child + (i32.const 20) + (i32.const 30) + ) ) ) ) @@ -3308,8 +3312,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $ref-null - ;; CHECK-NEXT: (local.get $ref) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $ref-null + ;; CHECK-NEXT: (local.get $ref) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -3330,8 +3336,10 @@ ) (if (local.get $x) - (local.set $ref-null - (local.get $ref) + (then + (local.set $ref-null + (local.get $ref) + ) ) ) ;; If the |if| executed they are equal, but otherwise not, so we can't diff --git a/test/lit/passes/gufa-ssa.wast b/test/lit/passes/gufa-ssa.wast index c97e30a62b9..355999f6171 100644 --- a/test/lit/passes/gufa-ssa.wast +++ b/test/lit/passes/gufa-ssa.wast @@ -40,8 +40,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 30) - ;; CHECK-NEXT: (local.set $y - ;; CHECK-NEXT: (i32.const 50) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 50) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -89,8 +91,10 @@ ) (if (local.get $x) - (local.set $y - (i32.const 50) + (then + (local.set $y + (i32.const 50) + ) ) ) ;; x is the same but y is no longer optimizable, since it might contain 50. diff --git a/test/lit/passes/gufa-tnh.wast b/test/lit/passes/gufa-tnh.wast index b3d5b122b67..cb363c567ea 100644 --- a/test/lit/passes/gufa-tnh.wast +++ b/test/lit/passes/gufa-tnh.wast @@ -465,7 +465,9 @@ ;; CHECK-NEXT: (local $local (ref null $A)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $B) @@ -478,7 +480,9 @@ ;; Control flow before the cast *does* stop us from optimizing. (if (i32.const 0) - (return) + (then + (return) + ) ) (drop (ref.cast (ref $B) @@ -689,7 +693,9 @@ ;; CHECK-NEXT: (block (result (ref $B)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.cast (ref $B) ;; CHECK-NEXT: (local.get $any) @@ -717,7 +723,9 @@ (block (result (ref $A)) (if (i32.const 0) - (return) + (then + (return) + ) ) (ref.cast (ref $A) (local.get $any) @@ -788,7 +796,9 @@ ;; CHECK-NEXT: (block (result (ref $A)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.cast (ref $A) ;; CHECK-NEXT: (local.get $any) @@ -814,7 +824,9 @@ (block (result (ref $A)) (if (i32.const 0) - (return) + (then + (return) + ) ) (ref.cast (ref $A) (local.get $any) @@ -976,9 +988,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result (ref $A)) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (ref.cast (ref $A) - ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $any) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.cast (ref $B) @@ -997,9 +1013,13 @@ ;; very last cast. (if (result (ref $A)) (i32.const 0) - (return) - (ref.cast (ref $A) - (local.get $any) + (then + (return) + ) + (else + (ref.cast (ref $A) + (local.get $any) + ) ) ) (ref.cast (ref $A) diff --git a/test/lit/passes/gufa-vs-cfp.wast b/test/lit/passes/gufa-vs-cfp.wast index eb365c5d12e..eb95c6bed03 100644 --- a/test/lit/passes/gufa-vs-cfp.wast +++ b/test/lit/passes/gufa-vs-cfp.wast @@ -381,8 +381,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result f32) ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (f32.const 42) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (f32.const 42) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (f32.const 42) @@ -395,8 +399,12 @@ ;; Fall though a 42 via an if. (if (result f32) (call $import) - (unreachable) - (f32.const 42) + (then + (unreachable) + ) + (else + (f32.const 42) + ) ) ) ) diff --git a/test/lit/passes/gufa.wast b/test/lit/passes/gufa.wast index b97e620ab62..fcb60310ad4 100644 --- a/test/lit/passes/gufa.wast +++ b/test/lit/passes/gufa.wast @@ -104,8 +104,10 @@ ;; CHECK: (func $return (type $0) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) @@ -116,8 +118,10 @@ ;; below. (if (i32.const 0) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (i32.const 2) @@ -139,8 +143,10 @@ ;; CHECK: (func $return-same (type $0) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) @@ -152,8 +158,10 @@ ;; but see the caller below. (if (i32.const 0) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (i32.const 1) @@ -180,8 +188,10 @@ ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) @@ -190,8 +200,10 @@ (local $x i32) (if (call $import) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) ) ;; $x has two possible values, 1 and the default 0, so we cannot optimize @@ -203,8 +215,10 @@ ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $import) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -213,10 +227,12 @@ (local $x i32) (if (call $import) - (local.set $x - ;; As above, but now we set 0 here. We can optimize the local.get to 0 - ;; in this case. - (i32.const 0) + (then + (local.set $x + ;; As above, but now we set 0 here. We can optimize the local.get to 0 + ;; in this case. + (i32.const 0) + ) ) ) (local.get $x) @@ -225,8 +241,10 @@ ;; CHECK: (func $param-no (type $3) (param $param i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (local.set $param - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $param + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $param) @@ -234,8 +252,10 @@ (func $param-no (export "param-no") (param $param i32) (result i32) (if (local.get $param) - (local.set $param - (i32.const 1) + (then + (local.set $param + (i32.const 1) + ) ) ) ;; $x has two possible values, the incoming param value and 1, so we cannot @@ -247,8 +267,10 @@ ;; CHECK: (func $param-yes (type $3) (param $param i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (local.set $param - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $param + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) @@ -260,8 +282,10 @@ ;; local.set in the if, so we'll optimize it to 1. (if (local.get $param) - (local.set $param - (i32.const 1) + (then + (local.set $param + (i32.const 1) + ) ) ) (local.get $param) @@ -523,8 +547,10 @@ ;; CHECK-NEXT: (block $named (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $named - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $named + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) @@ -537,8 +563,10 @@ ;; CHECK-NEXT: (block $named0 (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $named0 - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $named0 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) @@ -551,8 +579,10 @@ (block $named (result i32) (if (i32.const 0) - (br $named - (i32.const 1) + (then + (br $named + (i32.const 1) + ) ) ) (i32.const 1) @@ -564,8 +594,10 @@ (block $named (result i32) (if (i32.const 0) - (br $named - (i32.const 2) ;; this changed + (then + (br $named + (i32.const 2) ;; this changed + ) ) ) (i32.const 1) diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 37a9e791905..286bfdc19b2 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -646,8 +646,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block (result f64) @@ -666,8 +668,10 @@ ;; that as a result of this the final local.get has two sets that send it ;; values, but we know they are both the same allocation. (if (local.get $x) - (local.set $ref - (local.get $ref) + (then + (local.set $ref + (local.get $ref) + ) ) ) (struct.get $struct.A 1 @@ -726,8 +730,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $ref - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $ref + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (struct.get $struct.A 1 @@ -740,8 +746,10 @@ (struct.new_default $struct.A) ) (if (local.get $x) - (local.set $ref - (ref.null $struct.A) + (then + (local.set $ref + (ref.null $struct.A) + ) ) ) ;; A get that receives two different allocations, and so we should not try @@ -985,15 +993,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result f64) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -1025,20 +1035,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result f64) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1062,14 +1076,18 @@ ) ) (if (local.get $x) - (drop - (struct.get $struct.A 1 - (local.get $ref) + (then + (drop + (struct.get $struct.A 1 + (local.get $ref) + ) ) ) - (struct.set $struct.A 1 - (local.get $ref) - (f64.const 42) + (else + (struct.set $struct.A 1 + (local.get $ref) + (f64.const 42) + ) ) ) (loop $inner @@ -1087,14 +1105,18 @@ ) ) (if (local.get $x) - (drop - (struct.get $struct.A 0 - (local.get $ref) + (then + (drop + (struct.get $struct.A 0 + (local.get $ref) + ) ) ) - (drop - (struct.get $struct.A 1 - (local.get $ref) + (else + (drop + (struct.get $struct.A 1 + (local.get $ref) + ) ) ) ) diff --git a/test/lit/passes/inlining-optimizing_optimize-level=3.wast b/test/lit/passes/inlining-optimizing_optimize-level=3.wast index a0e320bd640..fdfbf7b35d6 100644 --- a/test/lit/passes/inlining-optimizing_optimize-level=3.wast +++ b/test/lit/passes/inlining-optimizing_optimize-level=3.wast @@ -175,7 +175,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -204,7 +206,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.get $1) ) @@ -245,7 +249,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $__THREW__) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $__THREW__ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -260,12 +264,14 @@ (i32.eqz (global.get $__THREW__) ) - (block - (global.set $__THREW__ - (local.get $0) - ) - (global.set $threwValue - (local.get $1) + (then + (block + (global.set $__THREW__ + (local.get $0) + ) + (global.set $threwValue + (local.get $1) + ) ) ) ) @@ -315,7 +321,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (global.get $STACKTOP) @@ -331,7 +339,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $6) @@ -356,7 +366,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.add @@ -418,8 +430,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load offset=76 ;; CHECK-NEXT: (local.get $0) @@ -437,11 +451,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const -33) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const -33) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -454,16 +470,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $_printf_core - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 672) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $_printf_core + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 672) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.tee $9 @@ -523,7 +541,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) ;; CHECK-NEXT: (local.get $0) @@ -612,7 +630,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (drop (call $_printf @@ -668,7 +688,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (call $_frexp ;; CHECK-NEXT: (f64.mul @@ -685,7 +705,9 @@ ;; CHECK-NEXT: (i32.const -64) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -765,24 +787,28 @@ (local.get $0) (f64.const 0) ) - (block (result i32) - (local.set $0 - (call $_frexp - (f64.mul - (local.get $0) - (f64.const 18446744073709551615) + (then + (block (result i32) + (local.set $0 + (call $_frexp + (f64.mul + (local.get $0) + (f64.const 18446744073709551615) + ) + (local.get $1) ) - (local.get $1) ) - ) - (i32.add - (i32.load - (local.get $1) + (i32.add + (i32.load + (local.get $1) + ) + (i32.const -64) ) - (i32.const -64) ) ) - (i32.const 0) + (else + (i32.const 0) + ) ) ) ) @@ -877,14 +903,18 @@ (i32.load8_s (local.get $0) ) - (block + (then + (block + (local.set $0 + (local.get $2) + ) + (br $while-in3) + ) + ) + (else (local.set $0 (local.get $2) ) - (br $while-in3) - ) - (local.set $0 - (local.get $2) ) ) ) @@ -905,10 +935,14 @@ ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load offset=60 - ;; CHECK-NEXT: (call $_pthread_self) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.load offset=60 + ;; CHECK-NEXT: (call $_pthread_self) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 60) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 60) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $___errno_location (result i32) @@ -916,10 +950,14 @@ (i32.load (i32.const 16) ) - (i32.load offset=60 - (call $_pthread_self) + (then + (i32.load offset=60 + (call $_pthread_self) + ) + ) + (else + (i32.const 60) ) - (i32.const 60) ) ) ;; CHECK: (func $___stdio_close (param $0 i32) (result i32) @@ -939,7 +977,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.tee $2 @@ -979,7 +1019,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (i32.store (local.tee $2 @@ -1020,7 +1062,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $4) @@ -1044,7 +1088,7 @@ ;; CHECK-NEXT: (i32.const 64) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.load offset=60 @@ -1064,9 +1108,11 @@ ;; CHECK-NEXT: (i32.const 54) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=75 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 offset=75 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1101,7 +1147,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.set $3 (local.get $4) @@ -1125,29 +1173,33 @@ (i32.const 64) ) ) - (block - (i32.store - (local.get $3) - (i32.load offset=60 - (local.get $0) + (then + (block + (i32.store + (local.get $3) + (i32.load offset=60 + (local.get $0) + ) ) - ) - (i32.store offset=4 - (local.get $3) - (i32.const 21505) - ) - (i32.store offset=8 - (local.get $3) - (local.get $5) - ) - (if - (call $___syscall54 - (i32.const 54) + (i32.store offset=4 (local.get $3) + (i32.const 21505) ) - (i32.store8 offset=75 - (local.get $0) - (i32.const -1) + (i32.store offset=8 + (local.get $3) + (local.get $5) + ) + (if + (call $___syscall54 + (i32.const 54) + (local.get $3) + ) + (then + (i32.store8 offset=75 + (local.get $0) + (i32.const -1) + ) + ) ) ) ) @@ -1181,7 +1233,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.tee $3 @@ -1223,15 +1277,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1257,7 +1313,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (i32.store (local.tee $3 @@ -1299,15 +1357,19 @@ ) (i32.const 0) ) - (block (result i32) - (i32.store - (local.get $0) + (then + (block (result i32) + (i32.store + (local.get $0) + (i32.const -1) + ) (i32.const -1) ) - (i32.const -1) ) - (i32.load - (local.get $0) + (else + (i32.load + (local.get $0) + ) ) ) ) @@ -1320,29 +1382,33 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (block $do-once (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (i32.load offset=76 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (block $do-once (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.load offset=76 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $do-once + ;; CHECK-NEXT: (call $___fflush_unlocked + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (call $___fflush_unlocked ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (call $___fflush_unlocked - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.tee $0 @@ -1350,10 +1416,14 @@ ;; CHECK-NEXT: (i32.const 12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_fflush - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_fflush + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $___lock @@ -1365,34 +1435,38 @@ ;; CHECK-NEXT: (i32.const 40) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load offset=76 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (i32.load offset=20 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load offset=28 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=76 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (call $___fflush_unlocked + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.load offset=20 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load offset=28 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $___fflush_unlocked + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load offset=56 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (br_if $while-in + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load offset=56 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1411,121 +1485,145 @@ (block $do-once (if (local.get $0) - (block - (if - (i32.le_s - (i32.load offset=76 - (local.get $0) + (then + (block + (if + (i32.le_s + (i32.load offset=76 + (local.get $0) + ) + (i32.const -1) + ) + (then + (block + (local.set $0 + (call $___fflush_unlocked + (local.get $0) + ) + ) + (br $do-once) + ) ) - (i32.const -1) ) - (block - (local.set $0 - (call $___fflush_unlocked + (local.set $2 + (i32.eqz + (call $___lockfile (local.get $0) ) ) - (br $do-once) ) - ) - (local.set $2 - (i32.eqz - (call $___lockfile + (local.set $1 + (call $___fflush_unlocked (local.get $0) ) ) - ) - (local.set $1 - (call $___fflush_unlocked - (local.get $0) - ) - ) - (local.set $0 - (if (result i32) - (local.get $2) - (local.get $1) - (block (result i32) - (call $___unlockfile - (local.get $0) + (local.set $0 + (if (result i32) + (local.get $2) + (then + (local.get $1) + ) + (else + (block (result i32) + (call $___unlockfile + (local.get $0) + ) + (local.get $1) + ) ) - (local.get $1) ) ) ) ) - (block - (local.set $0 - (if (result i32) - (i32.load - (i32.const 12) - ) - (call $_fflush + (else + (block + (local.set $0 + (if (result i32) (i32.load (i32.const 12) ) - ) - (i32.const 0) - ) - ) - (call $___lock - (i32.const 44) - ) - (if - (local.tee $1 - (i32.load - (i32.const 40) - ) - ) - (loop $while-in - (local.set $2 - (if (result i32) - (i32.gt_s - (i32.load offset=76 - (local.get $1) + (then + (call $_fflush + (i32.load + (i32.const 12) ) - (i32.const -1) - ) - (call $___lockfile - (local.get $1) ) + ) + (else (i32.const 0) ) ) - (if - (i32.gt_u - (i32.load offset=20 - (local.get $1) + ) + (call $___lock + (i32.const 44) + ) + (if + (local.tee $1 + (i32.load + (i32.const 40) + ) + ) + (then + (loop $while-in + (local.set $2 + (if (result i32) + (i32.gt_s + (i32.load offset=76 + (local.get $1) + ) + (i32.const -1) + ) + (then + (call $___lockfile + (local.get $1) + ) + ) + (else + (i32.const 0) + ) + ) ) - (i32.load offset=28 - (local.get $1) + (if + (i32.gt_u + (i32.load offset=20 + (local.get $1) + ) + (i32.load offset=28 + (local.get $1) + ) + ) + (then + (local.set $0 + (i32.or + (call $___fflush_unlocked + (local.get $1) + ) + (local.get $0) + ) + ) + ) ) - ) - (local.set $0 - (i32.or - (call $___fflush_unlocked - (local.get $1) + (if + (local.get $2) + (then + (call $___unlockfile + (local.get $1) + ) ) - (local.get $0) ) - ) - ) - (if - (local.get $2) - (call $___unlockfile - (local.get $1) - ) - ) - (br_if $while-in - (local.tee $1 - (i32.load offset=56 - (local.get $1) + (br_if $while-in + (local.tee $1 + (i32.load offset=56 + (local.get $1) + ) + ) ) ) ) ) - ) - (call $___unlock - (i32.const 44) + (call $___unlock + (i32.const 44) + ) ) ) ) @@ -1549,7 +1647,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (i32.store (local.tee $3 @@ -1604,7 +1704,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $9 ;; CHECK-NEXT: (i32.add @@ -1689,7 +1791,7 @@ ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $_pthread_cleanup_push ;; CHECK-NEXT: (i32.const 5) ;; CHECK-NEXT: (local.get $0) @@ -1720,7 +1822,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: (i32.load @@ -1767,7 +1869,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (local.tee $7 @@ -1802,13 +1904,13 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.add @@ -1825,8 +1927,10 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $3) @@ -1908,11 +2012,15 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1950,7 +2058,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.set $9 (i32.add @@ -2035,57 +2145,61 @@ (i32.load (i32.const 16) ) - (block - (call $_pthread_cleanup_push - (i32.const 5) - (local.get $0) - ) - (i32.store - (local.get $10) - (i32.load - (local.get $13) + (then + (block + (call $_pthread_cleanup_push + (i32.const 5) + (local.get $0) ) - ) - (i32.store offset=4 - (local.get $10) - (local.get $1) - ) - (i32.store offset=8 - (local.get $10) - (local.get $4) - ) - (local.set $3 - (call $___syscall_ret - (call $___syscall146 - (i32.const 146) - (local.get $10) + (i32.store + (local.get $10) + (i32.load + (local.get $13) ) ) - ) - (call $_pthread_cleanup_pop - (i32.const 0) + (i32.store offset=4 + (local.get $10) + (local.get $1) + ) + (i32.store offset=8 + (local.get $10) + (local.get $4) + ) + (local.set $3 + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (local.get $10) + ) + ) + ) + (call $_pthread_cleanup_pop + (i32.const 0) + ) ) ) - (block - (i32.store - (local.get $9) - (i32.load - (local.get $13) + (else + (block + (i32.store + (local.get $9) + (i32.load + (local.get $13) + ) ) - ) - (i32.store offset=4 - (local.get $9) - (local.get $1) - ) - (i32.store offset=8 - (local.get $9) - (local.get $4) - ) - (local.set $3 - (call $___syscall_ret - (call $___syscall146 - (i32.const 146) - (local.get $9) + (i32.store offset=4 + (local.get $9) + (local.get $1) + ) + (i32.store offset=8 + (local.get $9) + (local.get $4) + ) + (local.set $3 + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (local.get $9) + ) ) ) ) @@ -2113,79 +2227,87 @@ ) ) ) - (block (result i32) - (i32.store - (local.get $6) - (local.tee $7 - (i32.load - (local.get $14) + (then + (block (result i32) + (i32.store + (local.get $6) + (local.tee $7 + (i32.load + (local.get $14) + ) ) ) - ) - (i32.store - (local.get $11) - (local.get $7) - ) - (local.set $7 - (i32.load offset=12 - (local.get $1) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 8) - ) - ) - (local.set $4 - (i32.add - (local.get $4) - (i32.const -1) - ) - ) - (i32.sub - (local.get $3) - (local.get $5) - ) - ) - (block (result i32) - (if - (i32.eq - (local.get $4) - (i32.const 2) + (i32.store + (local.get $11) + (local.get $7) ) - (block - (i32.store - (local.get $6) - (i32.add - (i32.load - (local.get $6) - ) - (local.get $3) - ) + (local.set $7 + (i32.load offset=12 + (local.get $1) ) - (local.set $7 - (local.get $5) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 8) ) - (local.set $4 - (i32.const 2) + ) + (local.set $4 + (i32.add + (local.get $4) + (i32.const -1) ) ) - (local.set $7 + (i32.sub + (local.get $3) (local.get $5) ) ) - (local.get $3) - ) - ) - ) - (i32.store - (local.get $1) - (i32.add - (i32.load - (local.get $1) ) - (local.get $5) + (else + (block (result i32) + (if + (i32.eq + (local.get $4) + (i32.const 2) + ) + (then + (block + (i32.store + (local.get $6) + (i32.add + (i32.load + (local.get $6) + ) + (local.get $3) + ) + ) + (local.set $7 + (local.get $5) + ) + (local.set $4 + (i32.const 2) + ) + ) + ) + (else + (local.set $7 + (local.get $5) + ) + ) + ) + (local.get $3) + ) + ) + ) + ) + (i32.store + (local.get $1) + (i32.add + (i32.load + (local.get $1) + ) + (local.get $5) ) ) (i32.store offset=4 @@ -2254,11 +2376,15 @@ (local.get $4) (i32.const 2) ) - (i32.const 0) - (i32.sub - (local.get $2) - (i32.load offset=4 - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.sub + (local.get $2) + (i32.load offset=4 + (local.get $1) + ) ) ) ) @@ -2296,7 +2422,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.set $5 (i32.add @@ -2361,217 +2489,235 @@ ) (i32.const 0) ) - (i32.const -1) - (block (result i32) - (local.set $14 - (if (result i32) - (i32.gt_s - (i32.load offset=76 - (local.get $0) + (then + (i32.const -1) + ) + (else + (block (result i32) + (local.set $14 + (if (result i32) + (i32.gt_s + (i32.load offset=76 + (local.get $0) + ) + (i32.const -1) ) - (i32.const -1) - ) - (call $___lockfile - (local.get $0) - ) - (i32.const 0) - ) - ) - (local.set $10 - (i32.load - (local.get $0) - ) - ) - (if - (i32.lt_s - (i32.load8_s offset=74 - (local.get $0) - ) - (i32.const 1) - ) - (i32.store - (local.get $0) - (i32.and - (local.get $10) - (i32.const -33) - ) - ) - ) - (if - (i32.load - (local.tee $11 - (i32.add - (local.get $0) - (i32.const 48) + (then + (call $___lockfile + (local.get $0) + ) + ) + (else + (i32.const 0) ) ) ) - (local.set $1 - (call $_printf_core + (local.set $10 + (i32.load (local.get $0) - (local.get $1) - (local.get $5) - (local.get $7) - (local.get $8) ) ) - (block - (local.set $13 - (i32.load - (local.tee $12 - (i32.add - (local.get $0) - (i32.const 44) - ) - ) + (if + (i32.lt_s + (i32.load8_s offset=74 + (local.get $0) ) + (i32.const 1) ) - (i32.store - (local.get $12) - (local.get $6) - ) - (i32.store - (local.tee $9 - (i32.add - (local.get $0) - (i32.const 28) + (then + (i32.store + (local.get $0) + (i32.and + (local.get $10) + (i32.const -33) ) ) - (local.get $6) ) - (i32.store - (local.tee $3 + ) + (if + (i32.load + (local.tee $11 (i32.add (local.get $0) - (i32.const 20) + (i32.const 48) ) ) - (local.get $6) ) - (i32.store - (local.get $11) - (i32.const 80) - ) - (i32.store - (local.tee $2 - (i32.add + (then + (local.set $1 + (call $_printf_core (local.get $0) - (i32.const 16) + (local.get $1) + (local.get $5) + (local.get $7) + (local.get $8) ) ) - (i32.add - (local.get $6) - (i32.const 80) - ) - ) - (local.set $1 - (call $_printf_core - (local.get $0) - (local.get $1) - (local.get $5) - (local.get $7) - (local.get $8) - ) ) - (if - (local.get $13) + (else (block - (drop - (call_indirect (type $FUNCSIG$iiii) - (local.get $0) - (i32.const 0) - (i32.const 0) - (i32.add - (i32.and - (i32.load offset=36 - (local.get $0) - ) - (i32.const 7) + (local.set $13 + (i32.load + (local.tee $12 + (i32.add + (local.get $0) + (i32.const 44) ) - (i32.const 2) - ) - ) - ) - (local.set $1 - (select - (local.get $1) - (i32.const -1) - (i32.load - (local.get $3) ) ) ) (i32.store (local.get $12) - (local.get $13) + (local.get $6) ) (i32.store - (local.get $11) - (i32.const 0) + (local.tee $9 + (i32.add + (local.get $0) + (i32.const 28) + ) + ) + (local.get $6) ) (i32.store - (local.get $2) - (i32.const 0) + (local.tee $3 + (i32.add + (local.get $0) + (i32.const 20) + ) + ) + (local.get $6) ) (i32.store - (local.get $9) - (i32.const 0) + (local.get $11) + (i32.const 80) ) (i32.store - (local.get $3) - (i32.const 0) + (local.tee $2 + (i32.add + (local.get $0) + (i32.const 16) + ) + ) + (i32.add + (local.get $6) + (i32.const 80) + ) ) - ) - ) - ) - ) - (i32.store - (local.get $0) - (i32.or - (local.tee $2 - (i32.load - (local.get $0) - ) - ) - (i32.and - (local.get $10) - (i32.const 32) - ) - ) - ) - (if - (local.get $14) - (call $___unlockfile - (local.get $0) - ) - ) - (select - (i32.const -1) - (local.get $1) - (i32.and - (local.get $2) - (i32.const 32) - ) - ) - ) - ) - ) - (global.set $STACKTOP - (local.get $4) - ) - (local.get $0) - ) - ;; CHECK: (func $___fwritex (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - ;; CHECK-NEXT: (local $3 i32) - ;; CHECK-NEXT: (local $4 i32) - ;; CHECK-NEXT: (local $5 i32) - ;; CHECK-NEXT: (local $6 i32) - ;; CHECK-NEXT: (block $label$break$L5 - ;; CHECK-NEXT: (block $__rjti$0 - ;; CHECK-NEXT: (br_if $__rjti$0 - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $5 + (local.set $1 + (call $_printf_core + (local.get $0) + (local.get $1) + (local.get $5) + (local.get $7) + (local.get $8) + ) + ) + (if + (local.get $13) + (then + (block + (drop + (call_indirect (type $FUNCSIG$iiii) + (local.get $0) + (i32.const 0) + (i32.const 0) + (i32.add + (i32.and + (i32.load offset=36 + (local.get $0) + ) + (i32.const 7) + ) + (i32.const 2) + ) + ) + ) + (local.set $1 + (select + (local.get $1) + (i32.const -1) + (i32.load + (local.get $3) + ) + ) + ) + (i32.store + (local.get $12) + (local.get $13) + ) + (i32.store + (local.get $11) + (i32.const 0) + ) + (i32.store + (local.get $2) + (i32.const 0) + ) + (i32.store + (local.get $9) + (i32.const 0) + ) + (i32.store + (local.get $3) + (i32.const 0) + ) + ) + ) + ) + ) + ) + ) + (i32.store + (local.get $0) + (i32.or + (local.tee $2 + (i32.load + (local.get $0) + ) + ) + (i32.and + (local.get $10) + (i32.const 32) + ) + ) + ) + (if + (local.get $14) + (then + (call $___unlockfile + (local.get $0) + ) + ) + ) + (select + (i32.const -1) + (local.get $1) + (i32.and + (local.get $2) + (i32.const 32) + ) + ) + ) + ) + ) + ) + (global.set $STACKTOP + (local.get $4) + ) + (local.get $0) + ) + ;; CHECK: (func $___fwritex (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (block $label$break$L5 + ;; CHECK-NEXT: (block $__rjti$0 + ;; CHECK-NEXT: (br_if $__rjti$0 + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $5 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 16) @@ -2611,7 +2757,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.or @@ -2621,7 +2767,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store offset=8 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 0) @@ -2654,8 +2800,10 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.get $5) @@ -2684,7 +2832,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) ;; CHECK-NEXT: (local.get $2) @@ -2712,81 +2860,85 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$break$L10 (result i32) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_if $label$break$L10 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$break$L10 (result i32) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_if $label$break$L10 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$break$L5 - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load offset=36 - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (br_if $label$break$L5 + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load offset=36 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -2837,16 +2989,20 @@ (call $___towrite (local.get $2) ) - (local.set $3 - (i32.const 0) - ) - (block + (then (local.set $3 - (i32.load - (local.get $4) + (i32.const 0) + ) + ) + (else + (block + (local.set $3 + (i32.load + (local.get $4) + ) ) + (br $__rjti$0) ) - (br $__rjti$0) ) ) (br $label$break$L5) @@ -2868,24 +3024,26 @@ ) (local.get $1) ) - (block - (local.set $3 - (call_indirect (type $FUNCSIG$iiii) - (local.get $2) - (local.get $0) - (local.get $1) - (i32.add - (i32.and - (i32.load offset=36 - (local.get $2) + (then + (block + (local.set $3 + (call_indirect (type $FUNCSIG$iiii) + (local.get $2) + (local.get $0) + (local.get $1) + (i32.add + (i32.and + (i32.load offset=36 + (local.get $2) + ) + (i32.const 7) ) - (i32.const 7) + (i32.const 2) ) - (i32.const 2) ) ) + (br $label$break$L5) ) - (br $label$break$L5) ) ) (local.set $2 @@ -2897,81 +3055,87 @@ ) (i32.const -1) ) - (block (result i32) - (local.set $3 - (local.get $1) - ) - (loop $while-in - (drop - (br_if $label$break$L10 - (i32.const 0) - (i32.eqz - (local.get $3) - ) - ) + (then + (block (result i32) + (local.set $3 + (local.get $1) ) - (if - (i32.ne - (i32.load8_s - (i32.add - (local.get $0) - (local.tee $6 - (i32.add - (local.get $3) - (i32.const -1) + (loop $while-in + (drop + (br_if $label$break$L10 + (i32.const 0) + (i32.eqz + (local.get $3) + ) + ) + ) + (if + (i32.ne + (i32.load8_s + (i32.add + (local.get $0) + (local.tee $6 + (i32.add + (local.get $3) + (i32.const -1) + ) ) ) ) + (i32.const 10) ) - (i32.const 10) - ) - (block - (local.set $3 - (local.get $6) + (then + (block + (local.set $3 + (local.get $6) + ) + (br $while-in) + ) ) - (br $while-in) ) ) - ) - (br_if $label$break$L5 - (i32.lt_u - (call_indirect (type $FUNCSIG$iiii) - (local.get $2) - (local.get $0) - (local.get $3) - (i32.add - (i32.and - (i32.load offset=36 - (local.get $2) + (br_if $label$break$L5 + (i32.lt_u + (call_indirect (type $FUNCSIG$iiii) + (local.get $2) + (local.get $0) + (local.get $3) + (i32.add + (i32.and + (i32.load offset=36 + (local.get $2) + ) + (i32.const 7) ) - (i32.const 7) + (i32.const 2) ) - (i32.const 2) ) + (local.get $3) ) - (local.get $3) ) - ) - (local.set $4 - (i32.load - (local.get $5) + (local.set $4 + (i32.load + (local.get $5) + ) ) - ) - (local.set $1 - (i32.sub - (local.get $1) - (local.get $3) + (local.set $1 + (i32.sub + (local.get $1) + (local.get $3) + ) ) - ) - (local.set $0 - (i32.add - (local.get $0) - (local.get $3) + (local.set $0 + (i32.add + (local.get $0) + (local.get $3) + ) ) + (local.get $3) ) - (local.get $3) ) - (i32.const 0) + (else + (i32.const 0) + ) ) ) ) @@ -3033,47 +3197,51 @@ ) (i32.const 8) ) - (block (result i32) - (i32.store - (local.get $0) - (i32.or - (local.get $1) - (i32.const 32) + (then + (block (result i32) + (i32.store + (local.get $0) + (i32.or + (local.get $1) + (i32.const 32) + ) ) + (i32.const -1) ) - (i32.const -1) ) - (block (result i32) - (i32.store offset=8 - (local.get $0) - (i32.const 0) - ) - (i32.store offset=4 - (local.get $0) - (i32.const 0) - ) - (i32.store offset=28 - (local.get $0) - (local.tee $1 - (i32.load offset=44 - (local.get $0) + (else + (block (result i32) + (i32.store offset=8 + (local.get $0) + (i32.const 0) + ) + (i32.store offset=4 + (local.get $0) + (i32.const 0) + ) + (i32.store offset=28 + (local.get $0) + (local.tee $1 + (i32.load offset=44 + (local.get $0) + ) ) ) - ) - (i32.store offset=20 - (local.get $0) - (local.get $1) - ) - (i32.store offset=16 - (local.get $0) - (i32.add + (i32.store offset=20 + (local.get $0) (local.get $1) - (i32.load offset=48 - (local.get $0) + ) + (i32.store offset=16 + (local.get $0) + (i32.add + (local.get $1) + (i32.load offset=48 + (local.get $0) + ) ) ) + (i32.const 0) ) - (i32.const 0) ) ) ) @@ -3082,365 +3250,391 @@ (block $do-once (result i32) (if (result i32) (local.get $0) - (block (result i32) - (if - (i32.lt_u - (local.get $1) - (i32.const 128) - ) - (block - (i32.store8 - (local.get $0) + (then + (block (result i32) + (if + (i32.lt_u (local.get $1) + (i32.const 128) ) - (br $do-once - (i32.const 1) - ) - ) - ) - (if - (i32.lt_u - (local.get $1) - (i32.const 2048) - ) - (block - (i32.store8 - (local.get $0) - (i32.or - (i32.shr_u + (then + (block + (i32.store8 + (local.get $0) (local.get $1) - (i32.const 6) ) - (i32.const 192) - ) - ) - (i32.store8 offset=1 - (local.get $0) - (i32.or - (i32.and - (local.get $1) - (i32.const 63) + (br $do-once + (i32.const 1) ) - (i32.const 128) ) ) - (br $do-once - (i32.const 2) - ) ) - ) - (if - (i32.or + (if (i32.lt_u (local.get $1) - (i32.const 55296) - ) - (i32.eq - (i32.and - (local.get $1) - (i32.const -8192) - ) - (i32.const 57344) + (i32.const 2048) ) - ) - (block - (i32.store8 - (local.get $0) - (i32.or - (i32.shr_u - (local.get $1) - (i32.const 12) + (then + (block + (i32.store8 + (local.get $0) + (i32.or + (i32.shr_u + (local.get $1) + (i32.const 6) + ) + (i32.const 192) + ) ) - (i32.const 224) - ) - ) - (i32.store8 offset=1 - (local.get $0) - (i32.or - (i32.and - (i32.shr_u - (local.get $1) - (i32.const 6) + (i32.store8 offset=1 + (local.get $0) + (i32.or + (i32.and + (local.get $1) + (i32.const 63) + ) + (i32.const 128) ) - (i32.const 63) ) - (i32.const 128) - ) - ) - (i32.store8 offset=2 - (local.get $0) - (i32.or - (i32.and - (local.get $1) - (i32.const 63) + (br $do-once + (i32.const 2) ) - (i32.const 128) ) ) - (br $do-once - (i32.const 3) - ) ) - ) - (if (result i32) - (i32.lt_u - (i32.add - (local.get $1) - (i32.const -65536) - ) - (i32.const 1048576) - ) - (block (result i32) - (i32.store8 - (local.get $0) - (i32.or - (i32.shr_u + (if + (i32.or + (i32.lt_u + (local.get $1) + (i32.const 55296) + ) + (i32.eq + (i32.and (local.get $1) - (i32.const 18) + (i32.const -8192) ) - (i32.const 240) + (i32.const 57344) ) ) - (i32.store8 offset=1 - (local.get $0) - (i32.or - (i32.and - (i32.shr_u - (local.get $1) - (i32.const 12) + (then + (block + (i32.store8 + (local.get $0) + (i32.or + (i32.shr_u + (local.get $1) + (i32.const 12) + ) + (i32.const 224) ) - (i32.const 63) ) - (i32.const 128) - ) - ) - (i32.store8 offset=2 - (local.get $0) - (i32.or - (i32.and - (i32.shr_u - (local.get $1) - (i32.const 6) + (i32.store8 offset=1 + (local.get $0) + (i32.or + (i32.and + (i32.shr_u + (local.get $1) + (i32.const 6) + ) + (i32.const 63) + ) + (i32.const 128) + ) + ) + (i32.store8 offset=2 + (local.get $0) + (i32.or + (i32.and + (local.get $1) + (i32.const 63) + ) + (i32.const 128) ) - (i32.const 63) ) - (i32.const 128) + (br $do-once + (i32.const 3) + ) ) ) - (i32.store8 offset=3 - (local.get $0) - (i32.or - (i32.and - (local.get $1) - (i32.const 63) + ) + (if (result i32) + (i32.lt_u + (i32.add + (local.get $1) + (i32.const -65536) + ) + (i32.const 1048576) + ) + (then + (block (result i32) + (i32.store8 + (local.get $0) + (i32.or + (i32.shr_u + (local.get $1) + (i32.const 18) + ) + (i32.const 240) + ) + ) + (i32.store8 offset=1 + (local.get $0) + (i32.or + (i32.and + (i32.shr_u + (local.get $1) + (i32.const 12) + ) + (i32.const 63) + ) + (i32.const 128) + ) + ) + (i32.store8 offset=2 + (local.get $0) + (i32.or + (i32.and + (i32.shr_u + (local.get $1) + (i32.const 6) + ) + (i32.const 63) + ) + (i32.const 128) + ) + ) + (i32.store8 offset=3 + (local.get $0) + (i32.or + (i32.and + (local.get $1) + (i32.const 63) + ) + (i32.const 128) + ) ) - (i32.const 128) + (i32.const 4) ) ) - (i32.const 4) - ) - (block (result i32) - (i32.store - (call $___errno_location) - (i32.const 84) + (else + (block (result i32) + (i32.store + (call $___errno_location) + (i32.const 84) + ) + (i32.const -1) + ) ) - (i32.const -1) ) ) ) - (i32.const 1) + (else + (i32.const 1) + ) ) ) ) ;; CHECK: (func $_wctomb (param $0 i32) (param $1 i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block $do-once (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 128) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 2048) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 128) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 63) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (br $do-once + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: (i32.const 2048) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 57344) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 55296) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 offset=1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 224) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (i32.const -8192) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: (i32.const 57344) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: (i32.const 55296) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 65536) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1048576) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 18) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 224) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 240) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (i32.store8 offset=1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 63) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=2 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (i32.store8 offset=2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 63) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (br $do-once + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 offset=3 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: (i32.const 65536) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (i32.const 1048576) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (call $___errno_location) - ;; CHECK-NEXT: (i32.const 84) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $_wctomb (param $0 i32) (param $1 i32) (result i32) - (if (result i32) - (local.get $0) - (call $_wcrtomb - (local.get $0) - (local.get $1) - (i32.const 0) - ) - (i32.const 0) - ) - ) - (func $_memchr (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 18) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 240) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 offset=1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 offset=2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 offset=3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (call $___errno_location) + ;; CHECK-NEXT: (i32.const 84) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $_wctomb (param $0 i32) (param $1 i32) (result i32) + (if (result i32) + (local.get $0) + (then + (call $_wcrtomb + (local.get $0) + (local.get $1) + (i32.const 0) + ) + ) + (else + (i32.const 0) + ) + ) + ) + (func $_memchr (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) (local $4 i32) (local $5 i32) (local.set $5 @@ -3467,69 +3661,73 @@ (i32.const 0) ) ) - (block - (local.set $4 - (i32.and - (local.get $1) - (i32.const 255) + (then + (block + (local.set $4 + (i32.and + (local.get $1) + (i32.const 255) + ) ) - ) - (local.set $3 - (local.get $2) - ) - (local.set $2 - (local.get $0) - ) - (loop $while-in - (br_if $__rjti$2 - (i32.eq - (i32.load8_u - (local.get $2) - ) - (i32.and - (local.get $4) - (i32.const 255) + (local.set $3 + (local.get $2) + ) + (local.set $2 + (local.get $0) + ) + (loop $while-in + (br_if $__rjti$2 + (i32.eq + (i32.load8_u + (local.get $2) + ) + (i32.and + (local.get $4) + (i32.const 255) + ) ) ) - ) - (br_if $while-in - (i32.and - (local.tee $0 - (i32.ne - (local.tee $3 - (i32.add - (local.get $3) - (i32.const -1) + (br_if $while-in + (i32.and + (local.tee $0 + (i32.ne + (local.tee $3 + (i32.add + (local.get $3) + (i32.const -1) + ) ) + (i32.const 0) ) - (i32.const 0) ) - ) - (i32.ne - (i32.and - (local.tee $2 - (i32.add - (local.get $2) - (i32.const 1) + (i32.ne + (i32.and + (local.tee $2 + (i32.add + (local.get $2) + (i32.const 1) + ) ) + (i32.const 3) ) - (i32.const 3) + (i32.const 0) ) - (i32.const 0) ) ) ) ) ) - (block - (local.set $3 - (local.get $2) - ) - (local.set $2 - (local.get $0) - ) - (local.set $0 - (local.get $4) + (else + (block + (local.set $3 + (local.get $2) + ) + (local.set $2 + (local.get $0) + ) + (local.set $0 + (local.get $4) + ) ) ) ) @@ -3556,109 +3754,115 @@ ) ) ) - (block - (local.set $3 - (i32.mul - (local.get $5) - (i32.const 16843009) + (then + (block + (local.set $3 + (i32.mul + (local.get $5) + (i32.const 16843009) + ) ) - ) - (block $__rjto$0 - (block $__rjti$0 - (br_if $__rjti$0 - (i32.le_u - (local.get $0) - (i32.const 3) + (block $__rjto$0 + (block $__rjti$0 + (br_if $__rjti$0 + (i32.le_u + (local.get $0) + (i32.const 3) + ) ) - ) - (loop $while-in3 - (if - (i32.eqz - (i32.and - (i32.xor - (i32.and - (local.tee $4 - (i32.xor - (i32.load - (local.get $2) + (loop $while-in3 + (if + (i32.eqz + (i32.and + (i32.xor + (i32.and + (local.tee $4 + (i32.xor + (i32.load + (local.get $2) + ) + (local.get $3) ) - (local.get $3) ) + (i32.const -2139062144) ) (i32.const -2139062144) ) - (i32.const -2139062144) - ) - (i32.add - (local.get $4) - (i32.const -16843009) - ) - ) - ) - (block - (local.set $2 - (i32.add - (local.get $2) - (i32.const 4) + (i32.add + (local.get $4) + (i32.const -16843009) + ) ) ) - (br_if $while-in3 - (i32.gt_u - (local.tee $0 + (then + (block + (local.set $2 (i32.add - (local.get $0) - (i32.const -4) + (local.get $2) + (i32.const 4) ) ) - (i32.const 3) + (br_if $while-in3 + (i32.gt_u + (local.tee $0 + (i32.add + (local.get $0) + (i32.const -4) + ) + ) + (i32.const 3) + ) + ) + (br $__rjti$0) ) ) - (br $__rjti$0) ) ) + (br $__rjto$0) ) - (br $__rjto$0) - ) - (if - (i32.eqz - (local.get $0) - ) - (block - (local.set $0 - (i32.const 0) - ) - (br $label$break$L8) - ) - ) - ) - (loop $while-in5 - (br_if $label$break$L8 - (i32.eq - (i32.load8_u - (local.get $2) + (if + (i32.eqz + (local.get $0) ) - (i32.and - (local.get $1) - (i32.const 255) + (then + (block + (local.set $0 + (i32.const 0) + ) + (br $label$break$L8) + ) ) ) ) - (local.set $2 - (i32.add - (local.get $2) - (i32.const 1) - ) - ) - (br_if $while-in5 - (local.tee $0 + (loop $while-in5 + (br_if $label$break$L8 + (i32.eq + (i32.load8_u + (local.get $2) + ) + (i32.and + (local.get $1) + (i32.const 255) + ) + ) + ) + (local.set $2 (i32.add - (local.get $0) - (i32.const -1) + (local.get $2) + (i32.const 1) ) ) - ) - (local.set $0 - (i32.const 0) + (br_if $while-in5 + (local.tee $0 + (i32.add + (local.get $0) + (i32.const -1) + ) + ) + ) + (local.set $0 + (i32.const 0) + ) ) ) ) @@ -3676,7 +3880,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const -4096) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (call $___errno_location) ;; CHECK-NEXT: (i32.sub @@ -3686,7 +3890,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $___syscall_ret (param $0 i32) (result i32) @@ -3695,17 +3901,21 @@ (local.get $0) (i32.const -4096) ) - (block (result i32) - (i32.store - (call $___errno_location) - (i32.sub - (i32.const 0) - (local.get $0) + (then + (block (result i32) + (i32.store + (call $___errno_location) + (i32.sub + (i32.const 0) + (local.get $0) + ) ) + (i32.const -1) ) - (i32.const -1) ) - (local.get $0) + (else + (local.get $0) + ) ) ) ;; CHECK: (func $___fflush_unlocked (param $0 i32) (result i32) @@ -3786,22 +3996,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load offset=40 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_indirect (type $FUNCSIG$iiii) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load offset=40 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3908,22 +4120,24 @@ ) ) ) - (drop - (call_indirect (type $FUNCSIG$iiii) - (local.get $0) - (i32.sub - (local.get $4) - (local.get $6) - ) - (i32.const 1) - (i32.add - (i32.and - (i32.load offset=40 - (local.get $0) + (then + (drop + (call_indirect (type $FUNCSIG$iiii) + (local.get $0) + (i32.sub + (local.get $4) + (local.get $6) + ) + (i32.const 1) + (i32.add + (i32.and + (i32.load offset=40 + (local.get $0) + ) + (i32.const 7) ) - (i32.const 7) + (i32.const 2) ) - (i32.const 2) ) ) ) @@ -3966,8 +4180,10 @@ (local.get $0) ) ) - (call $___unlockfile - (local.get $0) + (then + (call $___unlockfile + (local.get $0) + ) ) ) ) @@ -3977,21 +4193,33 @@ (local.get $0) (local.get $0) ) - (i32.const -2147483648) - (if (result i32) - (f64.ge - (local.get $0) - (f64.const 2147483648) - ) + (then (i32.const -2147483648) + ) + (else (if (result i32) - (f64.le + (f64.ge (local.get $0) - (f64.const -2147483649) + (f64.const 2147483648) ) - (i32.const -2147483648) - (i32.trunc_f64_s - (local.get $0) + (then + (i32.const -2147483648) + ) + (else + (if (result i32) + (f64.le + (local.get $0) + (f64.const -2147483649) + ) + (then + (i32.const -2147483648) + ) + (else + (i32.trunc_f64_s + (local.get $0) + ) + ) + ) ) ) ) @@ -4000,44 +4228,60 @@ (func $i32s-div (param $0 i32) (param $1 i32) (result i32) (if (result i32) (local.get $1) - (if (result i32) - (i32.and - (i32.eq - (local.get $0) - (i32.const -2147483648) + (then + (if (result i32) + (i32.and + (i32.eq + (local.get $0) + (i32.const -2147483648) + ) + (i32.eq + (local.get $1) + (i32.const -1) + ) ) - (i32.eq - (local.get $1) - (i32.const -1) + (then + (i32.const 0) + ) + (else + (i32.div_s + (local.get $0) + (local.get $1) + ) ) ) + ) + (else (i32.const 0) - (i32.div_s - (local.get $0) - (local.get $1) - ) ) - (i32.const 0) ) ) (func $i32u-rem (param $0 i32) (param $1 i32) (result i32) (if (result i32) (local.get $1) - (i32.rem_u - (local.get $0) - (local.get $1) + (then + (i32.rem_u + (local.get $0) + (local.get $1) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) (func $i32u-div (param $0 i32) (param $1 i32) (result i32) (if (result i32) (local.get $1) - (i32.div_u - (local.get $0) - (local.get $1) + (then + (i32.div_u + (local.get $0) + (local.get $1) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) ;; CHECK: (func $_printf_core (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) @@ -4096,7 +4340,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $21 ;; CHECK-NEXT: (i32.add @@ -4222,25 +4468,29 @@ ;; CHECK-NEXT: (local.get $17) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 2147483647) - ;; CHECK-NEXT: (local.get $17) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: (local.get $17) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (call $___errno_location) - ;; CHECK-NEXT: (i32.const 75) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (call $___errno_location) + ;; CHECK-NEXT: (i32.const 75) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (local.get $17) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (local.get $17) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4333,20 +4583,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $29) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4356,7 +4610,7 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) @@ -4386,7 +4640,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.load8_s ;; CHECK-NEXT: (local.tee $10 @@ -4421,7 +4675,7 @@ ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) @@ -4445,77 +4699,81 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$break$L25 (result i32) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in4 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$break$L25 (result i32) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in4 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 75913) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L25 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.shl ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.extend8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 75913) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L25 ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.extend8_s - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in4 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (br_if $while-in4 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -32) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $1 @@ -4527,242 +4785,248 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once5 (result i32) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (block $__rjto$0 (result i32) - ;; CHECK-NEXT: (block $__rjti$0 - ;; CHECK-NEXT: (br_if $__rjti$0 - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.tee $9 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once5 (result i32) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (block $__rjto$0 (result i32) + ;; CHECK-NEXT: (block $__rjti$0 + ;; CHECK-NEXT: (br_if $__rjti$0 + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.tee $9 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $__rjti$0 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (i32.load8_s offset=2 - ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (br_if $__rjti$0 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.load8_s offset=2 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 36) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 36) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjto$0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (br $__rjto$0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $29) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $29) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once5 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once5 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const -4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 8192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 8192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.extend8_s - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.extend8_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in8 - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (loop $while-in8 + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $16 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $16 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4775,201 +5039,207 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 46) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $label$break$L46 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $label$break$L46 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L46 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in11 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_if $label$break$L46 + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L46 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in11 - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_if $label$break$L46 - ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_s offset=3 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 36) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.shl ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L46 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.load8_s offset=3 - ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 36) + ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $29) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L46 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $29) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $8 @@ -4991,7 +5261,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 57) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $17 ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) @@ -5030,7 +5300,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) @@ -5048,7 +5318,7 @@ ;; CHECK-NEXT: (i32.const 255) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $17 ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) @@ -5071,20 +5341,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 19) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $__rjti$2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjti$2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $4) @@ -5125,7 +5399,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $29) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $17 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -5145,7 +5419,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $29) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) @@ -5426,7 +5700,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $23) ;; CHECK-NEXT: ) @@ -5462,8 +5736,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.get $23) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $23) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -5471,7 +5747,7 @@ ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) @@ -5494,8 +5770,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $5 @@ -5523,7 +5801,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $tempRet0 ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (i32.sub @@ -5566,19 +5844,21 @@ ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: (i32.const 2048) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 4092) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 4093) - ;; CHECK-NEXT: (i32.const 4091) - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 4093) + ;; CHECK-NEXT: (i32.const 4091) + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -5652,7 +5932,7 @@ ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (br_if $while-in2 ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (local.tee $9 @@ -5695,13 +5975,15 @@ ;; CHECK-NEXT: (i32.load8_s ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $while-in3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -5756,13 +6038,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $__rjti$6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (call $_pad ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 32) @@ -5802,7 +6084,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $28 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -5813,30 +6095,32 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 4108) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 2048) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $28 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 2048) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4111) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $28 - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $28 + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4111) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 4114) - ;; CHECK-NEXT: (i32.const 4109) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $28 + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 4114) + ;; CHECK-NEXT: (i32.const 4109) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -5862,2154 +6146,2316 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2146435072) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once49 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (local.tee $25 - ;; CHECK-NEXT: (f64.mul - ;; CHECK-NEXT: (call $_frexp - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once49 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.tee $25 + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (call $_frexp + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $21) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.tee $26 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $26 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 97) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 97) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $30) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $30) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $30) - ;; CHECK-NEXT: (local.tee $18 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (local.tee $18 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (if (result f64) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (if (result f64) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $25) - ;; CHECK-NEXT: (block (result f64) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (f64.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $25) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in54 + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (f64.mul - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const 16) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in54 - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (loop $while-in54 + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (f64.neg - ;; CHECK-NEXT: (f64.add - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.sub - ;; CHECK-NEXT: (f64.neg - ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: (br_if $while-in54 + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $14) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.sub - ;; CHECK-NEXT: (f64.add - ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $14) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 45) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 45) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $28) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $28) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (call $_fmt_u - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (call $_fmt_u + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.lt_s ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: (local.get $24) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $38) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $38) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $24) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $38) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $38) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 43) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 43) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.const 15) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $15 - ;; CHECK-NEXT: (i32.le_s - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $15 + ;; CHECK-NEXT: (i32.le_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $22) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in56 - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.load8_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in56 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $7 ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.get $14) ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const 2147483648) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -2147483648) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.le - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const -2147483649) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.const -2147483648) - ;; CHECK-NEXT: (i32.trunc_f64_s - ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const 2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (f64.le + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const -2147483649) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.trunc_f64_s + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4075) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4075) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (f64.mul - ;; CHECK-NEXT: (f64.sub - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.convert_i32_s - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.convert_i32_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $22) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (f64.eq - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (f64.eq + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 46) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 46) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in56 - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (br_if $while-in56 + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $42) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $40) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $42) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $40) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $41) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $41) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 65536) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $22) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 65536) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $22) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $24) - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once49 - ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: (local.get $16) ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once49 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (if (result f64) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block (result f64) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $21) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (if (result f64) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 28) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 28) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: (f64.const 268435456) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.mul - ;; CHECK-NEXT: (local.get $25) - ;; CHECK-NEXT: (f64.const 268435456) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result f64) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $25) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $25) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $43) - ;; CHECK-NEXT: (local.get $44) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $43) + ;; CHECK-NEXT: (local.get $44) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in60 - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: (loop $while-in60 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.tee $5 ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.get $14) ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const 2147483648) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -2147483648) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (f64.le - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.const -2147483649) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.const -2147483648) - ;; CHECK-NEXT: (i32.trunc_f64_s - ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const 2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (f64.le + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.const -2147483649) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.trunc_f64_s + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in60 - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (local.tee $14 - ;; CHECK-NEXT: (f64.mul - ;; CHECK-NEXT: (f64.sub - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (f64.convert_i32_u - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (br_if $while-in60 + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.tee $14 + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (f64.convert_i32_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 1e9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 1e9) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in62 - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 29) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.const 29) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (loop $while-in62 + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 29) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.const 29) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once63 - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in66 - ;; CHECK-NEXT: (global.set $tempRet0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.tee $20 - ;; CHECK-NEXT: (call $_bitshift64Shl - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once63 + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in66 + ;; CHECK-NEXT: (global.set $tempRet0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.tee $20 + ;; CHECK-NEXT: (call $_bitshift64Shl + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $12 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $tempRet0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $12 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (call $___uremdi3 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.tee $20 + ;; CHECK-NEXT: (global.get $tempRet0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1000000000) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.get $tempRet0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (call $___uremdi3 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (local.tee $20 - ;; CHECK-NEXT: (global.get $tempRet0) + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (call $___udivmoddi4 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (i32.const 1000000000) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in66 + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1000000000) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (call $___udivmoddi4 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (i32.const 1000000000) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (br_if $do-once63 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in66 - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.tee $5 ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once63 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in68 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in68) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in68 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $21) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in68) + ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $21) - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (br_if $while-in62 + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in62 - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.set $19 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $19 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 6) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $31 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: (local.set $31 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $26) + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (loop $while-in70 (result i32) - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (loop $while-in70 (result i32) + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once71 - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $34 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.const 1000000000) - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in74 - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once71 + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $34 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 1000000000) ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in74 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $34) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in74 + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $34) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in74 - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $do-once71 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once71 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.set $12 ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $31) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (local.tee $11 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $21) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.get $18) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $20) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $21) - ;; CHECK-NEXT: (local.tee $11 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $21) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in70) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in70) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once75 - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once75 + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once75 - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (br_if $do-once75 + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in78 - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in78 - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (loop $while-in78 + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in78 + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $26) + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $31 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $31 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $34 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: (local.tee $34 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $26) + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 9216) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.const 9216) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in80 + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in80 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in80 + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.tee $18 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (br_if $while-in80 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4092) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.rem_u - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $26 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.tee $18 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4092) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once81 - ;; CHECK-NEXT: (local.set $35 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.div_u - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (if (result f64) - ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $26 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.tee $45 - ;; CHECK-NEXT: (i32.div_s - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once81 + ;; CHECK-NEXT: (local.set $35 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.div_u + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 0.5) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (f64.const 1) - ;; CHECK-NEXT: (f64.const 1.5) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (if (result f64) + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $45) + ;; CHECK-NEXT: (local.tee $45 + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (f64.const 0.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 1.5) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $26) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $45) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $25 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (f64.const 9007199254740994) - ;; CHECK-NEXT: (f64.const 9007199254740992) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $35) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.set $25 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (f64.const 9007199254740994) + ;; CHECK-NEXT: (f64.const 9007199254740992) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $35) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $28) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.load8_s - ;; CHECK-NEXT: (local.get $30) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $28) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 45) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $25 + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 45) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $25 - ;; CHECK-NEXT: (f64.neg - ;; CHECK-NEXT: (local.get $25) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $do-once81 + ;; CHECK-NEXT: (f64.eq + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $25) ;; CHECK-NEXT: (local.get $14) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $25) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once81 - ;; CHECK-NEXT: (f64.eq - ;; CHECK-NEXT: (f64.add - ;; CHECK-NEXT: (local.get $25) - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $25) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 999999999) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in86 ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 999999999) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in86 + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in86 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 999999999) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.shr_s ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $20) ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (br_if $do-once81 + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $8 ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in86 - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 999999999) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (loop $while-in88 + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once81 - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (br_if $while-in88 + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.tee $12 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in88 - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in88 - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.tee $12 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $12 ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $35 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.set $35 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (loop $while-in90 (result i32) - ;; CHECK-NEXT: (block $while-out89 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $26 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out89 + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (loop $while-in90 (result i32) + ;; CHECK-NEXT: (block $while-out89 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.le_u ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $26 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out89 ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $26 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $26 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in90) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in90) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.tee $8 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $34) - ;; CHECK-NEXT: (block $do-once91 (result i32) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $31) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $34) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once91 (result i32) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const -5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const -5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $19 - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $19 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $15) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $19 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $19 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_if $do-once91 - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (local.tee $18 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_if $do-once91 + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (local.tee $18 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: (block $do-once93 ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $15 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.get $26) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $do-once93 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $15 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once93) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once93) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in96 + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in96 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once93) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.rem_u - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once93) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in96 - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 102) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in96 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.rem_u - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $19) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 102) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $19) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $15) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $19) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $19) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $28) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.tee $19 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $28) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.tee $31 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $19 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $15 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.tee $31 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $15 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $24) - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (call $_fmt_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $35) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (call $_fmt_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $35) ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: (local.get $24) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $24) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in98 - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in98 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in98 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in98 - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $24) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 43) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $15 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 43) + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $15 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: (local.get $15) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $24) - ;; CHECK-NEXT: (local.get $15) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $30) - ;; CHECK-NEXT: (local.get $28) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $30) + ;; CHECK-NEXT: (local.get $28) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 65536) + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 65536) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $31) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.tee $12 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $31) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.tee $12 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $20) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in102 - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (call $_fmt_u - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (loop $while-in102 + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (call $_fmt_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $27) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $27) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once103 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br_if $do-once103 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $27) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $32) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $32) + ;; CHECK-NEXT: (block $do-once103 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br_if $do-once103 - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $do-once103 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in106 ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $32) ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in106 - ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br_if $do-once103 + ;; CHECK-NEXT: (i32.le_u ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (local.get $22) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in106 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in106 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $27) - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $20) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in102) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in102) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $19) ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $19) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (i32.const 4143) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (i32.const 4143) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in110 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (call $_fmt_u - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in110 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (call $_fmt_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: (local.get $22) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $22) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in112 - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in112 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in112 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in112 - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.gt_s ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.const 9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $do-once99 + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $20 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $26) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (local.set $18 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in110) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once99 - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $20 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $26) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $18 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in114 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (call $_fmt_u - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (loop $while-in114 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (call $_fmt_u + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (local.get $27) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $32) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $27) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.get $32) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $32) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once115 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $do-once115 ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $do-once115 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (i32.le_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $do-once115 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (i32.const 4143) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br_if $do-once115 + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once115 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: (i32.le_s - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (loop $while-in118 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in118 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once115 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $27) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.get $0) @@ -8017,143 +8463,99 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (i32.const 4143) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (br_if $do-once115 - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $22) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in118 - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (br_if $while-in114 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) + ;; CHECK-NEXT: (local.get $20) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in118 - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $22) + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $27) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.gt_s - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in114 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ge_s - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 18) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 18) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 18) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 18) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once99 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (br_if $do-once99 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $24) - ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $24) + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_pad - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 32) - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 8192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $16) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (call $_pad + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (local.get $16) ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $16) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (call $_pad ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 32) @@ -8188,7 +8590,7 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $___fwritex ;; CHECK-NEXT: (local.get $30) @@ -8233,11 +8635,13 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -8299,7 +8703,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $11 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $15) @@ -8368,13 +8772,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $11 ;; CHECK-NEXT: (i32.const 4091) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $11 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.shr_s @@ -8389,7 +8793,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $23) ;; CHECK-NEXT: ) @@ -8433,7 +8837,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) @@ -8477,7 +8881,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) @@ -8501,7 +8905,7 @@ ;; CHECK-NEXT: (i32.load8_u ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $__rjto$06 ;; CHECK-NEXT: (block $__rjti$07 ;; CHECK-NEXT: (br_if $__rjti$07 @@ -8531,7 +8935,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $8) @@ -8559,7 +8963,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $9 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -8705,7 +9109,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $17 ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) @@ -8721,7 +9125,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -8771,11 +9175,13 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $33) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $33) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -8794,7 +9200,9 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -8849,27 +9257,29 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $23) - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $23) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (local.get $23) ;; CHECK-NEXT: ) @@ -8911,11 +9321,13 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -8945,11 +9357,13 @@ ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $___fwritex - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $15) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $___fwritex + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $15) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -8978,96 +9392,104 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in130 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (call $_pop_arg_336 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in130 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in130 - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_pop_arg_336 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.shl ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L343) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in132 (result i32) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (br_if $while-in130 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L343) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in132 - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in132 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L343) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (br_if $while-in132 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -9139,7 +9561,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.set $20 (i32.add @@ -9282,25 +9706,31 @@ (local.get $16) (i32.const -1) ) - (local.set $16 - (if (result i32) - (i32.gt_s - (local.get $10) - (i32.sub - (i32.const 2147483647) - (local.get $16) + (then + (local.set $16 + (if (result i32) + (i32.gt_s + (local.get $10) + (i32.sub + (i32.const 2147483647) + (local.get $16) + ) ) - ) - (block (result i32) - (i32.store - (call $___errno_location) - (i32.const 75) + (then + (block (result i32) + (i32.store + (call $___errno_location) + (i32.const 75) + ) + (i32.const -1) + ) + ) + (else + (i32.add + (local.get $10) + (local.get $16) + ) ) - (i32.const -1) - ) - (i32.add - (local.get $10) - (local.get $16) ) ) ) @@ -9397,20 +9827,24 @@ ) (if (local.get $29) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) + (then + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop - (call $___fwritex - (local.get $5) - (local.get $7) - (local.get $0) + (then + (drop + (call $___fwritex + (local.get $5) + (local.get $7) + (local.get $0) + ) + ) ) ) ) @@ -9420,14 +9854,16 @@ (local.get $10) (local.get $5) ) - (block - (local.set $5 - (local.get $6) - ) - (local.set $10 - (local.get $7) + (then + (block + (local.set $5 + (local.get $6) + ) + (local.set $10 + (local.get $7) + ) + (br $label$continue$L1) ) - (br $label$continue$L1) ) ) (local.set $8 @@ -9450,49 +9886,53 @@ ) (i32.const 10) ) - (block (result i32) - (local.set $6 - (i32.load8_s - (local.tee $10 - (select - (i32.add - (local.get $6) - (i32.const 3) - ) - (local.get $10) - (local.tee $11 - (i32.eq - (i32.load8_s offset=2 - (local.get $6) + (then + (block (result i32) + (local.set $6 + (i32.load8_s + (local.tee $10 + (select + (i32.add + (local.get $6) + (i32.const 3) + ) + (local.get $10) + (local.tee $11 + (i32.eq + (i32.load8_s offset=2 + (local.get $6) + ) + (i32.const 36) ) - (i32.const 36) ) ) ) ) ) - ) - (local.set $17 + (local.set $17 + (select + (local.get $8) + (i32.const -1) + (local.get $11) + ) + ) (select - (local.get $8) - (i32.const -1) + (i32.const 1) + (local.get $1) (local.get $11) ) ) - (select - (i32.const 1) - (local.get $1) - (local.get $11) - ) ) - (block (result i32) - (local.set $6 - (local.get $11) - ) - (local.set $17 - (i32.const -1) + (else + (block (result i32) + (local.set $6 + (local.get $11) + ) + (local.set $17 + (i32.const -1) + ) + (local.get $1) ) - (local.get $1) ) ) ) @@ -9513,88 +9953,94 @@ ) (i32.const 32) ) - (block - (local.set $1 - (local.get $6) - ) - (local.set $6 - (local.get $11) - ) - (local.set $11 - (i32.const 0) - ) - (loop $while-in4 - (if - (i32.eqz - (i32.and - (i32.shl - (i32.const 1) - (i32.add - (local.get $6) - (i32.const -32) + (then + (block + (local.set $1 + (local.get $6) + ) + (local.set $6 + (local.get $11) + ) + (local.set $11 + (i32.const 0) + ) + (loop $while-in4 + (if + (i32.eqz + (i32.and + (i32.shl + (i32.const 1) + (i32.add + (local.get $6) + (i32.const -32) + ) ) + (i32.const 75913) ) - (i32.const 75913) ) - ) - (block - (local.set $6 - (local.get $1) - ) - (local.set $1 - (local.get $11) + (then + (block + (local.set $6 + (local.get $1) + ) + (local.set $1 + (local.get $11) + ) + (br $label$break$L25) + ) ) - (br $label$break$L25) ) - ) - (local.set $11 - (i32.or - (i32.shl - (i32.const 1) - (i32.add - (i32.shr_s - (i32.shl - (local.get $1) + (local.set $11 + (i32.or + (i32.shl + (i32.const 1) + (i32.add + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) (i32.const 24) ) - (i32.const 24) + (i32.const -32) ) - (i32.const -32) ) + (local.get $11) ) - (local.get $11) ) - ) - (br_if $while-in4 - (i32.eq - (i32.and - (local.tee $6 - (local.tee $1 - (i32.load8_s - (local.tee $10 - (i32.add - (local.get $10) - (i32.const 1) + (br_if $while-in4 + (i32.eq + (i32.and + (local.tee $6 + (local.tee $1 + (i32.load8_s + (local.tee $10 + (i32.add + (local.get $10) + (i32.const 1) + ) ) ) ) ) + (i32.const -32) ) - (i32.const -32) + (i32.const 32) ) - (i32.const 32) ) - ) - (local.set $6 - (local.get $1) - ) - (local.set $1 - (local.get $11) + (local.set $6 + (local.get $1) + ) + (local.set $1 + (local.get $11) + ) ) ) ) - (local.set $1 - (i32.const 0) + (else + (local.set $1 + (i32.const 0) + ) ) ) ) @@ -9607,230 +10053,263 @@ ) (i32.const 42) ) - (block - (local.set $10 - (block $__rjto$0 (result i32) - (block $__rjti$0 - (br_if $__rjti$0 - (i32.ge_u - (local.tee $11 - (i32.add - (i32.load8_s - (local.tee $6 - (i32.add - (local.get $10) - (i32.const 1) + (then + (block + (local.set $10 + (block $__rjto$0 (result i32) + (block $__rjti$0 + (br_if $__rjti$0 + (i32.ge_u + (local.tee $11 + (i32.add + (i32.load8_s + (local.tee $6 + (i32.add + (local.get $10) + (i32.const 1) + ) ) ) + (i32.const -48) ) - (i32.const -48) ) + (i32.const 10) ) - (i32.const 10) ) - ) - (br_if $__rjti$0 - (i32.ne - (i32.load8_s offset=2 - (local.get $10) + (br_if $__rjti$0 + (i32.ne + (i32.load8_s offset=2 + (local.get $10) + ) + (i32.const 36) ) - (i32.const 36) ) - ) - (i32.store - (i32.add - (local.get $4) - (i32.shl - (local.get $11) - (i32.const 2) + (i32.store + (i32.add + (local.get $4) + (i32.shl + (local.get $11) + (i32.const 2) + ) ) + (i32.const 10) ) - (i32.const 10) - ) - (drop - (i32.load offset=4 - (local.tee $6 - (i32.add - (local.get $3) - (i32.shl - (i32.add - (i32.load8_s - (local.get $6) + (drop + (i32.load offset=4 + (local.tee $6 + (i32.add + (local.get $3) + (i32.shl + (i32.add + (i32.load8_s + (local.get $6) + ) + (i32.const -48) ) - (i32.const -48) + (i32.const 3) ) - (i32.const 3) ) ) ) ) - ) - (local.set $8 - (i32.const 1) - ) - (local.set $14 - (i32.load - (local.get $6) + (local.set $8 + (i32.const 1) ) - ) - (br $__rjto$0 - (i32.add - (local.get $10) - (i32.const 3) + (local.set $14 + (i32.load + (local.get $6) + ) ) - ) - ) - (if - (local.get $8) - (block - (local.set $16 - (i32.const -1) + (br $__rjto$0 + (i32.add + (local.get $10) + (i32.const 3) + ) ) - (br $label$break$L1) - ) - ) - (if - (i32.eqz - (local.get $29) ) - (block - (local.set $11 - (local.get $1) - ) - (local.set $10 - (local.get $6) - ) - (local.set $1 - (i32.const 0) - ) - (local.set $14 - (i32.const 0) + (if + (local.get $8) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) + ) ) - (br $do-once5) ) - ) - (local.set $14 - (i32.load - (local.tee $10 - (i32.and - (i32.add - (i32.load - (local.get $2) + (if + (i32.eqz + (local.get $29) + ) + (then + (block + (local.set $11 + (local.get $1) + ) + (local.set $10 + (local.get $6) + ) + (local.set $1 + (i32.const 0) + ) + (local.set $14 + (i32.const 0) + ) + (br $do-once5) + ) + ) + ) + (local.set $14 + (i32.load + (local.tee $10 + (i32.and + (i32.add + (i32.load + (local.get $2) + ) + (i32.const 3) ) - (i32.const 3) + (i32.const -4) ) - (i32.const -4) ) ) ) - ) - (i32.store - (local.get $2) - (i32.add - (local.get $10) - (i32.const 4) + (i32.store + (local.get $2) + (i32.add + (local.get $10) + (i32.const 4) + ) ) + (local.set $8 + (i32.const 0) + ) + (local.get $6) ) - (local.set $8 - (i32.const 0) - ) - (local.get $6) ) - ) - (local.set $11 - (if (result i32) - (i32.lt_s - (local.get $14) - (i32.const 0) - ) - (block (result i32) - (local.set $14 - (i32.sub - (i32.const 0) - (local.get $14) + (local.set $11 + (if (result i32) + (i32.lt_s + (local.get $14) + (i32.const 0) + ) + (then + (block (result i32) + (local.set $14 + (i32.sub + (i32.const 0) + (local.get $14) + ) + ) + (i32.or + (local.get $1) + (i32.const 8192) + ) ) ) - (i32.or + (else (local.get $1) - (i32.const 8192) ) ) - (local.get $1) ) - ) - (local.set $1 - (local.get $8) + (local.set $1 + (local.get $8) + ) ) ) - (if - (i32.lt_u - (local.tee $6 - (i32.add - (i32.shr_s - (i32.shl - (local.get $6) + (else + (if + (i32.lt_u + (local.tee $6 + (i32.add + (i32.shr_s + (i32.shl + (local.get $6) + (i32.const 24) + ) (i32.const 24) ) - (i32.const 24) + (i32.const -48) ) - (i32.const -48) ) + (i32.const 10) ) - (i32.const 10) - ) - (block - (local.set $11 - (i32.const 0) - ) - (loop $while-in8 - (local.set $6 - (i32.add - (i32.mul - (local.get $11) - (i32.const 10) - ) - (local.get $6) + (then + (block + (local.set $11 + (i32.const 0) ) - ) - (if - (i32.lt_u - (local.tee $9 + (loop $while-in8 + (local.set $6 (i32.add - (i32.load8_s - (local.tee $10 - (i32.add - (local.get $10) - (i32.const 1) + (i32.mul + (local.get $11) + (i32.const 10) + ) + (local.get $6) + ) + ) + (if + (i32.lt_u + (local.tee $9 + (i32.add + (i32.load8_s + (local.tee $10 + (i32.add + (local.get $10) + (i32.const 1) + ) + ) ) + (i32.const -48) ) ) - (i32.const -48) + (i32.const 10) + ) + (then + (block + (local.set $11 + (local.get $6) + ) + (local.set $6 + (local.get $9) + ) + (br $while-in8) + ) ) ) - (i32.const 10) ) - (block - (local.set $11 + (if + (i32.lt_s (local.get $6) + (i32.const 0) ) - (local.set $6 - (local.get $9) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) + ) + ) + (else + (block + (local.set $11 + (local.get $1) + ) + (local.set $1 + (local.get $8) + ) + (local.set $14 + (local.get $6) + ) + ) ) - (br $while-in8) ) ) ) - (if - (i32.lt_s - (local.get $6) - (i32.const 0) - ) - (block - (local.set $16 - (i32.const -1) - ) - (br $label$break$L1) - ) + (else (block (local.set $11 (local.get $1) @@ -9839,22 +10318,11 @@ (local.get $8) ) (local.set $14 - (local.get $6) + (i32.const 0) ) ) ) ) - (block - (local.set $11 - (local.get $1) - ) - (local.set $1 - (local.get $8) - ) - (local.set $14 - (i32.const 0) - ) - ) ) ) ) @@ -9867,207 +10335,227 @@ ) (i32.const 46) ) - (block (result i32) - (if - (i32.ne - (local.tee $8 - (i32.load8_s - (local.tee $6 - (i32.add - (local.get $10) - (i32.const 1) + (then + (block (result i32) + (if + (i32.ne + (local.tee $8 + (i32.load8_s + (local.tee $6 + (i32.add + (local.get $10) + (i32.const 1) + ) ) ) ) + (i32.const 42) ) - (i32.const 42) - ) - (block - (if - (i32.lt_u - (local.tee $9 - (i32.add - (local.get $8) - (i32.const -48) - ) - ) - (i32.const 10) - ) - (block - (local.set $10 - (local.get $6) - ) - (local.set $8 - (i32.const 0) - ) - (local.set $6 - (local.get $9) - ) - ) + (then (block - (local.set $10 - (local.get $6) - ) - (br $label$break$L46 - (i32.const 0) - ) - ) - ) - (loop $while-in11 - (drop - (br_if $label$break$L46 - (local.tee $6 - (i32.add - (i32.mul - (local.get $8) - (i32.const 10) - ) - (local.get $6) - ) - ) - (i32.ge_u + (if + (i32.lt_u (local.tee $9 (i32.add - (i32.load8_s - (local.tee $10 - (i32.add - (local.get $10) - (i32.const 1) - ) - ) - ) + (local.get $8) (i32.const -48) ) ) (i32.const 10) ) + (then + (block + (local.set $10 + (local.get $6) + ) + (local.set $8 + (i32.const 0) + ) + (local.set $6 + (local.get $9) + ) + ) + ) + (else + (block + (local.set $10 + (local.get $6) + ) + (br $label$break$L46 + (i32.const 0) + ) + ) + ) ) - ) - (local.set $8 - (local.get $6) - ) - (local.set $6 - (local.get $9) - ) - (br $while-in11) - ) - ) - ) - (if - (i32.lt_u - (local.tee $8 - (i32.add - (i32.load8_s - (local.tee $6 - (i32.add - (local.get $10) - (i32.const 2) + (loop $while-in11 + (drop + (br_if $label$break$L46 + (local.tee $6 + (i32.add + (i32.mul + (local.get $8) + (i32.const 10) + ) + (local.get $6) + ) + ) + (i32.ge_u + (local.tee $9 + (i32.add + (i32.load8_s + (local.tee $10 + (i32.add + (local.get $10) + (i32.const 1) + ) + ) + ) + (i32.const -48) + ) + ) + (i32.const 10) + ) ) ) + (local.set $8 + (local.get $6) + ) + (local.set $6 + (local.get $9) + ) + (br $while-in11) ) - (i32.const -48) ) ) - (i32.const 10) ) (if - (i32.eq - (i32.load8_s offset=3 - (local.get $10) - ) - (i32.const 36) - ) - (block - (i32.store + (i32.lt_u + (local.tee $8 (i32.add - (local.get $4) - (i32.shl - (local.get $8) - (i32.const 2) + (i32.load8_s + (local.tee $6 + (i32.add + (local.get $10) + (i32.const 2) + ) + ) ) + (i32.const -48) ) - (i32.const 10) ) - (drop - (i32.load offset=4 - (local.tee $6 - (i32.add - (local.get $3) - (i32.shl - (i32.add - (i32.load8_s - (local.get $6) + (i32.const 10) + ) + (then + (if + (i32.eq + (i32.load8_s offset=3 + (local.get $10) + ) + (i32.const 36) + ) + (then + (block + (i32.store + (i32.add + (local.get $4) + (i32.shl + (local.get $8) + (i32.const 2) + ) + ) + (i32.const 10) + ) + (drop + (i32.load offset=4 + (local.tee $6 + (i32.add + (local.get $3) + (i32.shl + (i32.add + (i32.load8_s + (local.get $6) + ) + (i32.const -48) + ) + (i32.const 3) + ) ) - (i32.const -48) ) - (i32.const 3) + ) + ) + (local.set $10 + (i32.add + (local.get $10) + (i32.const 4) + ) + ) + (br $label$break$L46 + (i32.load + (local.get $6) ) ) ) ) ) - (local.set $10 - (i32.add - (local.get $10) - (i32.const 4) - ) - ) - (br $label$break$L46 - (i32.load - (local.get $6) - ) - ) ) ) - ) - (if - (local.get $1) - (block - (local.set $16 - (i32.const -1) + (if + (local.get $1) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) + ) ) - (br $label$break$L1) ) - ) - (if (result i32) - (local.get $29) - (block (result i32) - (local.set $8 - (i32.load - (local.tee $10 - (i32.and - (i32.add - (i32.load - (local.get $2) + (if (result i32) + (local.get $29) + (then + (block (result i32) + (local.set $8 + (i32.load + (local.tee $10 + (i32.and + (i32.add + (i32.load + (local.get $2) + ) + (i32.const 3) + ) + (i32.const -4) ) - (i32.const 3) ) - (i32.const -4) ) ) + (i32.store + (local.get $2) + (i32.add + (local.get $10) + (i32.const 4) + ) + ) + (local.set $10 + (local.get $6) + ) + (local.get $8) ) ) - (i32.store - (local.get $2) - (i32.add - (local.get $10) - (i32.const 4) + (else + (block (result i32) + (local.set $10 + (local.get $6) + ) + (i32.const 0) ) ) - (local.set $10 - (local.get $6) - ) - (local.get $8) - ) - (block (result i32) - (local.set $10 - (local.get $6) - ) - (i32.const 0) ) ) ) - (i32.const -1) + (else + (i32.const -1) + ) ) ) ) @@ -10090,11 +10578,13 @@ ) (i32.const 57) ) - (block - (local.set $16 - (i32.const -1) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) ) - (br $label$break$L1) ) ) (local.set $10 @@ -10129,17 +10619,21 @@ ) (i32.const 8) ) - (block - (local.set $8 - (local.get $10) - ) - (local.set $9 - (local.get $12) + (then + (block + (local.set $8 + (local.get $10) + ) + (local.set $9 + (local.get $12) + ) + (br $while-in13) ) - (br $while-in13) ) - (local.set $18 - (local.get $8) + (else + (local.set $18 + (local.get $8) + ) ) ) ) @@ -10150,11 +10644,13 @@ (i32.const 255) ) ) - (block - (local.set $16 - (i32.const -1) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) ) - (br $label$break$L1) ) ) (local.set $8 @@ -10173,74 +10669,86 @@ ) (i32.const 19) ) - (if - (local.get $8) - (block - (local.set $16 - (i32.const -1) + (then + (if + (local.get $8) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) + ) + ) + (else + (br $__rjti$2) ) - (br $label$break$L1) ) - (br $__rjti$2) ) - (block - (if - (local.get $8) - (block - (i32.store - (i32.add - (local.get $4) - (i32.shl - (local.get $17) - (i32.const 2) - ) - ) - (local.get $12) - ) - (local.set $13 - (i32.load offset=4 - (local.tee $12 + (else + (block + (if + (local.get $8) + (then + (block + (i32.store (i32.add - (local.get $3) + (local.get $4) (i32.shl (local.get $17) - (i32.const 3) + (i32.const 2) + ) + ) + (local.get $12) + ) + (local.set $13 + (i32.load offset=4 + (local.tee $12 + (i32.add + (local.get $3) + (i32.shl + (local.get $17) + (i32.const 3) + ) + ) ) ) ) + (i32.store + (local.tee $8 + (local.get $19) + ) + (i32.load + (local.get $12) + ) + ) + (i32.store offset=4 + (local.get $8) + (local.get $13) + ) + (br $__rjti$2) ) ) - (i32.store - (local.tee $8 - (local.get $19) - ) - (i32.load - (local.get $12) - ) + ) + (if + (i32.eqz + (local.get $29) ) - (i32.store offset=4 - (local.get $8) - (local.get $13) + (then + (block + (local.set $16 + (i32.const 0) + ) + (br $label$break$L1) + ) ) - (br $__rjti$2) ) - ) - (if - (i32.eqz - (local.get $29) - ) - (block - (local.set $16 - (i32.const 0) - ) - (br $label$break$L1) + (call $_pop_arg_336 + (local.get $19) + (local.get $12) + (local.get $2) ) ) - (call $_pop_arg_336 - (local.get $19) - (local.get $12) - (local.get $2) - ) ) ) (br $__rjto$2) @@ -10249,14 +10757,16 @@ (i32.eqz (local.get $29) ) - (block - (local.set $5 - (local.get $10) - ) - (local.set $10 - (local.get $7) + (then + (block + (local.set $5 + (local.get $10) + ) + (local.set $10 + (local.get $7) + ) + (br $label$continue$L1) ) - (br $label$continue$L1) ) ) ) @@ -10521,50 +11031,54 @@ ) ) ) - (local.set $8 - (local.get $26) - ) - (block - (local.set $5 - (local.get $7) - ) - (local.set $7 - (local.get $8) - ) + (then (local.set $8 (local.get $26) ) - (loop $while-in32 - (i32.store8 - (local.tee $8 - (i32.add - (local.get $8) - (i32.const -1) + ) + (else + (block + (local.set $5 + (local.get $7) + ) + (local.set $7 + (local.get $8) + ) + (local.set $8 + (local.get $26) + ) + (loop $while-in32 + (i32.store8 + (local.tee $8 + (i32.add + (local.get $8) + (i32.const -1) + ) ) - ) - (i32.or - (i32.and - (local.get $5) - (i32.const 7) + (i32.or + (i32.and + (local.get $5) + (i32.const 7) + ) + (i32.const 48) ) - (i32.const 48) ) - ) - (br_if $while-in32 - (i32.eqz - (i32.and - (i32.eqz - (local.tee $5 - (call $_bitshift64Lshr - (local.get $5) - (local.get $7) - (i32.const 3) + (br_if $while-in32 + (i32.eqz + (i32.and + (i32.eqz + (local.tee $5 + (call $_bitshift64Lshr + (local.get $5) + (local.get $7) + (i32.const 3) + ) ) ) - ) - (i32.eqz - (local.tee $7 - (global.get $tempRet0) + (i32.eqz + (local.tee $7 + (global.get $tempRet0) + ) ) ) ) @@ -10579,35 +11093,39 @@ (local.get $11) (i32.const 8) ) - (block (result i32) - (local.set $7 - (local.get $11) - ) - (local.set $6 - (select - (local.tee $11 - (i32.add - (i32.sub - (local.get $39) - (local.get $8) + (then + (block (result i32) + (local.set $7 + (local.get $11) + ) + (local.set $6 + (select + (local.tee $11 + (i32.add + (i32.sub + (local.get $39) + (local.get $8) + ) + (i32.const 1) ) - (i32.const 1) ) - ) - (local.get $6) - (i32.lt_s (local.get $6) - (local.get $11) + (i32.lt_s + (local.get $6) + (local.get $11) + ) ) ) + (local.get $8) ) - (local.get $8) ) - (block (result i32) - (local.set $7 - (local.get $11) + (else + (block (result i32) + (local.set $7 + (local.get $11) + ) + (local.get $8) ) - (local.get $8) ) ) ) @@ -10635,33 +11153,35 @@ ) (i32.const 0) ) - (block - (i32.store - (local.tee $8 - (local.get $19) + (then + (block + (i32.store + (local.tee $8 + (local.get $19) + ) + (local.tee $5 + (call $_i64Subtract + (i32.const 0) + (i32.const 0) + (local.get $5) + (local.get $7) + ) + ) ) - (local.tee $5 - (call $_i64Subtract - (i32.const 0) - (i32.const 0) - (local.get $5) - (local.get $7) + (i32.store offset=4 + (local.get $8) + (local.tee $7 + (global.get $tempRet0) ) ) - ) - (i32.store offset=4 - (local.get $8) - (local.tee $7 - (global.get $tempRet0) + (local.set $8 + (i32.const 1) ) + (local.set $9 + (i32.const 4091) + ) + (br $__rjti$4) ) - (local.set $8 - (i32.const 1) - ) - (local.set $9 - (i32.const 4091) - ) - (br $__rjti$4) ) ) (local.set $9 @@ -10670,25 +11190,29 @@ (local.get $11) (i32.const 2048) ) - (block (result i32) - (local.set $8 - (i32.const 1) + (then + (block (result i32) + (local.set $8 + (i32.const 1) + ) + (i32.const 4092) ) - (i32.const 4092) ) - (block (result i32) - (local.set $8 - (local.tee $9 - (i32.and - (local.get $11) - (i32.const 1) + (else + (block (result i32) + (local.set $8 + (local.tee $9 + (i32.and + (local.get $11) + (i32.const 1) + ) ) ) - ) - (select - (i32.const 4093) - (i32.const 4091) - (local.get $9) + (select + (i32.const 4093) + (i32.const 4091) + (local.get $9) + ) ) ) ) @@ -10797,24 +11321,28 @@ ) (if (local.get $6) - (block - (local.set $8 - (local.get $6) + (then + (block + (local.set $8 + (local.get $6) + ) + (br $__rjti$6) ) - (br $__rjti$6) ) - (block - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (i32.const 0) - (local.get $11) - ) - (local.set $7 - (i32.const 0) + (else + (block + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) + (i32.const 0) + (local.get $11) + ) + (local.set $7 + (i32.const 0) + ) + (br $__rjti$7) ) - (br $__rjti$7) ) ) ) @@ -10844,41 +11372,49 @@ ) (i32.const 0) ) - (block (result i32) - (local.set $27 - (i32.const 1) - ) - (local.set $15 - (f64.neg - (local.get $15) - ) - ) - (i32.const 4108) - ) - (if (result i32) - (i32.and - (local.get $11) - (i32.const 2048) - ) + (then (block (result i32) (local.set $27 (i32.const 1) ) - (i32.const 4111) - ) - (block (result i32) - (local.set $27 - (local.tee $5 - (i32.and - (local.get $11) + (local.set $15 + (f64.neg + (local.get $15) + ) + ) + (i32.const 4108) + ) + ) + (else + (if (result i32) + (i32.and + (local.get $11) + (i32.const 2048) + ) + (then + (block (result i32) + (local.set $27 (i32.const 1) ) + (i32.const 4111) ) ) - (select - (i32.const 4114) - (i32.const 4109) - (local.get $5) + (else + (block (result i32) + (local.set $27 + (local.tee $5 + (i32.and + (local.get $11) + (i32.const 1) + ) + ) + ) + (select + (i32.const 4114) + (i32.const 4109) + (local.get $5) + ) + ) ) ) ) @@ -10916,2124 +11452,2096 @@ (i32.const 0) ) ) - (block (result i32) - (if - (local.tee $5 - (f64.ne - (local.tee $23 - (f64.mul - (call $_frexp - (local.get $15) - (local.tee $5 - (local.get $20) + (then + (block (result i32) + (if + (local.tee $5 + (f64.ne + (local.tee $23 + (f64.mul + (call $_frexp + (local.get $15) + (local.tee $5 + (local.get $20) + ) ) + (f64.const 2) ) - (f64.const 2) ) + (f64.const 0) ) - (f64.const 0) ) - ) - (i32.store - (local.get $20) - (i32.add - (i32.load + (then + (i32.store (local.get $20) - ) - (i32.const -1) - ) - ) - ) - (if - (i32.eq - (local.tee $24 - (i32.or - (local.get $18) - (i32.const 32) - ) - ) - (i32.const 97) - ) - (block - (local.set $9 - (select (i32.add - (local.get $31) - (i32.const 9) - ) - (local.get $31) - (local.tee $13 - (i32.and - (local.get $18) - (i32.const 32) + (i32.load + (local.get $20) ) + (i32.const -1) ) ) ) - (local.set $15 - (if (result f64) + ) + (if + (i32.eq + (local.tee $24 (i32.or - (i32.gt_u - (local.get $6) - (i32.const 11) - ) - (i32.eqz - (local.tee $5 - (i32.sub - (i32.const 12) - (local.get $6) - ) - ) - ) + (local.get $18) + (i32.const 32) ) - (local.get $23) - (block (result f64) - (local.set $15 - (f64.const 8) - ) - (loop $while-in54 - (local.set $15 - (f64.mul - (local.get $15) - (f64.const 16) - ) + ) + (i32.const 97) + ) + (then + (block + (local.set $9 + (select + (i32.add + (local.get $31) + (i32.const 9) ) - (br_if $while-in54 - (local.tee $5 - (i32.add - (local.get $5) - (i32.const -1) - ) + (local.get $31) + (local.tee $13 + (i32.and + (local.get $18) + (i32.const 32) ) ) ) + ) + (local.set $15 (if (result f64) - (i32.eq - (i32.load8_s - (local.get $9) + (i32.or + (i32.gt_u + (local.get $6) + (i32.const 11) ) - (i32.const 45) - ) - (f64.neg - (f64.add - (local.get $15) - (f64.sub - (f64.neg - (local.get $23) + (i32.eqz + (local.tee $5 + (i32.sub + (i32.const 12) + (local.get $6) ) - (local.get $15) ) ) ) - (f64.sub - (f64.add - (local.get $23) - (local.get $15) + (then + (local.get $23) + ) + (else + (block (result f64) + (local.set $15 + (f64.const 8) + ) + (loop $while-in54 + (local.set $15 + (f64.mul + (local.get $15) + (f64.const 16) + ) + ) + (br_if $while-in54 + (local.tee $5 + (i32.add + (local.get $5) + (i32.const -1) + ) + ) + ) + ) + (if (result f64) + (i32.eq + (i32.load8_s + (local.get $9) + ) + (i32.const 45) + ) + (then + (f64.neg + (f64.add + (local.get $15) + (f64.sub + (f64.neg + (local.get $23) + ) + (local.get $15) + ) + ) + ) + ) + (else + (f64.sub + (f64.add + (local.get $23) + (local.get $15) + ) + (local.get $15) + ) + ) + ) ) - (local.get $15) ) ) ) - ) - ) - (if - (i32.eq - (local.tee $5 - (call $_fmt_u + (if + (i32.eq (local.tee $5 - (select - (i32.sub - (i32.const 0) - (local.tee $7 - (i32.load - (local.get $20) + (call $_fmt_u + (local.tee $5 + (select + (i32.sub + (i32.const 0) + (local.tee $7 + (i32.load + (local.get $20) + ) + ) + ) + (local.get $7) + (i32.lt_s + (local.get $7) + (i32.const 0) ) ) ) - (local.get $7) - (i32.lt_s - (local.get $7) - (i32.const 0) + (i32.shr_s + (i32.shl + (i32.lt_s + (local.get $5) + (i32.const 0) + ) + (i32.const 31) + ) + (i32.const 31) ) + (local.get $34) ) ) - (i32.shr_s - (i32.shl - (i32.lt_s - (local.get $5) - (i32.const 0) - ) + (local.get $34) + ) + (then + (block + (i32.store8 + (local.get $42) + (i32.const 48) + ) + (local.set $5 + (local.get $42) + ) + ) + ) + ) + (local.set $12 + (i32.or + (local.get $27) + (i32.const 2) + ) + ) + (i32.store8 + (i32.add + (local.get $5) + (i32.const -1) + ) + (i32.add + (i32.and + (i32.shr_s + (local.get $7) (i32.const 31) ) - (i32.const 31) + (i32.const 2) ) - (local.get $34) + (i32.const 43) ) ) - (local.get $34) - ) - (block (i32.store8 - (local.get $42) - (i32.const 48) + (local.tee $8 + (i32.add + (local.get $5) + (i32.const -2) + ) + ) + (i32.add + (local.get $18) + (i32.const 15) + ) ) - (local.set $5 - (local.get $42) + (local.set $18 + (i32.lt_s + (local.get $6) + (i32.const 1) + ) ) - ) - ) - (local.set $12 - (i32.or - (local.get $27) - (i32.const 2) - ) - ) - (i32.store8 - (i32.add - (local.get $5) - (i32.const -1) - ) - (i32.add - (i32.and - (i32.shr_s - (local.get $7) - (i32.const 31) + (local.set $17 + (i32.eqz + (i32.and + (local.get $11) + (i32.const 8) + ) ) - (i32.const 2) ) - (i32.const 43) - ) - ) - (i32.store8 - (local.tee $8 - (i32.add - (local.get $5) - (i32.const -2) + (local.set $5 + (local.get $22) ) - ) - (i32.add - (local.get $18) - (i32.const 15) - ) - ) - (local.set $18 - (i32.lt_s - (local.get $6) - (i32.const 1) - ) - ) - (local.set $17 - (i32.eqz - (i32.and - (local.get $11) - (i32.const 8) - ) - ) - ) - (local.set $5 - (local.get $22) - ) - (loop $while-in56 - (i32.store8 - (local.get $5) - (i32.or - (i32.load8_u - (i32.add - (local.tee $7 - (call $f64-to-int - (local.get $15) + (loop $while-in56 + (i32.store8 + (local.get $5) + (i32.or + (i32.load8_u + (i32.add + (local.tee $7 + (call $f64-to-int + (local.get $15) + ) + ) + (i32.const 4075) ) ) - (i32.const 4075) + (local.get $13) ) ) - (local.get $13) - ) - ) - (local.set $15 - (f64.mul - (f64.sub - (local.get $15) - (f64.convert_i32_s - (local.get $7) + (local.set $15 + (f64.mul + (f64.sub + (local.get $15) + (f64.convert_i32_s + (local.get $7) + ) + ) + (f64.const 16) ) ) - (f64.const 16) - ) - ) - (local.set $5 - (block $do-once57 (result i32) - (if (result i32) - (i32.eq - (i32.sub - (local.tee $7 - (i32.add - (local.get $5) - (i32.const 1) + (local.set $5 + (block $do-once57 (result i32) + (if (result i32) + (i32.eq + (i32.sub + (local.tee $7 + (i32.add + (local.get $5) + (i32.const 1) + ) + ) + (local.get $37) + ) + (i32.const 1) + ) + (then + (block (result i32) + (drop + (br_if $do-once57 + (local.get $7) + (i32.and + (local.get $17) + (i32.and + (local.get $18) + (f64.eq + (local.get $15) + (f64.const 0) + ) + ) + ) + ) + ) + (i32.store8 + (local.get $7) + (i32.const 46) + ) + (i32.add + (local.get $5) + (i32.const 2) + ) ) ) - (local.get $37) + (else + (local.get $7) + ) ) - (i32.const 1) ) - (block (result i32) - (drop - (br_if $do-once57 - (local.get $7) + ) + (br_if $while-in56 + (f64.ne + (local.get $15) + (f64.const 0) + ) + ) + ) + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) + (local.tee $7 + (i32.add + (local.tee $6 + (select + (i32.sub + (i32.add + (local.get $47) + (local.get $6) + ) + (local.get $8) + ) + (i32.add + (i32.sub + (local.get $45) + (local.get $8) + ) + (local.get $5) + ) (i32.and - (local.get $17) - (i32.and - (local.get $18) - (f64.eq - (local.get $15) - (f64.const 0) + (i32.ne + (local.get $6) + (i32.const 0) + ) + (i32.lt_s + (i32.add + (local.get $46) + (local.get $5) ) + (local.get $6) ) ) ) ) - (i32.store8 - (local.get $7) - (i32.const 46) + (local.get $12) + ) + ) + (local.get $11) + ) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) ) - (i32.add - (local.get $5) - (i32.const 2) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $9) + (local.get $12) + (local.get $0) ) ) - (local.get $7) ) ) - ) - (br_if $while-in56 - (f64.ne - (local.get $15) - (f64.const 0) + (call $_pad + (local.get $0) + (i32.const 48) + (local.get $14) + (local.get $7) + (i32.xor + (local.get $11) + (i32.const 65536) + ) ) - ) - ) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (local.tee $7 - (i32.add - (local.tee $6 - (select - (i32.sub - (i32.add - (local.get $47) - (local.get $6) - ) - (local.get $8) + (local.set $5 + (i32.sub + (local.get $5) + (local.get $37) + ) + ) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) ) - (i32.add + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $22) + (local.get $5) + (local.get $0) + ) + ) + ) + ) + (call $_pad + (local.get $0) + (i32.const 48) + (i32.sub + (local.get $6) + (i32.add + (local.get $5) + (local.tee $5 (i32.sub - (local.get $45) + (local.get $28) (local.get $8) ) + ) + ) + ) + (i32.const 0) + (i32.const 0) + ) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $8) (local.get $5) + (local.get $0) ) - (i32.and - (i32.ne - (local.get $6) - (i32.const 0) - ) - (i32.lt_s - (i32.add - (local.get $46) - (local.get $5) - ) - (local.get $6) + ) + ) + ) + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) + (local.get $7) + (i32.xor + (local.get $11) + (i32.const 8192) + ) + ) + (br $do-once49 + (select + (local.get $14) + (local.get $7) + (i32.lt_s + (local.get $7) + (local.get $14) + ) + ) + ) + ) + ) + ) + (local.set $15 + (if (result f64) + (local.get $5) + (then + (block (result f64) + (i32.store + (local.get $20) + (local.tee $5 + (i32.add + (i32.load + (local.get $20) ) + (i32.const -28) ) ) ) - (local.get $12) + (f64.mul + (local.get $23) + (f64.const 268435456) + ) ) ) - (local.get $11) - ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) + (else + (block (result f64) + (local.set $5 + (i32.load + (local.get $20) + ) ) - (i32.const 32) + (local.get $23) ) ) - (drop - (call $___fwritex - (local.get $9) - (local.get $12) - (local.get $0) - ) - ) - ) - (call $_pad - (local.get $0) - (i32.const 48) - (local.get $14) - (local.get $7) - (i32.xor - (local.get $11) - (i32.const 65536) - ) - ) - (local.set $5 - (i32.sub - (local.get $5) - (local.get $37) - ) - ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $22) - (local.get $5) - (local.get $0) - ) - ) - ) - (call $_pad - (local.get $0) - (i32.const 48) - (i32.sub - (local.get $6) - (i32.add - (local.get $5) - (local.tee $5 - (i32.sub - (local.get $28) - (local.get $8) - ) - ) - ) - ) - (i32.const 0) - (i32.const 0) ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $8) + ) + (local.set $7 + (local.tee $8 + (select + (local.get $48) + (local.get $49) + (i32.lt_s (local.get $5) - (local.get $0) + (i32.const 0) ) ) ) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) + ) + (loop $while-in60 + (i32.store (local.get $7) - (i32.xor - (local.get $11) - (i32.const 8192) + (local.tee $5 + (call $f64-to-int + (local.get $15) + ) ) ) - (br $do-once49 - (select - (local.get $14) + (local.set $7 + (i32.add (local.get $7) - (i32.lt_s - (local.get $7) - (local.get $14) - ) + (i32.const 4) ) ) - ) - ) - (local.set $15 - (if (result f64) - (local.get $5) - (block (result f64) - (i32.store - (local.get $20) - (local.tee $5 - (i32.add - (i32.load - (local.get $20) + (br_if $while-in60 + (f64.ne + (local.tee $15 + (f64.mul + (f64.sub + (local.get $15) + (f64.convert_i32_u + (local.get $5) + ) ) - (i32.const -28) + (f64.const 1e9) ) ) - ) - (f64.mul - (local.get $23) - (f64.const 268435456) + (f64.const 0) ) ) - (block (result f64) - (local.set $5 + ) + (if + (i32.gt_s + (local.tee $9 (i32.load (local.get $20) ) ) - (local.get $23) - ) - ) - ) - (local.set $7 - (local.tee $8 - (select - (local.get $48) - (local.get $49) - (i32.lt_s - (local.get $5) - (i32.const 0) - ) - ) - ) - ) - (loop $while-in60 - (i32.store - (local.get $7) - (local.tee $5 - (call $f64-to-int - (local.get $15) - ) - ) - ) - (local.set $7 - (i32.add - (local.get $7) - (i32.const 4) - ) - ) - (br_if $while-in60 - (f64.ne - (local.tee $15 - (f64.mul - (f64.sub - (local.get $15) - (f64.convert_i32_u - (local.get $5) - ) - ) - (f64.const 1e9) - ) - ) - (f64.const 0) - ) - ) - ) - (if - (i32.gt_s - (local.tee $9 - (i32.load - (local.get $20) - ) - ) - (i32.const 0) - ) - (block - (local.set $5 - (local.get $8) + (i32.const 0) ) - (loop $while-in62 - (local.set $13 - (select - (i32.const 29) - (local.get $9) - (i32.gt_s - (local.get $9) - (i32.const 29) - ) + (then + (block + (local.set $5 + (local.get $8) ) - ) - (block $do-once63 - (if - (i32.ge_u - (local.tee $9 - (i32.add - (local.get $7) - (i32.const -4) + (loop $while-in62 + (local.set $13 + (select + (i32.const 29) + (local.get $9) + (i32.gt_s + (local.get $9) + (i32.const 29) ) ) - (local.get $5) ) - (block - (local.set $12 - (i32.const 0) - ) - (loop $while-in66 - (i32.store - (local.get $9) - (call $___uremdi3 - (local.tee $12 - (call $_i64Add - (call $_bitshift64Shl - (i32.load - (local.get $9) + (block $do-once63 + (if + (i32.ge_u + (local.tee $9 + (i32.add + (local.get $7) + (i32.const -4) + ) + ) + (local.get $5) + ) + (then + (block + (local.set $12 + (i32.const 0) + ) + (loop $while-in66 + (i32.store + (local.get $9) + (call $___uremdi3 + (local.tee $12 + (call $_i64Add + (call $_bitshift64Shl + (i32.load + (local.get $9) + ) + (i32.const 0) + (local.get $13) + ) + (global.get $tempRet0) + (local.get $12) + (i32.const 0) + ) + ) + (local.tee $17 + (global.get $tempRet0) ) + (i32.const 1000000000) (i32.const 0) - (local.get $13) ) - (global.get $tempRet0) + ) + (local.set $12 + (call $___udivdi3 + (local.get $12) + (local.get $17) + (i32.const 1000000000) + (i32.const 0) + ) + ) + (br_if $while-in66 + (i32.ge_u + (local.tee $9 + (i32.add + (local.get $9) + (i32.const -4) + ) + ) + (local.get $5) + ) + ) + ) + (br_if $do-once63 + (i32.eqz (local.get $12) - (i32.const 0) ) ) - (local.tee $17 - (global.get $tempRet0) + (i32.store + (local.tee $5 + (i32.add + (local.get $5) + (i32.const -4) + ) + ) + (local.get $12) ) - (i32.const 1000000000) - (i32.const 0) ) ) - (local.set $12 - (call $___udivdi3 - (local.get $12) - (local.get $17) - (i32.const 1000000000) - (i32.const 0) - ) + ) + ) + (loop $while-in68 + (if + (i32.gt_u + (local.get $7) + (local.get $5) ) - (br_if $while-in66 - (i32.ge_u - (local.tee $9 - (i32.add - (local.get $9) - (i32.const -4) + (then + (if + (i32.eqz + (i32.load + (local.tee $9 + (i32.add + (local.get $7) + (i32.const -4) + ) + ) + ) + ) + (then + (block + (local.set $7 + (local.get $9) + ) + (br $while-in68) ) ) - (local.get $5) ) ) ) - (br_if $do-once63 - (i32.eqz - (local.get $12) - ) - ) - (i32.store - (local.tee $5 - (i32.add - (local.get $5) - (i32.const -4) + ) + (i32.store + (local.get $20) + (local.tee $9 + (i32.sub + (i32.load + (local.get $20) ) + (local.get $13) ) - (local.get $12) ) ) - ) - ) - (loop $while-in68 - (if - (i32.gt_u - (local.get $7) - (local.get $5) - ) - (if - (i32.eqz - (i32.load - (local.tee $9 - (i32.add - (local.get $7) - (i32.const -4) - ) - ) - ) - ) - (block - (local.set $7 - (local.get $9) - ) - (br $while-in68) - ) - ) - ) - ) - (i32.store - (local.get $20) - (local.tee $9 - (i32.sub - (i32.load - (local.get $20) + (br_if $while-in62 + (i32.gt_s + (local.get $9) + (i32.const 0) ) - (local.get $13) ) ) ) - (br_if $while-in62 - (i32.gt_s - (local.get $9) - (i32.const 0) - ) + ) + (else + (local.set $5 + (local.get $8) ) ) ) - (local.set $5 - (local.get $8) + (local.set $17 + (select + (i32.const 6) + (local.get $6) + (i32.lt_s + (local.get $6) + (i32.const 0) + ) + ) ) - ) - (local.set $17 - (select - (i32.const 6) - (local.get $6) + (if (i32.lt_s - (local.get $6) + (local.get $9) (i32.const 0) ) - ) - ) - (if - (i32.lt_s - (local.get $9) - (i32.const 0) - ) - (block - (local.set $21 - (i32.add - (call $i32s-div + (then + (block + (local.set $21 (i32.add - (local.get $17) - (i32.const 25) - ) - (i32.const 9) - ) - (i32.const 1) - ) - ) - (local.set $32 - (i32.eq - (local.get $24) - (i32.const 102) - ) - ) - (local.set $6 - (local.get $5) - ) - (local.set $5 - (local.get $7) - ) - (loop $while-in70 - (local.set $13 - (select - (i32.const 9) - (local.tee $7 - (i32.sub - (i32.const 0) - (local.get $9) + (call $i32s-div + (i32.add + (local.get $17) + (i32.const 25) + ) + (i32.const 9) ) - ) - (i32.gt_s - (local.get $7) - (i32.const 9) + (i32.const 1) ) ) - ) - (block $do-once71 - (if - (i32.lt_u - (local.get $6) - (local.get $5) + (local.set $32 + (i32.eq + (local.get $24) + (i32.const 102) ) - (block - (local.set $12 - (i32.add - (i32.shl - (i32.const 1) - (local.get $13) + ) + (local.set $6 + (local.get $5) + ) + (local.set $5 + (local.get $7) + ) + (loop $while-in70 + (local.set $13 + (select + (i32.const 9) + (local.tee $7 + (i32.sub + (i32.const 0) + (local.get $9) ) - (i32.const -1) ) - ) - (local.set $38 - (i32.shr_u - (i32.const 1000000000) - (local.get $13) + (i32.gt_s + (local.get $7) + (i32.const 9) ) ) - (local.set $9 - (i32.const 0) - ) - (local.set $7 - (local.get $6) - ) - (loop $while-in74 - (i32.store - (local.get $7) - (i32.add - (i32.shr_u - (local.tee $33 + ) + (block $do-once71 + (if + (i32.lt_u + (local.get $6) + (local.get $5) + ) + (then + (block + (local.set $12 + (i32.add + (i32.shl + (i32.const 1) + (local.get $13) + ) + (i32.const -1) + ) + ) + (local.set $38 + (i32.shr_u + (i32.const 1000000000) + (local.get $13) + ) + ) + (local.set $9 + (i32.const 0) + ) + (local.set $7 + (local.get $6) + ) + (loop $while-in74 + (i32.store + (local.get $7) + (i32.add + (i32.shr_u + (local.tee $33 + (i32.load + (local.get $7) + ) + ) + (local.get $13) + ) + (local.get $9) + ) + ) + (local.set $9 + (i32.mul + (i32.and + (local.get $33) + (local.get $12) + ) + (local.get $38) + ) + ) + (br_if $while-in74 + (i32.lt_u + (local.tee $7 + (i32.add + (local.get $7) + (i32.const 4) + ) + ) + (local.get $5) + ) + ) + ) + (local.set $7 + (select + (local.get $6) + (i32.add + (local.get $6) + (i32.const 4) + ) (i32.load - (local.get $7) + (local.get $6) ) ) - (local.get $13) ) - (local.get $9) - ) - ) - (local.set $9 - (i32.mul - (i32.and - (local.get $33) - (local.get $12) + (br_if $do-once71 + (i32.eqz + (local.get $9) + ) + ) + (i32.store + (local.get $5) + (local.get $9) + ) + (local.set $5 + (i32.add + (local.get $5) + (i32.const 4) + ) ) - (local.get $38) ) ) - (br_if $while-in74 - (i32.lt_u - (local.tee $7 + (else + (local.set $7 + (select + (local.get $6) (i32.add - (local.get $7) + (local.get $6) (i32.const 4) ) + (i32.load + (local.get $6) + ) ) - (local.get $5) ) ) ) - (local.set $7 - (select - (local.get $6) - (i32.add - (local.get $6) - (i32.const 4) + ) + (local.set $12 + (select + (i32.add + (local.tee $6 + (select + (local.get $8) + (local.get $7) + (local.get $32) + ) ) - (i32.load - (local.get $6) + (i32.shl + (local.get $21) + (i32.const 2) ) ) - ) - (br_if $do-once71 - (i32.eqz - (local.get $9) - ) - ) - (i32.store (local.get $5) - (local.get $9) - ) - (local.set $5 - (i32.add - (local.get $5) - (i32.const 4) + (i32.gt_s + (i32.shr_s + (i32.sub + (local.get $5) + (local.get $6) + ) + (i32.const 2) + ) + (local.get $21) ) ) ) - (local.set $7 - (select - (local.get $6) + (i32.store + (local.get $20) + (local.tee $9 (i32.add - (local.get $6) - (i32.const 4) - ) - (i32.load - (local.get $6) + (i32.load + (local.get $20) + ) + (local.get $13) ) ) ) - ) - ) - (local.set $12 - (select - (i32.add - (local.tee $6 - (select - (local.get $8) - (local.get $7) - (local.get $32) - ) - ) - (i32.shl - (local.get $21) - (i32.const 2) + (if + (i32.lt_s + (local.get $9) + (i32.const 0) ) - ) - (local.get $5) - (i32.gt_s - (i32.shr_s - (i32.sub - (local.get $5) - (local.get $6) + (then + (block + (local.set $6 + (local.get $7) + ) + (local.set $5 + (local.get $12) + ) + (br $while-in70) ) - (i32.const 2) ) - (local.get $21) - ) - ) - ) - (i32.store - (local.get $20) - (local.tee $9 - (i32.add - (i32.load - (local.get $20) + (else + (block + (local.set $5 + (local.get $7) + ) + (local.set $9 + (local.get $12) + ) + ) ) - (local.get $13) ) ) ) - (if - (i32.lt_s - (local.get $9) - (i32.const 0) - ) - (block - (local.set $6 - (local.get $7) - ) - (local.set $5 - (local.get $12) - ) - (br $while-in70) - ) - (block - (local.set $5 - (local.get $7) - ) - (local.set $9 - (local.get $12) - ) - ) + ) + (else + (local.set $9 + (local.get $7) ) ) ) - (local.set $9 - (local.get $7) + (local.set $21 + (local.get $8) ) - ) - (local.set $21 - (local.get $8) - ) - (block $do-once75 - (if - (i32.lt_u - (local.get $5) - (local.get $9) - ) - (block - (local.set $7 - (i32.mul - (i32.shr_s - (i32.sub - (local.get $21) - (local.get $5) + (block $do-once75 + (if + (i32.lt_u + (local.get $5) + (local.get $9) + ) + (then + (block + (local.set $7 + (i32.mul + (i32.shr_s + (i32.sub + (local.get $21) + (local.get $5) + ) + (i32.const 2) + ) + (i32.const 9) ) - (i32.const 2) ) - (i32.const 9) - ) - ) - (br_if $do-once75 - (i32.lt_u - (local.tee $12 - (i32.load - (local.get $5) + (br_if $do-once75 + (i32.lt_u + (local.tee $12 + (i32.load + (local.get $5) + ) + ) + (i32.const 10) ) ) - (i32.const 10) - ) - ) - (local.set $6 - (i32.const 10) - ) - (loop $while-in78 - (local.set $7 - (i32.add - (local.get $7) - (i32.const 1) + (local.set $6 + (i32.const 10) ) - ) - (br_if $while-in78 - (i32.ge_u - (local.get $12) - (local.tee $6 - (i32.mul - (local.get $6) - (i32.const 10) + (loop $while-in78 + (local.set $7 + (i32.add + (local.get $7) + (i32.const 1) + ) + ) + (br_if $while-in78 + (i32.ge_u + (local.get $12) + (local.tee $6 + (i32.mul + (local.get $6) + (i32.const 10) + ) + ) ) ) ) ) ) - ) - (local.set $7 - (i32.const 0) + (else + (local.set $7 + (i32.const 0) + ) + ) ) ) - ) - (local.set $5 - (if (result i32) - (i32.lt_s - (local.tee $6 - (i32.add - (i32.sub - (local.get $17) - (select - (local.get $7) - (i32.const 0) - (i32.ne - (local.get $24) - (i32.const 102) + (local.set $5 + (if (result i32) + (i32.lt_s + (local.tee $6 + (i32.add + (i32.sub + (local.get $17) + (select + (local.get $7) + (i32.const 0) + (i32.ne + (local.get $24) + (i32.const 102) + ) ) ) - ) - (i32.shr_s - (i32.shl - (i32.and - (local.tee $32 - (i32.ne - (local.get $17) - (i32.const 0) + (i32.shr_s + (i32.shl + (i32.and + (local.tee $32 + (i32.ne + (local.get $17) + (i32.const 0) + ) ) - ) - (local.tee $38 - (i32.eq - (local.get $24) - (i32.const 103) + (local.tee $38 + (i32.eq + (local.get $24) + (i32.const 103) + ) ) ) + (i32.const 31) ) (i32.const 31) ) - (i32.const 31) - ) - ) - ) - (i32.add - (i32.mul - (i32.shr_s - (i32.sub - (local.get $9) - (local.get $21) - ) - (i32.const 2) ) - (i32.const 9) ) - (i32.const -9) - ) - ) - (block (result i32) - (local.set $13 - (call $i32s-div - (local.tee $6 - (i32.add - (local.get $6) - (i32.const 9216) + (i32.add + (i32.mul + (i32.shr_s + (i32.sub + (local.get $9) + (local.get $21) + ) + (i32.const 2) ) + (i32.const 9) ) - (i32.const 9) + (i32.const -9) ) ) - (if - (i32.lt_s - (local.tee $6 - (i32.add - (if (result i32) - (local.tee $12 - (i32.const 9) - ) - (i32.rem_s + (then + (block (result i32) + (local.set $13 + (call $i32s-div + (local.tee $6 + (i32.add (local.get $6) - (local.get $12) - ) - (i32.const 0) - ) - (i32.const 1) - ) - ) - (i32.const 9) - ) - (block - (local.set $12 - (i32.const 10) - ) - (loop $while-in80 - (local.set $12 - (i32.mul - (local.get $12) - (i32.const 10) - ) - ) - (br_if $while-in80 - (i32.ne - (local.tee $6 - (i32.add - (local.get $6) - (i32.const 1) - ) + (i32.const 9216) ) - (i32.const 9) ) + (i32.const 9) ) ) - ) - (local.set $12 - (i32.const 10) - ) - ) - (local.set $13 - (call $i32u-rem - (local.tee $24 - (i32.load + (if + (i32.lt_s (local.tee $6 (i32.add - (i32.add - (local.get $8) - (i32.shl - (local.get $13) - (i32.const 2) + (if (result i32) + (local.tee $12 + (i32.const 9) + ) + (then + (i32.rem_s + (local.get $6) + (local.get $12) + ) + ) + (else + (i32.const 0) ) ) - (i32.const -4092) + (i32.const 1) ) ) + (i32.const 9) ) - ) - (local.get $12) - ) - ) - (block $do-once81 - (if - (i32.eqz - (i32.and - (local.tee $33 - (i32.eq - (i32.add - (local.get $6) - (i32.const 4) + (then + (block + (local.set $12 + (i32.const 10) + ) + (loop $while-in80 + (local.set $12 + (i32.mul + (local.get $12) + (i32.const 10) + ) + ) + (br_if $while-in80 + (i32.ne + (local.tee $6 + (i32.add + (local.get $6) + (i32.const 1) + ) + ) + (i32.const 9) + ) ) - (local.get $9) ) ) - (i32.eqz - (local.get $13) - ) ) - ) - (block - (local.set $50 - (call $i32u-div - (local.get $24) - (local.get $12) + (else + (local.set $12 + (i32.const 10) ) ) - (local.set $15 - (if (result f64) - (i32.lt_u - (local.get $13) - (local.tee $51 - (call $i32s-div - (local.get $12) - (i32.const 2) - ) - ) - ) - (f64.const 0.5) - (select - (f64.const 1) - (f64.const 1.5) - (i32.and - (local.get $33) - (i32.eq - (local.get $13) - (local.get $51) + ) + (local.set $13 + (call $i32u-rem + (local.tee $24 + (i32.load + (local.tee $6 + (i32.add + (i32.add + (local.get $8) + (i32.shl + (local.get $13) + (i32.const 2) + ) + ) + (i32.const -4092) ) ) ) ) + (local.get $12) ) - (local.set $23 - (select - (f64.const 9007199254740994) - (f64.const 9007199254740992) + ) + (block $do-once81 + (if + (i32.eqz (i32.and - (local.get $50) - (i32.const 1) + (local.tee $33 + (i32.eq + (i32.add + (local.get $6) + (i32.const 4) + ) + (local.get $9) + ) + ) + (i32.eqz + (local.get $13) + ) ) ) - ) - (block $do-once83 - (if - (local.get $27) + (then (block - (br_if $do-once83 - (i32.ne - (i32.load8_s - (local.get $31) + (local.set $50 + (call $i32u-div + (local.get $24) + (local.get $12) + ) + ) + (local.set $15 + (if (result f64) + (i32.lt_u + (local.get $13) + (local.tee $51 + (call $i32s-div + (local.get $12) + (i32.const 2) + ) + ) + ) + (then + (f64.const 0.5) + ) + (else + (select + (f64.const 1) + (f64.const 1.5) + (i32.and + (local.get $33) + (i32.eq + (local.get $13) + (local.get $51) + ) + ) + ) ) - (i32.const 45) ) ) (local.set $23 - (f64.neg - (local.get $23) + (select + (f64.const 9007199254740994) + (f64.const 9007199254740992) + (i32.and + (local.get $50) + (i32.const 1) + ) ) ) - (local.set $15 - (f64.neg - (local.get $15) + (block $do-once83 + (if + (local.get $27) + (then + (block + (br_if $do-once83 + (i32.ne + (i32.load8_s + (local.get $31) + ) + (i32.const 45) + ) + ) + (local.set $23 + (f64.neg + (local.get $23) + ) + ) + (local.set $15 + (f64.neg + (local.get $15) + ) + ) + ) + ) ) ) - ) - ) - ) - (i32.store - (local.get $6) - (local.tee $13 - (i32.sub - (local.get $24) - (local.get $13) - ) - ) - ) - (br_if $do-once81 - (f64.eq - (f64.add - (local.get $23) - (local.get $15) - ) - (local.get $23) - ) - ) - (i32.store - (local.get $6) - (local.tee $7 - (i32.add - (local.get $13) - (local.get $12) - ) - ) - ) - (if - (i32.gt_u - (local.get $7) - (i32.const 999999999) - ) - (loop $while-in86 - (i32.store - (local.get $6) - (i32.const 0) - ) - (if - (i32.lt_u - (local.tee $6 - (i32.add - (local.get $6) - (i32.const -4) + (i32.store + (local.get $6) + (local.tee $13 + (i32.sub + (local.get $24) + (local.get $13) ) ) - (local.get $5) + ) + (br_if $do-once81 + (f64.eq + (f64.add + (local.get $23) + (local.get $15) + ) + (local.get $23) + ) ) (i32.store - (local.tee $5 + (local.get $6) + (local.tee $7 (i32.add - (local.get $5) - (i32.const -4) + (local.get $13) + (local.get $12) ) ) - (i32.const 0) ) - ) - (i32.store - (local.get $6) - (local.tee $7 - (i32.add - (i32.load - (local.get $6) + (if + (i32.gt_u + (local.get $7) + (i32.const 999999999) + ) + (then + (loop $while-in86 + (i32.store + (local.get $6) + (i32.const 0) + ) + (if + (i32.lt_u + (local.tee $6 + (i32.add + (local.get $6) + (i32.const -4) + ) + ) + (local.get $5) + ) + (then + (i32.store + (local.tee $5 + (i32.add + (local.get $5) + (i32.const -4) + ) + ) + (i32.const 0) + ) + ) + ) + (i32.store + (local.get $6) + (local.tee $7 + (i32.add + (i32.load + (local.get $6) + ) + (i32.const 1) + ) + ) + ) + (br_if $while-in86 + (i32.gt_u + (local.get $7) + (i32.const 999999999) + ) + ) ) - (i32.const 1) ) ) - ) - (br_if $while-in86 - (i32.gt_u - (local.get $7) - (i32.const 999999999) + (local.set $7 + (i32.mul + (i32.shr_s + (i32.sub + (local.get $21) + (local.get $5) + ) + (i32.const 2) + ) + (i32.const 9) + ) ) - ) - ) - ) - (local.set $7 - (i32.mul - (i32.shr_s - (i32.sub - (local.get $21) - (local.get $5) + (br_if $do-once81 + (i32.lt_u + (local.tee $13 + (i32.load + (local.get $5) + ) + ) + (i32.const 10) + ) ) - (i32.const 2) - ) - (i32.const 9) - ) - ) - (br_if $do-once81 - (i32.lt_u - (local.tee $13 - (i32.load - (local.get $5) + (local.set $12 + (i32.const 10) + ) + (loop $while-in88 + (local.set $7 + (i32.add + (local.get $7) + (i32.const 1) + ) + ) + (br_if $while-in88 + (i32.ge_u + (local.get $13) + (local.tee $12 + (i32.mul + (local.get $12) + (i32.const 10) + ) + ) + ) + ) ) ) - (i32.const 10) ) ) - (local.set $12 - (i32.const 10) - ) - (loop $while-in88 - (local.set $7 - (i32.add - (local.get $7) - (i32.const 1) - ) - ) - (br_if $while-in88 - (i32.ge_u - (local.get $13) - (local.tee $12 - (i32.mul - (local.get $12) - (i32.const 10) - ) - ) - ) + ) + (local.set $12 + (local.get $5) + ) + (local.set $13 + (local.get $7) + ) + (select + (local.tee $5 + (i32.add + (local.get $6) + (i32.const 4) ) ) + (local.get $9) + (i32.gt_u + (local.get $9) + (local.get $5) + ) ) ) ) - (local.set $12 - (local.get $5) - ) - (local.set $13 - (local.get $7) - ) - (select - (local.tee $5 - (i32.add - (local.get $6) - (i32.const 4) + (else + (block (result i32) + (local.set $12 + (local.get $5) + ) + (local.set $13 + (local.get $7) ) - ) - (local.get $9) - (i32.gt_u (local.get $9) - (local.get $5) ) ) ) - (block (result i32) - (local.set $12 - (local.get $5) - ) - (local.set $13 - (local.get $7) - ) - (local.get $9) - ) ) - ) - (local.set $33 - (i32.sub - (i32.const 0) - (local.get $13) + (local.set $33 + (i32.sub + (i32.const 0) + (local.get $13) + ) ) - ) - (loop $while-in90 - (block $while-out89 - (if - (i32.le_u - (local.get $5) - (local.get $12) - ) - (block - (local.set $24 - (i32.const 0) - ) - (local.set $9 + (loop $while-in90 + (block $while-out89 + (if + (i32.le_u (local.get $5) + (local.get $12) ) - (br $while-out89) - ) - ) - (if - (i32.load - (local.tee $7 - (i32.add - (local.get $5) - (i32.const -4) + (then + (block + (local.set $24 + (i32.const 0) + ) + (local.set $9 + (local.get $5) + ) + (br $while-out89) ) ) ) - (block - (local.set $24 - (i32.const 1) + (if + (i32.load + (local.tee $7 + (i32.add + (local.get $5) + (i32.const -4) + ) + ) ) - (local.set $9 - (local.get $5) + (then + (block + (local.set $24 + (i32.const 1) + ) + (local.set $9 + (local.get $5) + ) + ) ) - ) - (block - (local.set $5 - (local.get $7) + (else + (block + (local.set $5 + (local.get $7) + ) + (br $while-in90) + ) ) - (br $while-in90) ) ) ) - ) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (local.tee $13 - (i32.add + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) + (local.tee $13 (i32.add (i32.add (i32.add - (local.get $27) - (i32.const 1) - ) - (local.tee $5 - (block $do-once91 (result i32) - (if (result i32) - (local.get $38) - (block (result i32) - (local.set $7 - (if (result i32) - (i32.and - (i32.gt_s - (local.tee $5 - (i32.add - (i32.xor - (local.get $32) - (i32.const 1) + (i32.add + (local.get $27) + (i32.const 1) + ) + (local.tee $5 + (block $do-once91 (result i32) + (if (result i32) + (local.get $38) + (then + (block (result i32) + (local.set $7 + (if (result i32) + (i32.and + (i32.gt_s + (local.tee $5 + (i32.add + (i32.xor + (local.get $32) + (i32.const 1) + ) + (local.get $17) + ) ) - (local.get $17) + (local.get $13) + ) + (i32.gt_s + (local.get $13) + (i32.const -5) ) ) - (local.get $13) - ) - (i32.gt_s - (local.get $13) - (i32.const -5) - ) - ) - (block (result i32) - (local.set $17 - (i32.sub - (i32.add - (local.get $5) - (i32.const -1) + (then + (block (result i32) + (local.set $17 + (i32.sub + (i32.add + (local.get $5) + (i32.const -1) + ) + (local.get $13) + ) + ) + (i32.add + (local.get $18) + (i32.const -1) + ) + ) + ) + (else + (block (result i32) + (local.set $17 + (i32.add + (local.get $5) + (i32.const -1) + ) + ) + (i32.add + (local.get $18) + (i32.const -2) + ) ) - (local.get $13) ) - ) - (i32.add - (local.get $18) - (i32.const -1) ) ) - (block (result i32) - (local.set $17 - (i32.add - (local.get $5) - (i32.const -1) + (if + (local.tee $5 + (i32.and + (local.get $11) + (i32.const 8) ) ) - (i32.add - (local.get $18) - (i32.const -2) + (then + (block + (local.set $21 + (local.get $5) + ) + (br $do-once91 + (local.get $17) + ) + ) ) ) - ) - ) - (if - (local.tee $5 - (i32.and - (local.get $11) - (i32.const 8) - ) - ) - (block - (local.set $21 - (local.get $5) - ) - (br $do-once91 - (local.get $17) - ) - ) - ) - (block $do-once93 - (if - (local.get $24) - (block + (block $do-once93 (if - (i32.eqz - (local.tee $18 - (i32.load - (i32.add - (local.get $9) - (i32.const -4) + (local.get $24) + (then + (block + (if + (i32.eqz + (local.tee $18 + (i32.load + (i32.add + (local.get $9) + (i32.const -4) + ) + ) + ) + ) + (then + (block + (local.set $5 + (i32.const 9) + ) + (br $do-once93) + ) + ) + ) + (if + (call $i32u-rem + (local.get $18) + (i32.const 10) + ) + (then + (block + (local.set $5 + (i32.const 0) + ) + (br $do-once93) + ) + ) + (else + (block + (local.set $6 + (i32.const 10) + ) + (local.set $5 + (i32.const 0) + ) + ) + ) + ) + (loop $while-in96 + (local.set $5 + (i32.add + (local.get $5) + (i32.const 1) + ) + ) + (br_if $while-in96 + (i32.eqz + (call $i32u-rem + (local.get $18) + (local.tee $6 + (i32.mul + (local.get $6) + (i32.const 10) + ) + ) + ) + ) ) ) ) ) - (block + (else (local.set $5 (i32.const 9) ) - (br $do-once93) ) ) - (if - (call $i32u-rem - (local.get $18) - (i32.const 10) - ) - (block - (local.set $5 - (i32.const 0) + ) + (local.set $6 + (i32.add + (i32.mul + (i32.shr_s + (i32.sub + (local.get $9) + (local.get $21) + ) + (i32.const 2) ) - (br $do-once93) + (i32.const 9) ) - (block - (local.set $6 - (i32.const 10) - ) - (local.set $5 - (i32.const 0) - ) + (i32.const -9) + ) + ) + (if (result i32) + (i32.eq + (i32.or + (local.get $7) + (i32.const 32) ) + (i32.const 102) ) - (loop $while-in96 - (local.set $5 - (i32.add - (local.get $5) - (i32.const 1) + (then + (block (result i32) + (local.set $21 + (i32.const 0) ) - ) - (br_if $while-in96 - (i32.eqz - (call $i32u-rem - (local.get $18) - (local.tee $6 - (i32.mul - (local.get $6) - (i32.const 10) + (select + (local.get $17) + (local.tee $5 + (select + (i32.const 0) + (local.tee $5 + (i32.sub + (local.get $6) + (local.get $5) + ) + ) + (i32.lt_s + (local.get $5) + (i32.const 0) ) ) ) + (i32.lt_s + (local.get $17) + (local.get $5) + ) ) ) ) - ) - (local.set $5 - (i32.const 9) - ) - ) - ) - (local.set $6 - (i32.add - (i32.mul - (i32.shr_s - (i32.sub - (local.get $9) - (local.get $21) - ) - (i32.const 2) - ) - (i32.const 9) - ) - (i32.const -9) - ) - ) - (if (result i32) - (i32.eq - (i32.or - (local.get $7) - (i32.const 32) - ) - (i32.const 102) - ) - (block (result i32) - (local.set $21 - (i32.const 0) - ) - (select - (local.get $17) - (local.tee $5 - (select - (i32.const 0) - (local.tee $5 - (i32.sub - (local.get $6) - (local.get $5) - ) - ) - (i32.lt_s - (local.get $5) + (else + (block (result i32) + (local.set $21 (i32.const 0) ) - ) - ) - (i32.lt_s - (local.get $17) - (local.get $5) - ) - ) - ) - (block (result i32) - (local.set $21 - (i32.const 0) - ) - (select - (local.get $17) - (local.tee $5 - (select - (i32.const 0) - (local.tee $5 - (i32.sub - (i32.add - (local.get $6) - (local.get $13) + (select + (local.get $17) + (local.tee $5 + (select + (i32.const 0) + (local.tee $5 + (i32.sub + (i32.add + (local.get $6) + (local.get $13) + ) + (local.get $5) + ) + ) + (i32.lt_s + (local.get $5) + (i32.const 0) + ) ) + ) + (i32.lt_s + (local.get $17) (local.get $5) ) ) - (i32.lt_s - (local.get $5) - (i32.const 0) - ) ) ) - (i32.lt_s - (local.get $17) - (local.get $5) - ) ) ) ) - ) - (block (result i32) - (local.set $21 - (i32.and - (local.get $11) - (i32.const 8) + (else + (block (result i32) + (local.set $21 + (i32.and + (local.get $11) + (i32.const 8) + ) + ) + (local.set $7 + (local.get $18) + ) + (local.get $17) ) ) - (local.set $7 - (local.get $18) - ) - (local.get $17) ) ) ) ) - ) - (i32.ne - (local.tee $32 - (i32.or - (local.get $5) - (local.get $21) + (i32.ne + (local.tee $32 + (i32.or + (local.get $5) + (local.get $21) + ) ) + (i32.const 0) ) - (i32.const 0) ) - ) - (if (result i32) - (local.tee $17 - (i32.eq - (i32.or - (local.get $7) - (i32.const 32) + (if (result i32) + (local.tee $17 + (i32.eq + (i32.or + (local.get $7) + (i32.const 32) + ) + (i32.const 102) ) - (i32.const 102) - ) - ) - (block (result i32) - (local.set $18 - (i32.const 0) ) - (select - (local.get $13) - (i32.const 0) - (i32.gt_s - (local.get $13) - (i32.const 0) + (then + (block (result i32) + (local.set $18 + (i32.const 0) + ) + (select + (local.get $13) + (i32.const 0) + (i32.gt_s + (local.get $13) + (i32.const 0) + ) + ) ) ) - ) - (block (result i32) - (if - (i32.lt_s - (i32.sub - (local.get $28) - (local.tee $6 - (call $_fmt_u + (else + (block (result i32) + (if + (i32.lt_s + (i32.sub + (local.get $28) (local.tee $6 - (select - (local.get $33) - (local.get $13) - (i32.lt_s - (local.get $13) - (i32.const 0) + (call $_fmt_u + (local.tee $6 + (select + (local.get $33) + (local.get $13) + (i32.lt_s + (local.get $13) + (i32.const 0) + ) + ) ) + (i32.shr_s + (i32.shl + (i32.lt_s + (local.get $6) + (i32.const 0) + ) + (i32.const 31) + ) + (i32.const 31) + ) + (local.get $34) ) ) - (i32.shr_s - (i32.shl - (i32.lt_s + ) + (i32.const 2) + ) + (then + (loop $while-in98 + (i32.store8 + (local.tee $6 + (i32.add (local.get $6) - (i32.const 0) + (i32.const -1) ) - (i32.const 31) ) - (i32.const 31) + (i32.const 48) + ) + (br_if $while-in98 + (i32.lt_s + (i32.sub + (local.get $28) + (local.get $6) + ) + (i32.const 2) + ) ) - (local.get $34) ) ) ) - (i32.const 2) - ) - (loop $while-in98 (i32.store8 - (local.tee $6 - (i32.add - (local.get $6) - (i32.const -1) + (i32.add + (local.get $6) + (i32.const -1) + ) + (i32.add + (i32.and + (i32.shr_s + (local.get $13) + (i32.const 31) + ) + (i32.const 2) ) + (i32.const 43) ) - (i32.const 48) ) - (br_if $while-in98 - (i32.lt_s - (i32.sub - (local.get $28) + (i32.store8 + (local.tee $6 + (i32.add (local.get $6) + (i32.const -2) ) - (i32.const 2) ) + (local.get $7) ) - ) - ) - (i32.store8 - (i32.add - (local.get $6) - (i32.const -1) - ) - (i32.add - (i32.and - (i32.shr_s - (local.get $13) - (i32.const 31) - ) - (i32.const 2) + (local.set $18 + (local.get $6) ) - (i32.const 43) - ) - ) - (i32.store8 - (local.tee $6 - (i32.add + (i32.sub + (local.get $28) (local.get $6) - (i32.const -2) ) ) - (local.get $7) - ) - (local.set $18 - (local.get $6) - ) - (i32.sub - (local.get $28) - (local.get $6) ) ) ) ) + (local.get $11) ) - (local.get $11) - ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $31) + (local.get $27) + (local.get $0) + ) ) - (i32.const 32) ) ) - (drop - (call $___fwritex - (local.get $31) - (local.get $27) - (local.get $0) + (call $_pad + (local.get $0) + (i32.const 48) + (local.get $14) + (local.get $13) + (i32.xor + (local.get $11) + (i32.const 65536) ) ) - ) - (call $_pad - (local.get $0) - (i32.const 48) - (local.get $14) - (local.get $13) - (i32.xor - (local.get $11) - (i32.const 65536) - ) - ) - (block $do-once99 - (if - (local.get $17) - (block - (local.set $6 - (local.tee $12 - (select - (local.get $8) - (local.get $12) - (i32.gt_u - (local.get $12) - (local.get $8) - ) - ) - ) - ) - (loop $while-in102 - (local.set $7 - (call $_fmt_u - (i32.load - (local.get $6) + (block $do-once99 + (if + (local.get $17) + (then + (block + (local.set $6 + (local.tee $12 + (select + (local.get $8) + (local.get $12) + (i32.gt_u + (local.get $12) + (local.get $8) + ) + ) ) - (i32.const 0) - (local.get $30) ) - ) - (block $do-once103 - (if - (i32.eq - (local.get $6) - (local.get $12) - ) - (block - (br_if $do-once103 - (i32.ne - (local.get $7) - (local.get $30) + (loop $while-in102 + (local.set $7 + (call $_fmt_u + (i32.load + (local.get $6) ) - ) - (i32.store8 - (local.get $35) - (i32.const 48) - ) - (local.set $7 - (local.get $35) + (i32.const 0) + (local.get $30) ) ) - (block - (br_if $do-once103 - (i32.le_u - (local.get $7) - (local.get $22) + (block $do-once103 + (if + (i32.eq + (local.get $6) + (local.get $12) ) - ) - (loop $while-in106 - (i32.store8 - (local.tee $7 - (i32.add - (local.get $7) - (i32.const -1) + (then + (block + (br_if $do-once103 + (i32.ne + (local.get $7) + (local.get $30) + ) + ) + (i32.store8 + (local.get $35) + (i32.const 48) + ) + (local.set $7 + (local.get $35) ) ) - (i32.const 48) ) - (br_if $while-in106 - (i32.gt_u - (local.get $7) - (local.get $22) + (else + (block + (br_if $do-once103 + (i32.le_u + (local.get $7) + (local.get $22) + ) + ) + (loop $while-in106 + (i32.store8 + (local.tee $7 + (i32.add + (local.get $7) + (i32.const -1) + ) + ) + (i32.const 48) + ) + (br_if $while-in106 + (i32.gt_u + (local.get $7) + (local.get $22) + ) + ) + ) ) ) ) ) - ) - ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $7) - (i32.sub - (local.get $43) - (local.get $7) - ) - (local.get $0) - ) - ) - ) - (if - (i32.le_u - (local.tee $7 - (i32.add - (local.get $6) - (i32.const 4) - ) - ) - (local.get $8) - ) - (block - (local.set $6 - (local.get $7) - ) - (br $while-in102) - ) - ) - ) - (block $do-once107 - (if - (local.get $32) - (block - (br_if $do-once107 - (i32.and - (i32.load - (local.get $0) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (local.get $0) ) - ) - ) - ) - ) - (if - (i32.and - (i32.gt_s - (local.get $5) - (i32.const 0) - ) - (i32.lt_u - (local.get $7) - (local.get $9) - ) - ) - (loop $while-in110 - (if - (i32.gt_u - (local.tee $6 - (call $_fmt_u - (i32.load + (then + (drop + (call $___fwritex (local.get $7) + (i32.sub + (local.get $43) + (local.get $7) + ) + (local.get $0) ) - (i32.const 0) - (local.get $30) ) ) - (local.get $22) ) - (loop $while-in112 - (i32.store8 - (local.tee $6 + (if + (i32.le_u + (local.tee $7 (i32.add (local.get $6) - (i32.const -1) + (i32.const 4) ) ) - (i32.const 48) + (local.get $8) ) - (br_if $while-in112 - (i32.gt_u - (local.get $6) - (local.get $22) + (then + (block + (local.set $6 + (local.get $7) + ) + (br $while-in102) ) ) ) ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $6) - (select - (i32.const 9) - (local.get $5) - (i32.gt_s - (local.get $5) - (i32.const 9) + (block $do-once107 + (if + (local.get $32) + (then + (block + (br_if $do-once107 + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (local.get $0) + ) ) ) - (local.get $0) ) ) ) - (local.set $6 - (i32.add - (local.get $5) - (i32.const -9) - ) - ) (if (i32.and (i32.gt_s (local.get $5) - (i32.const 9) + (i32.const 0) ) (i32.lt_u - (local.tee $7 - (i32.add - (local.get $7) - (i32.const 4) - ) - ) + (local.get $7) (local.get $9) ) ) - (block - (local.set $5 - (local.get $6) - ) - (br $while-in110) - ) - (local.set $5 - (local.get $6) - ) - ) - ) - ) - (call $_pad - (local.get $0) - (i32.const 48) - (i32.add - (local.get $5) - (i32.const 9) - ) - (i32.const 9) - (i32.const 0) - ) - ) - (block - (local.set $9 - (select - (local.get $9) - (i32.add - (local.get $12) - (i32.const 4) - ) - (local.get $24) - ) - ) - (if - (i32.gt_s - (local.get $5) - (i32.const -1) - ) - (block - (local.set $17 - (i32.eqz - (local.get $21) - ) - ) - (local.set $6 - (local.get $12) - ) - (local.set $7 - (local.get $5) - ) - (loop $while-in114 - (if - (i32.eq - (local.tee $5 - (call $_fmt_u - (i32.load - (local.get $6) - ) - (i32.const 0) - (local.get $30) - ) - ) - (local.get $30) - ) - (block - (i32.store8 - (local.get $35) - (i32.const 48) - ) - (local.set $5 - (local.get $35) - ) - ) - ) - (block $do-once115 - (if - (i32.eq - (local.get $6) - (local.get $12) - ) - (block - (if - (i32.eqz - (i32.and + (then + (loop $while-in110 + (if + (i32.gt_u + (local.tee $6 + (call $_fmt_u (i32.load - (local.get $0) + (local.get $7) ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $5) - (i32.const 1) - (local.get $0) + (i32.const 0) + (local.get $30) ) ) + (local.get $22) ) - (local.set $5 - (i32.add - (local.get $5) - (i32.const 1) - ) - ) - (br_if $do-once115 - (i32.and - (local.get $17) - (i32.lt_s - (local.get $7) - (i32.const 1) + (then + (loop $while-in112 + (i32.store8 + (local.tee $6 + (i32.add + (local.get $6) + (i32.const -1) + ) + ) + (i32.const 48) + ) + (br_if $while-in112 + (i32.gt_u + (local.get $6) + (local.get $22) + ) ) ) ) - (br_if $do-once115 + ) + (if + (i32.eqz (i32.and (i32.load (local.get $0) @@ -13041,256 +13549,444 @@ (i32.const 32) ) ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (local.get $0) + (then + (drop + (call $___fwritex + (local.get $6) + (select + (i32.const 9) + (local.get $5) + (i32.gt_s + (local.get $5) + (i32.const 9) + ) + ) + (local.get $0) + ) ) ) ) - (block - (br_if $do-once115 - (i32.le_u + (local.set $6 + (i32.add + (local.get $5) + (i32.const -9) + ) + ) + (if + (i32.and + (i32.gt_s (local.get $5) - (local.get $22) + (i32.const 9) ) - ) - (loop $while-in118 - (i32.store8 - (local.tee $5 + (i32.lt_u + (local.tee $7 (i32.add - (local.get $5) - (i32.const -1) + (local.get $7) + (i32.const 4) ) ) - (i32.const 48) + (local.get $9) ) - (br_if $while-in118 - (i32.gt_u - (local.get $5) - (local.get $22) + ) + (then + (block + (local.set $5 + (local.get $6) ) + (br $while-in110) + ) + ) + (else + (local.set $5 + (local.get $6) ) ) ) ) ) - (local.set $8 - (i32.sub - (local.get $43) - (local.get $5) + ) + (call $_pad + (local.get $0) + (i32.const 48) + (i32.add + (local.get $5) + (i32.const 9) + ) + (i32.const 9) + (i32.const 0) + ) + ) + ) + (else + (block + (local.set $9 + (select + (local.get $9) + (i32.add + (local.get $12) + (i32.const 4) ) + (local.get $24) ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) + ) + (if + (i32.gt_s + (local.get $5) + (i32.const -1) + ) + (then + (block + (local.set $17 + (i32.eqz + (local.get $21) ) - (i32.const 32) ) - ) - (drop - (call $___fwritex + (local.set $6 + (local.get $12) + ) + (local.set $7 (local.get $5) - (select - (local.get $8) - (local.get $7) - (i32.gt_s - (local.get $7) - (local.get $8) + ) + (loop $while-in114 + (if + (i32.eq + (local.tee $5 + (call $_fmt_u + (i32.load + (local.get $6) + ) + (i32.const 0) + (local.get $30) + ) + ) + (local.get $30) + ) + (then + (block + (i32.store8 + (local.get $35) + (i32.const 48) + ) + (local.set $5 + (local.get $35) + ) + ) ) ) - (local.get $0) - ) - ) - ) - (br_if $while-in114 - (i32.and - (i32.lt_u - (local.tee $6 - (i32.add - (local.get $6) - (i32.const 4) + (block $do-once115 + (if + (i32.eq + (local.get $6) + (local.get $12) + ) + (then + (block + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $5) + (i32.const 1) + (local.get $0) + ) + ) + ) + ) + (local.set $5 + (i32.add + (local.get $5) + (i32.const 1) + ) + ) + (br_if $do-once115 + (i32.and + (local.get $17) + (i32.lt_s + (local.get $7) + (i32.const 1) + ) + ) + ) + (br_if $do-once115 + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (local.get $0) + ) + ) + ) + ) + (else + (block + (br_if $do-once115 + (i32.le_u + (local.get $5) + (local.get $22) + ) + ) + (loop $while-in118 + (i32.store8 + (local.tee $5 + (i32.add + (local.get $5) + (i32.const -1) + ) + ) + (i32.const 48) + ) + (br_if $while-in118 + (i32.gt_u + (local.get $5) + (local.get $22) + ) + ) + ) + ) + ) ) ) - (local.get $9) - ) - (i32.gt_s - (local.tee $7 + (local.set $8 (i32.sub - (local.get $7) - (local.get $8) + (local.get $43) + (local.get $5) ) ) - (i32.const -1) - ) - ) - ) - (local.set $5 - (local.get $7) - ) - ) - ) - ) - (call $_pad - (local.get $0) - (i32.const 48) - (i32.add - (local.get $5) - (i32.const 18) - ) - (i32.const 18) - (i32.const 0) - ) - (br_if $do-once99 - (i32.and - (i32.load - (local.get $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (local.get $18) - (i32.sub - (local.get $28) - (local.get $18) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $5) + (select + (local.get $8) + (local.get $7) + (i32.gt_s + (local.get $7) + (local.get $8) + ) + ) + (local.get $0) + ) + ) + ) + ) + (br_if $while-in114 + (i32.and + (i32.lt_u + (local.tee $6 + (i32.add + (local.get $6) + (i32.const 4) + ) + ) + (local.get $9) + ) + (i32.gt_s + (local.tee $7 + (i32.sub + (local.get $7) + (local.get $8) + ) + ) + (i32.const -1) + ) + ) + ) + (local.set $5 + (local.get $7) + ) + ) + ) + ) + ) + (call $_pad + (local.get $0) + (i32.const 48) + (i32.add + (local.get $5) + (i32.const 18) + ) + (i32.const 18) + (i32.const 0) + ) + (br_if $do-once99 + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (drop + (call $___fwritex + (local.get $18) + (i32.sub + (local.get $28) + (local.get $18) + ) + (local.get $0) + ) ) - (local.get $0) ) ) ) ) - ) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (local.get $13) - (i32.xor - (local.get $11) - (i32.const 8192) - ) - ) - (select - (local.get $14) - (local.get $13) - (i32.lt_s + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) (local.get $13) + (i32.xor + (local.get $11) + (i32.const 8192) + ) + ) + (select (local.get $14) + (local.get $13) + (i32.lt_s + (local.get $13) + (local.get $14) + ) ) ) ) - (block (result i32) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (local.tee $7 - (i32.add - (local.tee $9 - (select - (i32.const 0) - (local.get $27) - (local.tee $6 - (i32.or - (f64.ne - (local.get $15) - (local.get $15) + (else + (block (result i32) + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) + (local.tee $7 + (i32.add + (local.tee $9 + (select + (i32.const 0) + (local.get $27) + (local.tee $6 + (i32.or + (f64.ne + (local.get $15) + (local.get $15) + ) + (i32.const 0) ) - (i32.const 0) ) ) ) + (i32.const 3) ) - (i32.const 3) ) + (local.get $8) ) - (local.get $8) - ) - (if - (i32.eqz - (i32.and - (local.tee $5 - (i32.load - (local.get $0) + (if + (i32.eqz + (i32.and + (local.tee $5 + (i32.load + (local.get $0) + ) ) - ) - (i32.const 32) - ) - ) - (block - (drop - (call $___fwritex - (local.get $31) - (local.get $9) - (local.get $0) + (i32.const 32) ) ) - (local.set $5 - (i32.load - (local.get $0) + (then + (block + (drop + (call $___fwritex + (local.get $31) + (local.get $9) + (local.get $0) + ) + ) + (local.set $5 + (i32.load + (local.get $0) + ) + ) ) ) ) - ) - (local.set $6 - (select + (local.set $6 (select - (i32.const 4135) - (i32.const 4139) - (local.tee $8 - (i32.ne - (i32.and - (local.get $18) - (i32.const 32) + (select + (i32.const 4135) + (i32.const 4139) + (local.tee $8 + (i32.ne + (i32.and + (local.get $18) + (i32.const 32) + ) + (i32.const 0) ) - (i32.const 0) ) ) + (select + (i32.const 4127) + (i32.const 4131) + (local.get $8) + ) + (local.get $6) ) - (select - (i32.const 4127) - (i32.const 4131) - (local.get $8) - ) - (local.get $6) ) - ) - (if - (i32.eqz - (i32.and - (local.get $5) - (i32.const 32) + (if + (i32.eqz + (i32.and + (local.get $5) + (i32.const 32) + ) ) - ) - (drop - (call $___fwritex - (local.get $6) - (i32.const 3) - (local.get $0) + (then + (drop + (call $___fwritex + (local.get $6) + (i32.const 3) + (local.get $0) + ) + ) ) ) - ) - (call $_pad - (local.get $0) - (i32.const 32) - (local.get $14) - (local.get $7) - (i32.xor - (local.get $11) - (i32.const 8192) - ) - ) - (select - (local.get $14) - (local.get $7) - (i32.lt_s + (call $_pad + (local.get $0) + (i32.const 32) + (local.get $14) (local.get $7) + (i32.xor + (local.get $11) + (i32.const 8192) + ) + ) + (select (local.get $14) + (local.get $7) + (i32.lt_s + (local.get $7) + (local.get $14) + ) ) ) ) @@ -13346,115 +14042,123 @@ ) ) ) - (block - (local.set $5 - (local.get $26) - ) - (local.set $8 - (i32.const 0) - ) - (local.set $9 - (i32.const 4091) + (then + (block + (local.set $5 + (local.get $26) + ) + (local.set $8 + (i32.const 0) + ) + (local.set $9 + (i32.const 4091) + ) + (br $__rjti$8) ) - (br $__rjti$8) ) - (block - (local.set $5 - (local.get $8) - ) - (local.set $8 - (local.get $26) - ) - (loop $while-in123 - (i32.store8 - (local.tee $8 - (i32.add - (local.get $8) - (i32.const -1) - ) - ) - (i32.or - (i32.load8_u + (else + (block + (local.set $5 + (local.get $8) + ) + (local.set $8 + (local.get $26) + ) + (loop $while-in123 + (i32.store8 + (local.tee $8 (i32.add - (i32.and - (local.get $5) - (i32.const 15) - ) - (i32.const 4075) + (local.get $8) + (i32.const -1) ) ) - (local.get $9) - ) - ) - (br_if $while-in123 - (i32.eqz - (i32.and - (i32.eqz - (local.tee $5 - (call $_bitshift64Lshr + (i32.or + (i32.load8_u + (i32.add + (i32.and (local.get $5) - (local.get $11) - (i32.const 4) + (i32.const 15) ) + (i32.const 4075) ) ) - (i32.eqz - (local.tee $11 - (global.get $tempRet0) - ) - ) + (local.get $9) ) ) - ) - (local.set $5 - (local.get $8) - ) - ) - (local.set $8 - (if (result i32) - (i32.or + (br_if $while-in123 (i32.eqz (i32.and - (local.get $7) - (i32.const 8) - ) - ) - (i32.and - (i32.eqz - (i32.load + (i32.eqz + (local.tee $5 + (call $_bitshift64Lshr + (local.get $5) + (local.get $11) + (i32.const 4) + ) + ) + ) + (i32.eqz (local.tee $11 - (local.get $19) + (global.get $tempRet0) ) ) ) + ) + ) + (local.set $5 + (local.get $8) + ) + ) + (local.set $8 + (if (result i32) + (i32.or (i32.eqz - (i32.load offset=4 - (local.get $11) + (i32.and + (local.get $7) + (i32.const 8) + ) + ) + (i32.and + (i32.eqz + (i32.load + (local.tee $11 + (local.get $19) + ) + ) + ) + (i32.eqz + (i32.load offset=4 + (local.get $11) + ) ) ) ) - ) - (block (result i32) - (local.set $9 - (i32.const 4091) + (then + (block (result i32) + (local.set $9 + (i32.const 4091) + ) + (i32.const 0) + ) ) - (i32.const 0) - ) - (block (result i32) - (local.set $9 - (i32.add - (i32.shr_s - (local.get $18) - (i32.const 4) + (else + (block (result i32) + (local.set $9 + (i32.add + (i32.shr_s + (local.get $18) + (i32.const 4) + ) + (i32.const 4091) + ) ) - (i32.const 4091) + (i32.const 2) ) ) - (i32.const 2) ) ) + (br $__rjti$8) ) - (br $__rjti$8) ) ) ) @@ -13580,11 +14284,13 @@ (local.get $7) (i32.const 0) ) - (block - (local.set $16 - (i32.const -1) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L1) ) - (br $label$break$L1) ) ) (call $_pad @@ -13596,89 +14302,99 @@ ) (if (local.get $5) - (block - (local.set $6 - (i32.const 0) - ) - (local.set $7 - (i32.load - (local.get $19) + (then + (block + (local.set $6 + (i32.const 0) ) - ) - (loop $while-in127 - (if - (i32.eqz - (local.tee $8 - (i32.load - (local.get $7) + (local.set $7 + (i32.load + (local.get $19) + ) + ) + (loop $while-in127 + (if + (i32.eqz + (local.tee $8 + (i32.load + (local.get $7) + ) ) ) - ) - (block - (local.set $7 - (local.get $5) + (then + (block + (local.set $7 + (local.get $5) + ) + (br $__rjti$7) + ) ) - (br $__rjti$7) ) - ) - (if - (i32.gt_s - (local.tee $6 - (i32.add - (local.tee $8 - (call $_wctomb - (local.get $36) - (local.get $8) + (if + (i32.gt_s + (local.tee $6 + (i32.add + (local.tee $8 + (call $_wctomb + (local.get $36) + (local.get $8) + ) ) + (local.get $6) ) - (local.get $6) ) - ) - (local.get $5) - ) - (block - (local.set $7 (local.get $5) ) - (br $__rjti$7) + (then + (block + (local.set $7 + (local.get $5) + ) + (br $__rjti$7) + ) + ) ) - ) - (if - (i32.eqz - (i32.and - (i32.load - (local.get $0) + (if + (i32.eqz + (i32.and + (i32.load + (local.get $0) + ) + (i32.const 32) + ) + ) + (then + (drop + (call $___fwritex + (local.get $36) + (local.get $8) + (local.get $0) + ) ) - (i32.const 32) ) ) - (drop - (call $___fwritex - (local.get $36) - (local.get $8) - (local.get $0) + (local.set $7 + (i32.add + (local.get $7) + (i32.const 4) ) ) - ) - (local.set $7 - (i32.add - (local.get $7) - (i32.const 4) + (br_if $while-in127 + (i32.lt_u + (local.get $6) + (local.get $5) + ) ) - ) - (br_if $while-in127 - (i32.lt_u - (local.get $6) + (local.set $7 (local.get $5) ) ) - (local.set $7 - (local.get $5) - ) ) ) - (local.set $7 - (i32.const 0) + (else + (local.set $7 + (i32.const 0) + ) ) ) ) @@ -13743,38 +14459,42 @@ ) ) ) - (block (result i32) - (local.set $7 - (local.get $5) - ) - (select - (local.get $6) - (local.tee $5 - (i32.add - (i32.xor - (i32.and - (local.get $12) + (then + (block (result i32) + (local.set $7 + (local.get $5) + ) + (select + (local.get $6) + (local.tee $5 + (i32.add + (i32.xor + (i32.and + (local.get $12) + (i32.const 1) + ) (i32.const 1) ) - (i32.const 1) - ) - (i32.sub - (local.get $39) - (local.get $5) + (i32.sub + (local.get $39) + (local.get $5) + ) ) ) - ) - (i32.gt_s - (local.get $6) - (local.get $5) + (i32.gt_s + (local.get $6) + (local.get $5) + ) ) ) ) - (block (result i32) - (local.set $7 - (local.get $26) + (else + (block (result i32) + (local.set $7 + (local.get $26) + ) + (i32.const 0) ) - (i32.const 0) ) ) ) @@ -13825,11 +14545,13 @@ (i32.const 32) ) ) - (drop - (call $___fwritex - (local.get $9) - (local.get $8) - (local.get $0) + (then + (drop + (call $___fwritex + (local.get $9) + (local.get $8) + (local.get $0) + ) ) ) ) @@ -13859,11 +14581,13 @@ (i32.const 32) ) ) - (drop - (call $___fwritex - (local.get $7) - (local.get $13) - (local.get $0) + (then + (drop + (call $___fwritex + (local.get $7) + (local.get $13) + (local.get $0) + ) ) ) ) @@ -13892,101 +14616,115 @@ (i32.eqz (local.get $0) ) - (if - (local.get $1) - (block - (local.set $0 - (i32.const 1) - ) - (loop $while-in130 - (if - (local.tee $1 - (i32.load - (i32.add - (local.get $4) - (i32.shl - (local.get $0) - (i32.const 2) - ) - ) - ) + (then + (if + (local.get $1) + (then + (block + (local.set $0 + (i32.const 1) ) - (block - (call $_pop_arg_336 - (i32.add - (local.get $3) - (i32.shl - (local.get $0) - (i32.const 3) + (loop $while-in130 + (if + (local.tee $1 + (i32.load + (i32.add + (local.get $4) + (i32.shl + (local.get $0) + (i32.const 2) + ) + ) ) ) - (local.get $1) - (local.get $2) - ) - (br_if $while-in130 - (i32.lt_s - (local.tee $0 - (i32.add - (local.get $0) + (then + (block + (call $_pop_arg_336 + (i32.add + (local.get $3) + (i32.shl + (local.get $0) + (i32.const 3) + ) + ) + (local.get $1) + (local.get $2) + ) + (br_if $while-in130 + (i32.lt_s + (local.tee $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (i32.const 10) + ) + ) + (local.set $16 (i32.const 1) ) + (br $label$break$L343) ) - (i32.const 10) ) ) - (local.set $16 - (i32.const 1) - ) - (br $label$break$L343) ) - ) - ) - (if - (i32.lt_s - (local.get $0) - (i32.const 10) - ) - (loop $while-in132 (if - (i32.load - (i32.add - (local.get $4) - (i32.shl - (local.get $0) - (i32.const 2) + (i32.lt_s + (local.get $0) + (i32.const 10) + ) + (then + (loop $while-in132 + (if + (i32.load + (i32.add + (local.get $4) + (i32.shl + (local.get $0) + (i32.const 2) + ) + ) + ) + (then + (block + (local.set $16 + (i32.const -1) + ) + (br $label$break$L343) + ) + ) + ) + (br_if $while-in132 + (i32.lt_s + (local.tee $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (i32.const 10) + ) + ) + (local.set $16 + (i32.const 1) ) ) ) - (block + (else (local.set $16 - (i32.const -1) - ) - (br $label$break$L343) - ) - ) - (br_if $while-in132 - (i32.lt_s - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 1) - ) + (i32.const 1) ) - (i32.const 10) ) ) - (local.set $16 - (i32.const 1) - ) ) + ) + (else (local.set $16 - (i32.const 1) + (i32.const 0) ) ) ) - (local.set $16 - (i32.const 0) - ) ) ) ) @@ -14005,27 +14743,56 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 20) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $switch-default - ;; CHECK-NEXT: (block $switch-case9 - ;; CHECK-NEXT: (block $switch-case8 - ;; CHECK-NEXT: (block $switch-case7 - ;; CHECK-NEXT: (block $switch-case6 - ;; CHECK-NEXT: (block $switch-case5 - ;; CHECK-NEXT: (block $switch-case4 - ;; CHECK-NEXT: (block $switch-case3 - ;; CHECK-NEXT: (block $switch-case2 - ;; CHECK-NEXT: (block $switch-case1 - ;; CHECK-NEXT: (block $switch-case - ;; CHECK-NEXT: (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default - ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $switch-default + ;; CHECK-NEXT: (block $switch-case9 + ;; CHECK-NEXT: (block $switch-case8 + ;; CHECK-NEXT: (block $switch-case7 + ;; CHECK-NEXT: (block $switch-case6 + ;; CHECK-NEXT: (block $switch-case5 + ;; CHECK-NEXT: (block $switch-case4 + ;; CHECK-NEXT: (block $switch-case3 + ;; CHECK-NEXT: (block $switch-case2 + ;; CHECK-NEXT: (block $switch-case1 + ;; CHECK-NEXT: (block $switch-case + ;; CHECK-NEXT: (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (local.tee $3 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.load @@ -14041,19 +14808,32 @@ ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.load @@ -14069,97 +14849,108 @@ ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) @@ -14187,31 +14978,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 65535) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 65535) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) @@ -14239,14 +15013,31 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) @@ -14274,45 +15065,28 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 255) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 24) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 24) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 255) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.shr_s - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.lt_s - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.load ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14321,19 +15095,12 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (f64.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L1) ;; CHECK-NEXT: ) @@ -14363,33 +15130,6 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (f64.load - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14405,27 +15145,56 @@ (local.get $1) (i32.const 20) ) - (block $switch-default - (block $switch-case9 - (block $switch-case8 - (block $switch-case7 - (block $switch-case6 - (block $switch-case5 - (block $switch-case4 - (block $switch-case3 - (block $switch-case2 - (block $switch-case1 - (block $switch-case - (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default - (i32.sub + (then + (block $switch-default + (block $switch-case9 + (block $switch-case8 + (block $switch-case7 + (block $switch-case6 + (block $switch-case5 + (block $switch-case4 + (block $switch-case3 + (block $switch-case2 + (block $switch-case1 + (block $switch-case + (br_table $switch-case $switch-case1 $switch-case2 $switch-case3 $switch-case4 $switch-case5 $switch-case6 $switch-case7 $switch-case8 $switch-case9 $switch-default + (i32.sub + (local.get $1) + (i32.const 9) + ) + ) + ) + (local.set $3 + (i32.load + (local.tee $1 + (i32.and + (i32.add + (i32.load + (local.get $2) + ) + (i32.const 3) + ) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (local.get $2) + (i32.add (local.get $1) - (i32.const 9) + (i32.const 4) ) ) + (i32.store + (local.get $0) + (local.get $3) + ) + (br $label$break$L1) ) - (local.set $3 + (local.set $1 (i32.load - (local.tee $1 + (local.tee $3 (i32.and (i32.add (i32.load @@ -14441,19 +15210,32 @@ (i32.store (local.get $2) (i32.add - (local.get $1) + (local.get $3) (i32.const 4) ) ) (i32.store (local.get $0) - (local.get $3) + (local.get $1) + ) + (i32.store offset=4 + (local.get $0) + (i32.shr_s + (i32.shl + (i32.lt_s + (local.get $1) + (i32.const 0) + ) + (i32.const 31) + ) + (i32.const 31) + ) ) (br $label$break$L1) ) - (local.set $1 + (local.set $3 (i32.load - (local.tee $3 + (local.tee $1 (i32.and (i32.add (i32.load @@ -14469,97 +15251,108 @@ (i32.store (local.get $2) (i32.add - (local.get $3) + (local.get $1) (i32.const 4) ) ) (i32.store (local.get $0) - (local.get $1) + (local.get $3) ) (i32.store offset=4 (local.get $0) - (i32.shr_s - (i32.shl - (i32.lt_s - (local.get $1) - (i32.const 0) - ) - (i32.const 31) - ) - (i32.const 31) - ) + (i32.const 0) ) (br $label$break$L1) ) - (local.set $3 + (local.set $5 (i32.load - (local.tee $1 - (i32.and - (i32.add - (i32.load - (local.get $2) + (local.tee $3 + (local.tee $1 + (i32.and + (i32.add + (i32.load + (local.get $2) + ) + (i32.const 7) ) - (i32.const 3) + (i32.const -8) ) - (i32.const -4) ) ) ) ) + (local.set $3 + (i32.load offset=4 + (local.get $3) + ) + ) (i32.store (local.get $2) (i32.add (local.get $1) - (i32.const 4) + (i32.const 8) ) ) (i32.store (local.get $0) - (local.get $3) + (local.get $5) ) (i32.store offset=4 (local.get $0) - (i32.const 0) + (local.get $3) ) (br $label$break$L1) ) - (local.set $5 + (local.set $3 (i32.load - (local.tee $3 - (local.tee $1 - (i32.and - (i32.add - (i32.load - (local.get $2) - ) - (i32.const 7) + (local.tee $1 + (i32.and + (i32.add + (i32.load + (local.get $2) ) - (i32.const -8) + (i32.const 3) ) + (i32.const -4) ) ) ) ) - (local.set $3 - (i32.load offset=4 - (local.get $3) - ) - ) (i32.store (local.get $2) (i32.add (local.get $1) - (i32.const 8) + (i32.const 4) ) ) (i32.store (local.get $0) - (local.get $5) + (local.tee $1 + (i32.shr_s + (i32.shl + (i32.and + (local.get $3) + (i32.const 65535) + ) + (i32.const 16) + ) + (i32.const 16) + ) + ) ) (i32.store offset=4 (local.get $0) - (local.get $3) + (i32.shr_s + (i32.shl + (i32.lt_s + (local.get $1) + (i32.const 0) + ) + (i32.const 31) + ) + (i32.const 31) + ) ) (br $label$break$L1) ) @@ -14587,31 +15380,14 @@ ) (i32.store (local.get $0) - (local.tee $1 - (i32.shr_s - (i32.shl - (i32.and - (local.get $3) - (i32.const 65535) - ) - (i32.const 16) - ) - (i32.const 16) - ) + (i32.and + (local.get $3) + (i32.const 65535) ) ) (i32.store offset=4 (local.get $0) - (i32.shr_s - (i32.shl - (i32.lt_s - (local.get $1) - (i32.const 0) - ) - (i32.const 31) - ) - (i32.const 31) - ) + (i32.const 0) ) (br $label$break$L1) ) @@ -14639,14 +15415,31 @@ ) (i32.store (local.get $0) - (i32.and - (local.get $3) - (i32.const 65535) + (local.tee $1 + (i32.shr_s + (i32.shl + (i32.and + (local.get $3) + (i32.const 255) + ) + (i32.const 24) + ) + (i32.const 24) + ) ) ) (i32.store offset=4 (local.get $0) - (i32.const 0) + (i32.shr_s + (i32.shl + (i32.lt_s + (local.get $1) + (i32.const 0) + ) + (i32.const 31) + ) + (i32.const 31) + ) ) (br $label$break$L1) ) @@ -14674,45 +15467,28 @@ ) (i32.store (local.get $0) - (local.tee $1 - (i32.shr_s - (i32.shl - (i32.and - (local.get $3) - (i32.const 255) - ) - (i32.const 24) - ) - (i32.const 24) - ) + (i32.and + (local.get $3) + (i32.const 255) ) ) (i32.store offset=4 (local.get $0) - (i32.shr_s - (i32.shl - (i32.lt_s - (local.get $1) - (i32.const 0) - ) - (i32.const 31) - ) - (i32.const 31) - ) + (i32.const 0) ) (br $label$break$L1) ) - (local.set $3 - (i32.load + (local.set $4 + (f64.load (local.tee $1 (i32.and (i32.add (i32.load (local.get $2) ) - (i32.const 3) + (i32.const 7) ) - (i32.const -4) + (i32.const -8) ) ) ) @@ -14721,19 +15497,12 @@ (local.get $2) (i32.add (local.get $1) - (i32.const 4) - ) - ) - (i32.store - (local.get $0) - (i32.and - (local.get $3) - (i32.const 255) + (i32.const 8) ) ) - (i32.store offset=4 + (f64.store (local.get $0) - (i32.const 0) + (local.get $4) ) (br $label$break$L1) ) @@ -14763,33 +15532,6 @@ (local.get $0) (local.get $4) ) - (br $label$break$L1) - ) - (local.set $4 - (f64.load - (local.tee $1 - (i32.and - (i32.add - (i32.load - (local.get $2) - ) - (i32.const 7) - ) - (i32.const -8) - ) - ) - ) - ) - (i32.store - (local.get $2) - (i32.add - (local.get $1) - (i32.const 8) - ) - ) - (f64.store - (local.get $0) - (local.get $4) ) ) ) @@ -14798,81 +15540,85 @@ ;; CHECK: (func $_fmt_u (param $0 i32) (param $1 i32) (param $2 i32) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (loop $while-in - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $___uremdi3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (call $___uremdi3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (call $___udivmoddi4 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (call $___udivmoddi4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (global.get $tempRet0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (global.get $tempRet0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (loop $while-in1 - ;; CHECK-NEXT: (i32.store8 - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $while-in1 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 48) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.div_u ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 48) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.div_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14898,103 +15644,113 @@ ) ) ) - (loop $while-in - (i32.store8 - (local.tee $2 - (i32.add - (local.get $2) - (i32.const -1) + (then + (loop $while-in + (i32.store8 + (local.tee $2 + (i32.add + (local.get $2) + (i32.const -1) + ) ) - ) - (i32.or - (local.tee $3 - (call $___uremdi3 - (local.get $0) - (local.get $1) - (i32.const 10) - (i32.const 0) + (i32.or + (local.tee $3 + (call $___uremdi3 + (local.get $0) + (local.get $1) + (i32.const 10) + (i32.const 0) + ) ) + (i32.const 48) ) - (i32.const 48) - ) - ) - (local.set $3 - (call $___udivdi3 - (local.get $0) - (local.get $1) - (i32.const 10) - (i32.const 0) ) - ) - (local.set $4 - (global.get $tempRet0) - ) - (if - (i32.or - (i32.gt_u + (local.set $3 + (call $___udivdi3 + (local.get $0) (local.get $1) - (i32.const 9) + (i32.const 10) + (i32.const 0) ) - (i32.and - (i32.eq + ) + (local.set $4 + (global.get $tempRet0) + ) + (if + (i32.or + (i32.gt_u (local.get $1) (i32.const 9) ) - (i32.gt_u - (local.get $0) - (i32.const -1) + (i32.and + (i32.eq + (local.get $1) + (i32.const 9) + ) + (i32.gt_u + (local.get $0) + (i32.const -1) + ) ) ) - ) - (block - (local.set $0 - (local.get $3) + (then + (block + (local.set $0 + (local.get $3) + ) + (local.set $1 + (local.get $4) + ) + (br $while-in) + ) ) - (local.set $1 - (local.get $4) + (else + (local.set $0 + (local.get $3) + ) ) - (br $while-in) - ) - (local.set $0 - (local.get $3) ) ) ) ) (if (local.get $0) - (loop $while-in1 - (i32.store8 - (local.tee $2 - (i32.add - (local.get $2) - (i32.const -1) + (then + (loop $while-in1 + (i32.store8 + (local.tee $2 + (i32.add + (local.get $2) + (i32.const -1) + ) + ) + (i32.or + (call $i32u-rem + (local.get $0) + (i32.const 10) + ) + (i32.const 48) ) ) - (i32.or - (call $i32u-rem + (local.set $1 + (call $i32u-div (local.get $0) (i32.const 10) ) - (i32.const 48) - ) - ) - (local.set $1 - (call $i32u-div - (local.get $0) - (i32.const 10) - ) - ) - (if - (i32.ge_u - (local.get $0) - (i32.const 10) ) - (block - (local.set $0 - (local.get $1) + (if + (i32.ge_u + (local.get $0) + (i32.const 10) + ) + (then + (block + (local.set $0 + (local.get $1) + ) + (br $while-in1) + ) ) - (br $while-in1) ) ) ) @@ -15019,7 +15775,9 @@ ;; CHECK-NEXT: (global.get $STACKTOP) ;; CHECK-NEXT: (global.get $STACK_MAX) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (local.get $7) @@ -15038,7 +15796,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $_memset ;; CHECK-NEXT: (local.get $6) @@ -15075,11 +15833,11 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.const 255) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (loop $while-in ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $___fwritex ;; CHECK-NEXT: (local.get $6) @@ -15129,9 +15887,11 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br_if $do-once + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15167,7 +15927,9 @@ (global.get $STACKTOP) (global.get $STACK_MAX) ) - (call $abort) + (then + (call $abort) + ) ) (local.set $6 (local.get $7) @@ -15186,110 +15948,118 @@ ) ) ) - (block - (drop - (call $_memset - (local.get $6) - (local.get $1) - (select - (i32.const 256) - (local.tee $5 - (i32.sub - (local.get $2) - (local.get $3) - ) - ) - (i32.gt_u - (local.get $5) + (then + (block + (drop + (call $_memset + (local.get $6) + (local.get $1) + (select (i32.const 256) + (local.tee $5 + (i32.sub + (local.get $2) + (local.get $3) + ) + ) + (i32.gt_u + (local.get $5) + (i32.const 256) + ) ) ) ) - ) - (local.set $4 - (i32.eqz - (i32.and - (local.tee $1 - (i32.load - (local.get $0) + (local.set $4 + (i32.eqz + (i32.and + (local.tee $1 + (i32.load + (local.get $0) + ) ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (if - (i32.gt_u - (local.get $5) - (i32.const 255) - ) - (block - (loop $while-in - (if - (local.get $4) - (block - (drop - (call $___fwritex - (local.get $6) - (i32.const 256) - (local.get $0) + (if + (i32.gt_u + (local.get $5) + (i32.const 255) + ) + (then + (block + (loop $while-in + (if + (local.get $4) + (then + (block + (drop + (call $___fwritex + (local.get $6) + (i32.const 256) + (local.get $0) + ) + ) + (local.set $1 + (i32.load + (local.get $0) + ) + ) + ) ) ) - (local.set $1 - (i32.load - (local.get $0) + (local.set $4 + (i32.eqz + (i32.and + (local.get $1) + (i32.const 32) + ) + ) + ) + (br_if $while-in + (i32.gt_u + (local.tee $5 + (i32.add + (local.get $5) + (i32.const -256) + ) + ) + (i32.const 255) ) ) ) - ) - (local.set $4 - (i32.eqz - (i32.and - (local.get $1) - (i32.const 32) + (br_if $do-once + (i32.eqz + (local.get $4) ) ) - ) - (br_if $while-in - (i32.gt_u - (local.tee $5 - (i32.add - (local.get $5) - (i32.const -256) + (local.set $5 + (i32.and + (i32.sub + (local.get $2) + (local.get $3) ) + (i32.const 255) ) - (i32.const 255) ) ) ) - (br_if $do-once - (i32.eqz - (local.get $4) - ) - ) - (local.set $5 - (i32.and - (i32.sub - (local.get $2) - (local.get $3) + (else + (br_if $do-once + (i32.eqz + (local.get $4) ) - (i32.const 255) ) ) ) - (br_if $do-once - (i32.eqz - (local.get $4) + (drop + (call $___fwritex + (local.get $6) + (local.get $5) + (local.get $0) ) ) ) - (drop - (call $___fwritex - (local.get $6) - (local.get $5) - (local.get $0) - ) - ) ) ) ) @@ -15323,7 +16093,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 245) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.tee $5 @@ -15358,7 +16128,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.tee $1 @@ -15402,20 +16172,22 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 176) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 176) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $10) @@ -15423,7 +16195,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -15437,7 +16211,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $2) @@ -15447,7 +16221,9 @@ ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15494,10 +16270,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.shr_u @@ -15641,7 +16417,7 @@ ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.and @@ -15659,7 +16435,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $9) @@ -15667,7 +16443,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -15681,7 +16459,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $10) @@ -15696,7 +16474,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15736,7 +16516,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $12 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 196) @@ -15770,33 +16550,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.or @@ -15852,7 +16636,7 @@ ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.shr_u @@ -15977,23 +16761,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load offset=20 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load offset=20 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $10 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $10 @@ -16041,7 +16827,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ge_u @@ -16053,7 +16841,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (i32.load offset=24 @@ -16070,7 +16860,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.tee $1 @@ -16084,24 +16874,26 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16117,7 +16909,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -16138,7 +16930,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -16154,8 +16946,10 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) @@ -16166,7 +16960,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.tee $7 @@ -16176,7 +16970,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -16190,7 +16986,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -16204,7 +17002,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -16217,7 +17015,9 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16225,7 +17025,7 @@ ;; CHECK-NEXT: (block $do-once8 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $5) @@ -16245,7 +17045,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $9) @@ -16254,7 +17054,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.and @@ -16274,7 +17074,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $8) @@ -16282,7 +17082,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -16296,13 +17098,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $do-once8 @@ -16321,7 +17127,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=24 ;; CHECK-NEXT: (local.get $9) @@ -16333,20 +17141,24 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=16 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16357,22 +17169,26 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16385,7 +17201,7 @@ ;; CHECK-NEXT: (local.get $10) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.or @@ -16416,7 +17232,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.or @@ -16444,7 +17260,7 @@ ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 196) @@ -16478,33 +17294,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.or @@ -16558,252 +17378,270 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const -65) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $18 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 8) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $18 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $14 ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 16777215) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.gt_u ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 14) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: (i32.const 16777215) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 520192) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 520192) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 245760) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 245760) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 15) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $__rjto$3 - ;; CHECK-NEXT: (block $__rjti$3 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load offset=480 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (block $__rjto$3 + ;; CHECK-NEXT: (block $__rjti$3 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load offset=480 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 25) - ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $14) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in14 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.tee $9 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in14 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.tee $9 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjti$3) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__rjti$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.load offset=20 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.load offset=20 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.tee $9 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.tee $9 + ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16811,134 +17649,148 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in14) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in14) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $18) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $18) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.get $14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 12) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.load offset=480 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.load offset=480 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.shr_u ;; CHECK-NEXT: (local.tee $4 ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.and @@ -16949,9 +17801,9 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -16966,887 +17818,814 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__rjti$3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjti$3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__rjto$3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjto$3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in16 - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (loop $while-in16 + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.load offset=16 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.load offset=16 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-in16 - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.load offset=20 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (br_if $while-in16 + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.load offset=20 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 184) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.tee $12 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.tee $6 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.load offset=24 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once17 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load offset=12 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.tee $12 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once17) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (loop $while-in20 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in20) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.tee $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $10 - ;; CHECK-NEXT: (i32.load offset=8 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.load offset=24 + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $do-once17 ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load offset=12 + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $10) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $11 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once21 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load offset=28 - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 480) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once17) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 180) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: (loop $while-in20 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once21) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.tee $10 + ;; CHECK-NEXT: (i32.load offset=8 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $do-once21 - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $do-once21 ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load offset=16 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=16 - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load offset=20 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $do-once25 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load offset=28 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 480) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 256) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 216) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 176) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once21) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $do-once21 + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load offset=16 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 176) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load offset=20 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $do-once25 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $13) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=12 - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=8 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=12 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once25) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 216) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 176) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 176) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 16777215) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $13) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=8 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (local.tee $0 ;; CHECK-NEXT: (i32.shr_u ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 14) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 16777215) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.const 520192) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 520192) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 245760) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 245760) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (i32.const 15) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 480) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 480) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=28 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.store offset=28 ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 180) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 180) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=12 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=8 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once25) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 25) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $__rjto$1 - ;; CHECK-NEXT: (block $__rjti$1 - ;; CHECK-NEXT: (loop $while-in28 - ;; CHECK-NEXT: (br_if $__rjti$1 - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $7 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 16) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 180) + ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-in28) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=24 ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=12 ;; CHECK-NEXT: (local.get $6) @@ -17859,79 +18638,194 @@ ;; CHECK-NEXT: (br $do-once25) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjto$1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 8) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 31) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=12 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=8 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=12 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $__rjto$1 + ;; CHECK-NEXT: (block $__rjti$1 + ;; CHECK-NEXT: (loop $while-in28 + ;; CHECK-NEXT: (br_if $__rjti$1 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in28) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=8 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__rjto$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=8 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=12 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -17946,7 +18840,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 196) @@ -17962,7 +18856,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 15) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: (local.tee $1 @@ -17998,7 +18892,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: (i32.const 0) @@ -18057,54 +18951,58 @@ ;; CHECK-NEXT: (i32.const 648) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (call $_sysconf - ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (call $_sysconf + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 656) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 652) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 660) - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 664) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 668) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 620) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 648) - ;; CHECK-NEXT: (i32.xor - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (call $_time - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 656) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 652) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 660) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 664) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 668) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 620) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 648) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (call $_time + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -16) + ;; CHECK-NEXT: (i32.const 1431655768) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1431655768) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18139,8 +19037,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if @@ -18149,29 +19049,33 @@ ;; CHECK-NEXT: (i32.const 616) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 608) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 608) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $11 @@ -18191,7 +19095,7 @@ ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $label$break$L279 ;; CHECK-NEXT: (block $__rjti$5 ;; CHECK-NEXT: (block $__rjti$4 @@ -18218,26 +19122,28 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out33) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $while-out33) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18266,33 +19172,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2147483647) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (call $_sbrk - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (call $_sbrk + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $__rjti$13 - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $__rjti$13 + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__rjti$5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__rjti$5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18307,7 +19217,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.and @@ -18325,23 +19235,27 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $9 @@ -18365,22 +19279,24 @@ ;; CHECK-NEXT: (i32.const 2147483647) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.tee $2 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (i32.const 616) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $label$break$L279 - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.le_u - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $9) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $label$break$L279 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18428,65 +19344,75 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 656) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 656) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2147483647) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eq - ;; CHECK-NEXT: (call $_sbrk - ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 2147483647) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $_sbrk - ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (call $_sbrk + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $_sbrk + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$break$L279) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$break$L279) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -18510,42 +19436,46 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.const 2147483647) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (call $_sbrk - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (call $_sbrk + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (call $_sbrk - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (call $_sbrk + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ne - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const -1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $__rjti$13 - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $__rjti$13 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18571,9 +19501,11 @@ ;; CHECK-NEXT: (i32.const 612) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 612) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 612) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block $do-once40 @@ -18583,7 +19515,7 @@ ;; CHECK-NEXT: (i32.const 200) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 624) ;; CHECK-NEXT: ) @@ -18631,91 +19563,93 @@ ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.ge_u - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $11) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.ge_u ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 188) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 188) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 200) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 188) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 188) ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=4 - ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.store offset=4 ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 40) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 204) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 664) + ;; CHECK-NEXT: (i32.store offset=4 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 204) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 664) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once40) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once40) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -18729,7 +19663,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: (local.get $1) @@ -18758,7 +19692,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -18785,10 +19719,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.const 624) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const 624) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $1) @@ -18881,7 +19817,7 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 188) ;; CHECK-NEXT: (local.tee $0 @@ -18905,7 +19841,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $5) @@ -18913,7 +19849,7 @@ ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: (local.tee $0 @@ -18962,7 +19898,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $11 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $0) @@ -18981,7 +19917,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.load offset=12 ;; CHECK-NEXT: (local.get $5) @@ -19005,13 +19941,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $do-once51 ;; CHECK-NEXT: (i32.eq @@ -19030,7 +19968,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.and @@ -19055,19 +19993,23 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $15 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $15 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -19081,7 +20023,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $15 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -19101,7 +20043,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.load offset=24 ;; CHECK-NEXT: (local.get $5) @@ -19117,7 +20059,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.tee $1 @@ -19136,20 +20078,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $12 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $12 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once55) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once55) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19165,7 +20111,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -19186,7 +20132,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -19202,8 +20148,10 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) @@ -19214,7 +20162,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.tee $2 @@ -19224,7 +20172,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -19238,7 +20188,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -19252,7 +20204,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (local.get $0) @@ -19265,7 +20217,9 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19295,7 +20249,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $12) @@ -19320,7 +20274,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $label$break$L331) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $6) @@ -19328,7 +20282,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -19342,13 +20298,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $label$break$L331 @@ -19368,7 +20328,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=24 ;; CHECK-NEXT: (local.get $12) @@ -19385,20 +20347,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=16 - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19419,8 +20385,10 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store offset=20 ;; CHECK-NEXT: (local.get $12) ;; CHECK-NEXT: (local.get $0) @@ -19445,7 +20413,9 @@ ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 4) @@ -19483,7 +20453,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.shl @@ -19508,7 +20478,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ge_u ;; CHECK-NEXT: (local.tee $0 @@ -19525,7 +20495,7 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $16 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -19537,7 +20507,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.or @@ -19588,7 +20558,7 @@ ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $do-once65 ;; CHECK-NEXT: (i32.const 31) @@ -19678,7 +20648,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19720,7 +20692,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.or @@ -19811,7 +20783,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -19829,8 +20801,10 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $8) @@ -19876,7 +20850,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store offset=12 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $8) @@ -19898,7 +20872,9 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19924,17 +20900,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $while-out69 - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.load offset=4 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $while-out69 + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.load offset=4 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -20136,7 +21114,7 @@ ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.and @@ -20173,7 +21151,7 @@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.shl @@ -20197,33 +21175,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $17 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $17 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.or @@ -20272,93 +21254,101 @@ ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.const 16777215) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (i32.const 16777215) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 14) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.tee $2 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 520192) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 520192) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 245760) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 245760) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) @@ -20394,7 +21384,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.or @@ -20485,7 +21475,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -20503,8 +21493,10 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $6) @@ -20550,7 +21542,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store offset=12 ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $6) @@ -20572,13 +21564,15 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.eqz @@ -20593,9 +21587,11 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store @@ -20802,198 +21798,220 @@ (local.get $0) (i32.const 245) ) - (block - (if - (i32.and - (local.tee $5 - (i32.shr_u - (local.tee $11 - (i32.load - (i32.const 176) + (then + (block + (if + (i32.and + (local.tee $5 + (i32.shr_u + (local.tee $11 + (i32.load + (i32.const 176) + ) ) - ) - (local.tee $13 - (i32.shr_u - (local.tee $4 - (select - (i32.const 16) - (i32.and - (i32.add + (local.tee $13 + (i32.shr_u + (local.tee $4 + (select + (i32.const 16) + (i32.and + (i32.add + (local.get $0) + (i32.const 11) + ) + (i32.const -8) + ) + (i32.lt_u (local.get $0) (i32.const 11) ) - (i32.const -8) - ) - (i32.lt_u - (local.get $0) - (i32.const 11) ) ) + (i32.const 3) ) - (i32.const 3) ) ) ) + (i32.const 3) ) - (i32.const 3) - ) - (block - (local.set $10 - (i32.load - (local.tee $1 - (i32.add - (local.tee $7 - (i32.load - (local.tee $3 - (i32.add - (local.tee $2 + (then + (block + (local.set $10 + (i32.load + (local.tee $1 + (i32.add + (local.tee $7 + (i32.load + (local.tee $3 (i32.add - (i32.shl - (local.tee $4 - (i32.add - (i32.xor - (i32.and - (local.get $5) - (i32.const 1) + (local.tee $2 + (i32.add + (i32.shl + (local.tee $4 + (i32.add + (i32.xor + (i32.and + (local.get $5) + (i32.const 1) + ) + (i32.const 1) + ) + (local.get $13) ) - (i32.const 1) ) - (local.get $13) + (i32.const 3) ) + (i32.const 216) ) - (i32.const 3) ) - (i32.const 216) + (i32.const 8) ) ) - (i32.const 8) ) ) + (i32.const 8) ) ) - (i32.const 8) ) ) - ) - ) - (if - (i32.eq - (local.get $2) - (local.get $10) - ) - (i32.store - (i32.const 176) - (i32.and - (local.get $11) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $4) - ) - (i32.const -1) - ) - ) - ) - (block (if - (i32.lt_u + (i32.eq + (local.get $2) (local.get $10) - (i32.load - (i32.const 192) - ) ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $10) - (i32.const 12) + (then + (i32.store + (i32.const 176) + (i32.and + (local.get $11) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $4) + ) + (i32.const -1) ) ) ) - (local.get $7) ) - (block - (i32.store - (local.get $0) - (local.get $2) - ) - (i32.store - (local.get $3) - (local.get $10) + (else + (block + (if + (i32.lt_u + (local.get $10) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $10) + (i32.const 12) + ) + ) + ) + (local.get $7) + ) + (then + (block + (i32.store + (local.get $0) + (local.get $2) + ) + (i32.store + (local.get $3) + (local.get $10) + ) + ) + ) + (else + (call $_abort) + ) + ) ) ) - (call $_abort) ) - ) - ) - (i32.store offset=4 - (local.get $7) - (i32.or - (local.tee $0 - (i32.shl - (local.get $4) + (i32.store offset=4 + (local.get $7) + (i32.or + (local.tee $0 + (i32.shl + (local.get $4) + (i32.const 3) + ) + ) (i32.const 3) ) ) - (i32.const 3) - ) - ) - (i32.store - (local.tee $0 - (i32.add - (i32.add - (local.get $7) - (local.get $0) + (i32.store + (local.tee $0 + (i32.add + (i32.add + (local.get $7) + (local.get $0) + ) + (i32.const 4) + ) + ) + (i32.or + (i32.load + (local.get $0) + ) + (i32.const 1) ) - (i32.const 4) ) - ) - (i32.or - (i32.load - (local.get $0) + (return + (local.get $1) ) - (i32.const 1) ) ) - (return - (local.get $1) - ) ) - ) - (if - (i32.gt_u - (local.get $4) - (local.tee $0 - (i32.load - (i32.const 184) + (if + (i32.gt_u + (local.get $4) + (local.tee $0 + (i32.load + (i32.const 184) + ) ) ) - ) - (block - (if - (local.get $5) + (then (block - (local.set $10 - (i32.and - (i32.shr_u - (local.tee $3 - (i32.add - (i32.and + (if + (local.get $5) + (then + (block + (local.set $10 + (i32.and + (i32.shr_u (local.tee $3 - (i32.and - (i32.shl - (local.get $5) - (local.get $13) - ) - (i32.or + (i32.add + (i32.and (local.tee $3 - (i32.shl - (i32.const 2) - (local.get $13) + (i32.and + (i32.shl + (local.get $5) + (local.get $13) + ) + (i32.or + (local.tee $3 + (i32.shl + (i32.const 2) + (local.get $13) + ) + ) + (i32.sub + (i32.const 0) + (local.get $3) + ) + ) ) ) (i32.sub @@ -21001,2416 +22019,2652 @@ (local.get $3) ) ) + (i32.const -1) ) ) - (i32.sub - (i32.const 0) - (local.get $3) - ) + (i32.const 12) ) - (i32.const -1) + (i32.const 16) ) ) - (i32.const 12) - ) - (i32.const 16) - ) - ) - (local.set $9 - (i32.load - (local.tee $7 - (i32.add - (local.tee $12 - (i32.load - (local.tee $3 - (i32.add - (local.tee $10 - (i32.add - (i32.shl - (local.tee $5 + (local.set $9 + (i32.load + (local.tee $7 + (i32.add + (local.tee $12 + (i32.load + (local.tee $3 + (i32.add + (local.tee $10 (i32.add - (i32.or - (i32.or - (i32.or + (i32.shl + (local.tee $5 + (i32.add (i32.or - (local.tee $3 - (i32.and - (i32.shr_u - (local.tee $7 - (i32.shr_u - (local.get $3) - (local.get $10) + (i32.or + (i32.or + (i32.or + (local.tee $3 + (i32.and + (i32.shr_u + (local.tee $7 + (i32.shr_u + (local.get $3) + (local.get $10) + ) + ) + (i32.const 5) + ) + (i32.const 8) ) ) - (i32.const 5) + (local.get $10) ) - (i32.const 8) - ) - ) - (local.get $10) - ) - (local.tee $3 - (i32.and - (i32.shr_u - (local.tee $7 - (i32.shr_u - (local.get $7) - (local.get $3) + (local.tee $3 + (i32.and + (i32.shr_u + (local.tee $7 + (i32.shr_u + (local.get $7) + (local.get $3) + ) + ) + (i32.const 2) + ) + (i32.const 4) ) ) - (i32.const 2) ) - (i32.const 4) + (local.tee $3 + (i32.and + (i32.shr_u + (local.tee $7 + (i32.shr_u + (local.get $7) + (local.get $3) + ) + ) + (i32.const 1) + ) + (i32.const 2) + ) + ) ) - ) - ) - (local.tee $3 - (i32.and - (i32.shr_u - (local.tee $7 + (local.tee $3 + (i32.and (i32.shr_u - (local.get $7) - (local.get $3) + (local.tee $7 + (i32.shr_u + (local.get $7) + (local.get $3) + ) + ) + (i32.const 1) ) + (i32.const 1) ) - (i32.const 1) ) - (i32.const 2) ) - ) - ) - (local.tee $3 - (i32.and (i32.shr_u - (local.tee $7 - (i32.shr_u - (local.get $7) - (local.get $3) - ) - ) - (i32.const 1) + (local.get $7) + (local.get $3) ) - (i32.const 1) ) ) + (i32.const 3) ) - (i32.shr_u - (local.get $7) - (local.get $3) - ) + (i32.const 216) ) ) - (i32.const 3) + (i32.const 8) ) - (i32.const 216) ) ) - (i32.const 8) ) + (i32.const 8) ) ) ) - (i32.const 8) - ) - ) - ) - ) - (if - (i32.eq - (local.get $10) - (local.get $9) - ) - (block - (i32.store - (i32.const 176) - (i32.and - (local.get $11) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $5) - ) - (i32.const -1) - ) ) - ) - (local.set $8 - (local.get $0) - ) - ) - (block - (if - (i32.lt_u - (local.get $9) - (i32.load - (i32.const 192) + (if + (i32.eq + (local.get $10) + (local.get $9) ) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $9) - (i32.const 12) + (then + (block + (i32.store + (i32.const 176) + (i32.and + (local.get $11) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $5) + ) + (i32.const -1) + ) + ) + ) + (local.set $8 + (local.get $0) ) ) ) - (local.get $12) - ) - (block - (i32.store - (local.get $0) - (local.get $10) - ) - (i32.store - (local.get $3) - (local.get $9) - ) - (local.set $8 - (i32.load - (i32.const 184) + (else + (block + (if + (i32.lt_u + (local.get $9) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $9) + (i32.const 12) + ) + ) + ) + (local.get $12) + ) + (then + (block + (i32.store + (local.get $0) + (local.get $10) + ) + (i32.store + (local.get $3) + (local.get $9) + ) + (local.set $8 + (i32.load + (i32.const 184) + ) + ) + ) + ) + (else + (call $_abort) + ) + ) ) ) ) - (call $_abort) - ) - ) - ) - (i32.store offset=4 - (local.get $12) - (i32.or - (local.get $4) - (i32.const 3) - ) - ) - (i32.store offset=4 - (local.tee $10 - (i32.add - (local.get $12) - (local.get $4) - ) - ) - (i32.or - (local.tee $5 - (i32.sub - (i32.shl - (local.get $5) + (i32.store offset=4 + (local.get $12) + (i32.or + (local.get $4) (i32.const 3) ) - (local.get $4) - ) - ) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $10) - (local.get $5) - ) - (local.get $5) - ) - (if - (local.get $8) - (block - (local.set $12 - (i32.load - (i32.const 196) ) - ) - (local.set $4 - (i32.add - (i32.shl - (local.tee $0 - (i32.shr_u - (local.get $8) - (i32.const 3) - ) + (i32.store offset=4 + (local.tee $10 + (i32.add + (local.get $12) + (local.get $4) ) - (i32.const 3) ) - (i32.const 216) - ) - ) - (if - (i32.and - (local.tee $3 - (i32.load - (i32.const 176) + (i32.or + (local.tee $5 + (i32.sub + (i32.shl + (local.get $5) + (i32.const 3) + ) + (local.get $4) + ) ) + (i32.const 1) ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $0) - ) + ) + (i32.store + (i32.add + (local.get $10) + (local.get $5) ) + (local.get $5) ) (if - (i32.lt_u - (local.tee $0 - (i32.load - (local.tee $3 - (i32.add - (local.get $4) - (i32.const 8) - ) - ) - ) - ) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (local.set $2 - (local.get $3) - ) - (local.set $1 - (local.get $0) - ) - ) - ) - (block - (i32.store - (i32.const 176) - (i32.or - (local.get $3) - (local.get $0) - ) - ) - (local.set $2 - (i32.add - (local.get $4) - (i32.const 8) - ) - ) - (local.set $1 - (local.get $4) - ) - ) - ) - (i32.store - (local.get $2) - (local.get $12) - ) - (i32.store offset=12 - (local.get $1) - (local.get $12) - ) - (i32.store offset=8 - (local.get $12) - (local.get $1) - ) - (i32.store offset=12 - (local.get $12) - (local.get $4) - ) - ) - ) - (i32.store - (i32.const 184) - (local.get $5) - ) - (i32.store - (i32.const 196) - (local.get $10) - ) - (return - (local.get $7) - ) - ) - ) - (if - (local.tee $0 - (i32.load - (i32.const 180) - ) - ) - (block - (local.set $2 - (i32.and - (i32.shr_u - (local.tee $0 - (i32.add - (i32.and - (local.get $0) - (i32.sub - (i32.const 0) - (local.get $0) + (local.get $8) + (then + (block + (local.set $12 + (i32.load + (i32.const 196) + ) ) - ) - (i32.const -1) - ) - ) - (i32.const 12) - ) - (i32.const 16) - ) - ) - (local.set $7 - (i32.sub - (i32.and - (i32.load offset=4 - (local.tee $0 - (i32.load offset=480 - (i32.shl + (local.set $4 (i32.add - (i32.or - (i32.or - (i32.or - (i32.or - (local.tee $0 - (i32.and - (i32.shr_u - (local.tee $1 - (i32.shr_u - (local.get $0) - (local.get $2) - ) - ) - (i32.const 5) - ) - (i32.const 8) - ) - ) - (local.get $2) - ) - (local.tee $0 - (i32.and - (i32.shr_u - (local.tee $1 - (i32.shr_u - (local.get $1) - (local.get $0) - ) - ) - (i32.const 2) - ) - (i32.const 4) - ) - ) + (i32.shl + (local.tee $0 + (i32.shr_u + (local.get $8) + (i32.const 3) ) + ) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (if + (i32.and + (local.tee $3 + (i32.load + (i32.const 176) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $0) + ) + ) + ) + (then + (if + (i32.lt_u (local.tee $0 - (i32.and - (i32.shr_u - (local.tee $1 - (i32.shr_u - (local.get $1) - (local.get $0) - ) + (i32.load + (local.tee $3 + (i32.add + (local.get $4) + (i32.const 8) ) - (i32.const 1) ) - (i32.const 2) ) ) + (i32.load + (i32.const 192) + ) ) - (local.tee $0 - (i32.and - (i32.shr_u - (local.tee $1 - (i32.shr_u - (local.get $1) - (local.get $0) - ) - ) - (i32.const 1) + (then + (call $_abort) + ) + (else + (block + (local.set $2 + (local.get $3) + ) + (local.set $1 + (local.get $0) ) - (i32.const 1) ) ) ) - (i32.shr_u - (local.get $1) - (local.get $0) + ) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $3) + (local.get $0) + ) + ) + (local.set $2 + (i32.add + (local.get $4) + (i32.const 8) + ) + ) + (local.set $1 + (local.get $4) + ) ) ) - (i32.const 2) + ) + (i32.store + (local.get $2) + (local.get $12) + ) + (i32.store offset=12 + (local.get $1) + (local.get $12) + ) + (i32.store offset=8 + (local.get $12) + (local.get $1) + ) + (i32.store offset=12 + (local.get $12) + (local.get $4) ) ) ) ) - (i32.const -8) + (i32.store + (i32.const 184) + (local.get $5) + ) + (i32.store + (i32.const 196) + (local.get $10) + ) + (return + (local.get $7) + ) ) - (local.get $4) ) ) - (local.set $1 - (local.get $0) - ) - (local.set $2 - (local.get $0) - ) - (loop $while-in - (block $while-out - (if - (i32.eqz - (local.tee $0 - (i32.load offset=16 - (local.get $1) - ) - ) - ) - (if - (i32.eqz - (local.tee $0 - (i32.load offset=20 - (local.get $1) - ) - ) - ) - (block - (local.set $10 - (local.get $7) - ) - (local.set $5 - (local.get $2) + (if + (local.tee $0 + (i32.load + (i32.const 180) + ) + ) + (then + (block + (local.set $2 + (i32.and + (i32.shr_u + (local.tee $0 + (i32.add + (i32.and + (local.get $0) + (i32.sub + (i32.const 0) + (local.get $0) + ) + ) + (i32.const -1) + ) + ) + (i32.const 12) ) - (br $while-out) + (i32.const 16) ) ) - ) - (local.set $10 - (i32.lt_u - (local.tee $1 - (i32.sub - (i32.and - (i32.load offset=4 - (local.get $0) + (local.set $7 + (i32.sub + (i32.and + (i32.load offset=4 + (local.tee $0 + (i32.load offset=480 + (i32.shl + (i32.add + (i32.or + (i32.or + (i32.or + (i32.or + (local.tee $0 + (i32.and + (i32.shr_u + (local.tee $1 + (i32.shr_u + (local.get $0) + (local.get $2) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (local.get $2) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (local.tee $1 + (i32.shr_u + (local.get $1) + (local.get $0) + ) + ) + (i32.const 2) + ) + (i32.const 4) + ) + ) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (local.tee $1 + (i32.shr_u + (local.get $1) + (local.get $0) + ) + ) + (i32.const 1) + ) + (i32.const 2) + ) + ) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (local.tee $1 + (i32.shr_u + (local.get $1) + (local.get $0) + ) + ) + (i32.const 1) + ) + (i32.const 1) + ) + ) + ) + (i32.shr_u + (local.get $1) + (local.get $0) + ) + ) + (i32.const 2) + ) + ) ) - (i32.const -8) ) - (local.get $4) + (i32.const -8) ) + (local.get $4) ) - (local.get $7) - ) - ) - (local.set $7 - (select - (local.get $1) - (local.get $7) - (local.get $10) ) - ) - (local.set $1 - (local.get $0) - ) - (local.set $2 - (select + (local.set $1 (local.get $0) - (local.get $2) - (local.get $10) - ) - ) - (br $while-in) - ) - ) - (if - (i32.lt_u - (local.get $5) - (local.tee $12 - (i32.load - (i32.const 192) - ) - ) - ) - (call $_abort) - ) - (if - (i32.ge_u - (local.get $5) - (local.tee $11 - (i32.add - (local.get $5) - (local.get $4) ) - ) - ) - (call $_abort) - ) - (local.set $8 - (i32.load offset=24 - (local.get $5) - ) - ) - (block $do-once4 - (if - (i32.eq - (local.tee $0 - (i32.load offset=12 - (local.get $5) - ) + (local.set $2 + (local.get $0) ) - (local.get $5) - ) - (block - (if - (i32.eqz - (local.tee $1 - (i32.load + (loop $while-in + (block $while-out + (if + (i32.eqz (local.tee $0 - (i32.add - (local.get $5) - (i32.const 20) + (i32.load offset=16 + (local.get $1) ) ) ) - ) - ) - (if - (i32.eqz - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add - (local.get $5) - (i32.const 16) + (then + (if + (i32.eqz + (local.tee $0 + (i32.load offset=20 + (local.get $1) + ) + ) + ) + (then + (block + (local.set $10 + (local.get $7) + ) + (local.set $5 + (local.get $2) + ) + (br $while-out) ) ) ) ) ) - (block - (local.set $9 - (i32.const 0) - ) - (br $do-once4) - ) - ) - ) - (loop $while-in7 - (if - (local.tee $2 - (i32.load - (local.tee $7 - (i32.add - (local.get $1) - (i32.const 20) + (local.set $10 + (i32.lt_u + (local.tee $1 + (i32.sub + (i32.and + (i32.load offset=4 + (local.get $0) + ) + (i32.const -8) + ) + (local.get $4) ) ) + (local.get $7) ) ) - (block - (local.set $1 - (local.get $2) - ) - (local.set $0 + (local.set $7 + (select + (local.get $1) (local.get $7) + (local.get $10) ) - (br $while-in7) ) - ) - (if - (local.tee $2 - (i32.load - (local.tee $7 - (i32.add - (local.get $1) - (i32.const 16) - ) - ) - ) + (local.set $1 + (local.get $0) ) - (block - (local.set $1 + (local.set $2 + (select + (local.get $0) (local.get $2) + (local.get $10) ) - (local.set $0 - (local.get $7) - ) - (br $while-in7) ) + (br $while-in) ) ) (if (i32.lt_u - (local.get $0) - (local.get $12) - ) - (call $_abort) - (block - (i32.store - (local.get $0) - (i32.const 0) - ) - (local.set $9 - (local.get $1) + (local.get $5) + (local.tee $12 + (i32.load + (i32.const 192) + ) ) ) + (then + (call $_abort) + ) ) - ) - (block (if - (i32.lt_u - (local.tee $7 - (i32.load offset=8 + (i32.ge_u + (local.get $5) + (local.tee $11 + (i32.add (local.get $5) + (local.get $4) ) ) - (local.get $12) ) - (call $_abort) + (then + (call $_abort) + ) ) - (if - (i32.ne - (i32.load - (local.tee $2 - (i32.add - (local.get $7) - (i32.const 12) - ) - ) - ) + (local.set $8 + (i32.load offset=24 (local.get $5) ) - (call $_abort) ) - (if - (i32.eq - (i32.load - (local.tee $1 - (i32.add - (local.get $0) - (i32.const 8) + (block $do-once4 + (if + (i32.eq + (local.tee $0 + (i32.load offset=12 + (local.get $5) ) ) + (local.get $5) ) - (local.get $5) - ) - (block - (i32.store - (local.get $2) - (local.get $0) - ) - (i32.store - (local.get $1) - (local.get $7) - ) - (local.set $9 - (local.get $0) - ) - ) - (call $_abort) - ) - ) - ) - ) - (block $do-once8 - (if - (local.get $8) - (block - (if - (i32.eq - (local.get $5) - (i32.load - (local.tee $0 - (i32.add - (i32.shl + (then + (block + (if + (i32.eqz (local.tee $1 - (i32.load offset=28 - (local.get $5) + (i32.load + (local.tee $0 + (i32.add + (local.get $5) + (i32.const 20) + ) + ) + ) + ) + ) + (then + (if + (i32.eqz + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.get $5) + (i32.const 16) + ) + ) + ) + ) + ) + (then + (block + (local.set $9 + (i32.const 0) + ) + (br $do-once4) + ) ) ) - (i32.const 2) ) - (i32.const 480) ) - ) - ) - ) - (block - (i32.store - (local.get $0) - (local.get $9) - ) - (if - (i32.eqz - (local.get $9) - ) - (block - (i32.store - (i32.const 180) - (i32.and - (i32.load - (i32.const 180) + (loop $while-in7 + (if + (local.tee $2 + (i32.load + (local.tee $7 + (i32.add + (local.get $1) + (i32.const 20) + ) + ) + ) ) - (i32.xor - (i32.shl - (i32.const 1) + (then + (block + (local.set $1 + (local.get $2) + ) + (local.set $0 + (local.get $7) + ) + (br $while-in7) + ) + ) + ) + (if + (local.tee $2 + (i32.load + (local.tee $7 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + ) + ) + (then + (block + (local.set $1 + (local.get $2) + ) + (local.set $0 + (local.get $7) + ) + (br $while-in7) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $0) + (local.get $12) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $0) + (i32.const 0) + ) + (local.set $9 (local.get $1) ) - (i32.const -1) ) ) ) - (br $do-once8) ) ) - ) - (block - (if - (i32.lt_u - (local.get $8) - (i32.load - (i32.const 192) + (else + (block + (if + (i32.lt_u + (local.tee $7 + (i32.load offset=8 + (local.get $5) + ) + ) + (local.get $12) + ) + (then + (call $_abort) + ) ) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $8) - (i32.const 16) + (if + (i32.ne + (i32.load + (local.tee $2 + (i32.add + (local.get $7) + (i32.const 12) + ) + ) ) + (local.get $5) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $1 + (i32.add + (local.get $0) + (i32.const 8) + ) + ) + ) + (local.get $5) + ) + (then + (block + (i32.store + (local.get $2) + (local.get $0) + ) + (i32.store + (local.get $1) + (local.get $7) + ) + (local.set $9 + (local.get $0) + ) + ) + ) + (else + (call $_abort) ) ) - (local.get $5) - ) - (i32.store - (local.get $0) - (local.get $9) - ) - (i32.store offset=20 - (local.get $8) - (local.get $9) - ) - ) - (br_if $do-once8 - (i32.eqz - (local.get $9) ) ) ) ) - (if - (i32.lt_u - (local.get $9) - (local.tee $0 - (i32.load - (i32.const 192) + (block $do-once8 + (if + (local.get $8) + (then + (block + (if + (i32.eq + (local.get $5) + (i32.load + (local.tee $0 + (i32.add + (i32.shl + (local.tee $1 + (i32.load offset=28 + (local.get $5) + ) + ) + (i32.const 2) + ) + (i32.const 480) + ) + ) + ) + ) + (then + (block + (i32.store + (local.get $0) + (local.get $9) + ) + (if + (i32.eqz + (local.get $9) + ) + (then + (block + (i32.store + (i32.const 180) + (i32.and + (i32.load + (i32.const 180) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $1) + ) + (i32.const -1) + ) + ) + ) + (br $do-once8) + ) + ) + ) + ) + ) + (else + (block + (if + (i32.lt_u + (local.get $8) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $8) + (i32.const 16) + ) + ) + ) + (local.get $5) + ) + (then + (i32.store + (local.get $0) + (local.get $9) + ) + ) + (else + (i32.store offset=20 + (local.get $8) + (local.get $9) + ) + ) + ) + (br_if $do-once8 + (i32.eqz + (local.get $9) + ) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $9) + (local.tee $0 + (i32.load + (i32.const 192) + ) + ) + ) + (then + (call $_abort) + ) + ) + (i32.store offset=24 + (local.get $9) + (local.get $8) + ) + (if + (local.tee $1 + (i32.load offset=16 + (local.get $5) + ) + ) + (then + (if + (i32.lt_u + (local.get $1) + (local.get $0) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=16 + (local.get $9) + (local.get $1) + ) + (i32.store offset=24 + (local.get $1) + (local.get $9) + ) + ) + ) + ) + ) + ) + (if + (local.tee $0 + (i32.load offset=20 + (local.get $5) + ) + ) + (then + (if + (i32.lt_u + (local.get $0) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=20 + (local.get $9) + (local.get $0) + ) + (i32.store offset=24 + (local.get $0) + (local.get $9) + ) + ) + ) + ) + ) + ) ) ) ) - (call $_abort) - ) - (i32.store offset=24 - (local.get $9) - (local.get $8) ) (if - (local.tee $1 - (i32.load offset=16 - (local.get $5) - ) + (i32.lt_u + (local.get $10) + (i32.const 16) ) - (if - (i32.lt_u - (local.get $1) - (local.get $0) - ) - (call $_abort) + (then (block - (i32.store offset=16 - (local.get $9) - (local.get $1) + (i32.store offset=4 + (local.get $5) + (i32.or + (local.tee $0 + (i32.add + (local.get $10) + (local.get $4) + ) + ) + (i32.const 3) + ) ) - (i32.store offset=24 - (local.get $1) - (local.get $9) + (i32.store + (local.tee $0 + (i32.add + (i32.add + (local.get $5) + (local.get $0) + ) + (i32.const 4) + ) + ) + (i32.or + (i32.load + (local.get $0) + ) + (i32.const 1) + ) ) ) ) - ) - (if - (local.tee $0 - (i32.load offset=20 - (local.get $5) - ) - ) - (if - (i32.lt_u - (local.get $0) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) + (else (block - (i32.store offset=20 - (local.get $9) - (local.get $0) + (i32.store offset=4 + (local.get $5) + (i32.or + (local.get $4) + (i32.const 3) + ) ) - (i32.store offset=24 - (local.get $0) - (local.get $9) + (i32.store offset=4 + (local.get $11) + (i32.or + (local.get $10) + (i32.const 1) + ) ) - ) - ) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $10) - (i32.const 16) - ) - (block - (i32.store offset=4 - (local.get $5) - (i32.or - (local.tee $0 - (i32.add - (local.get $10) - (local.get $4) - ) - ) - (i32.const 3) - ) - ) - (i32.store - (local.tee $0 - (i32.add - (i32.add - (local.get $5) - (local.get $0) - ) - (i32.const 4) - ) - ) - (i32.or - (i32.load - (local.get $0) - ) - (i32.const 1) - ) - ) - ) - (block - (i32.store offset=4 - (local.get $5) - (i32.or - (local.get $4) - (i32.const 3) - ) - ) - (i32.store offset=4 - (local.get $11) - (i32.or - (local.get $10) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $11) - (local.get $10) - ) - (local.get $10) - ) - (if - (local.tee $0 - (i32.load - (i32.const 184) - ) - ) - (block - (local.set $4 - (i32.load - (i32.const 196) - ) - ) - (local.set $2 - (i32.add - (i32.shl - (local.tee $0 - (i32.shr_u - (local.get $0) - (i32.const 3) - ) - ) - (i32.const 3) - ) - (i32.const 216) - ) - ) - (if - (i32.and - (local.tee $1 - (i32.load - (i32.const 176) - ) - ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $0) + (i32.store + (i32.add + (local.get $11) + (local.get $10) ) + (local.get $10) ) - ) - (if - (i32.lt_u + (if (local.tee $0 (i32.load - (local.tee $1 + (i32.const 184) + ) + ) + (then + (block + (local.set $4 + (i32.load + (i32.const 196) + ) + ) + (local.set $2 (i32.add - (local.get $2) - (i32.const 8) + (i32.shl + (local.tee $0 + (i32.shr_u + (local.get $0) + (i32.const 3) + ) + ) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (if + (i32.and + (local.tee $1 + (i32.load + (i32.const 176) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $0) + ) + ) + ) + (then + (if + (i32.lt_u + (local.tee $0 + (i32.load + (local.tee $1 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (local.set $6 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + ) + ) + ) + ) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (local.set $6 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + (local.set $3 + (local.get $2) + ) + ) ) ) + (i32.store + (local.get $6) + (local.get $4) + ) + (i32.store offset=12 + (local.get $3) + (local.get $4) + ) + (i32.store offset=8 + (local.get $4) + (local.get $3) + ) + (i32.store offset=12 + (local.get $4) + (local.get $2) + ) ) ) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (local.set $6 - (local.get $1) - ) - (local.set $3 - (local.get $0) - ) ) - ) - (block (i32.store - (i32.const 176) - (i32.or - (local.get $1) - (local.get $0) - ) - ) - (local.set $6 - (i32.add - (local.get $2) - (i32.const 8) - ) + (i32.const 184) + (local.get $10) ) - (local.set $3 - (local.get $2) + (i32.store + (i32.const 196) + (local.get $11) ) ) ) - (i32.store - (local.get $6) - (local.get $4) - ) - (i32.store offset=12 - (local.get $3) - (local.get $4) - ) - (i32.store offset=8 - (local.get $4) - (local.get $3) - ) - (i32.store offset=12 - (local.get $4) - (local.get $2) + ) + (return + (i32.add + (local.get $5) + (i32.const 8) ) ) ) - (i32.store - (i32.const 184) - (local.get $10) - ) - (i32.store - (i32.const 196) - (local.get $11) - ) ) - ) - (return - (i32.add - (local.get $5) - (i32.const 8) + (else + (local.set $0 + (local.get $4) + ) ) ) ) + ) + (else (local.set $0 (local.get $4) ) ) ) - (local.set $0 - (local.get $4) - ) ) ) - (if - (i32.gt_u - (local.get $0) - (i32.const -65) - ) - (local.set $0 - (i32.const -1) - ) - (block - (local.set $2 - (i32.and - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 11) - ) - ) - (i32.const -8) - ) + (else + (if + (i32.gt_u + (local.get $0) + (i32.const -65) ) - (if - (local.tee $18 - (i32.load - (i32.const 180) - ) + (then + (local.set $0 + (i32.const -1) ) + ) + (else (block - (local.set $14 - (if (result i32) + (local.set $2 + (i32.and (local.tee $0 - (i32.shr_u + (i32.add (local.get $0) - (i32.const 8) + (i32.const 11) ) ) - (if (result i32) - (i32.gt_u - (local.get $2) - (i32.const 16777215) - ) - (i32.const 31) - (i32.or - (i32.and - (i32.shr_u - (local.get $2) - (i32.add - (local.tee $0 - (i32.add - (i32.sub - (i32.const 14) - (i32.or - (i32.or + (i32.const -8) + ) + ) + (if + (local.tee $18 + (i32.load + (i32.const 180) + ) + ) + (then + (block + (local.set $14 + (if (result i32) + (local.tee $0 + (i32.shr_u + (local.get $0) + (i32.const 8) + ) + ) + (then + (if (result i32) + (i32.gt_u + (local.get $2) + (i32.const 16777215) + ) + (then + (i32.const 31) + ) + (else + (i32.or + (i32.and + (i32.shr_u + (local.get $2) + (i32.add (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $0) - (local.tee $3 - (i32.and - (i32.shr_u - (i32.add + (i32.add + (i32.sub + (i32.const 14) + (i32.or + (i32.or + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $0) + (local.tee $3 + (i32.and + (i32.shr_u + (i32.add + (local.get $0) + (i32.const 1048320) + ) + (i32.const 16) + ) + (i32.const 8) + ) + ) + ) + ) + (i32.const 520192) + ) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (local.get $3) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $1) (local.get $0) - (i32.const 1048320) ) - (i32.const 16) ) - (i32.const 8) + (i32.const 245760) ) + (i32.const 16) ) + (i32.const 2) ) ) - (i32.const 520192) ) - (i32.const 16) ) - (i32.const 4) - ) - ) - (local.get $3) - ) - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $1) - (local.get $0) - ) + (i32.shr_u + (i32.shl + (local.get $1) + (local.get $0) ) - (i32.const 245760) + (i32.const 15) ) - (i32.const 16) ) - (i32.const 2) ) + (i32.const 7) ) ) + (i32.const 1) ) - (i32.shr_u - (i32.shl - (local.get $1) - (local.get $0) - ) - (i32.const 15) + (i32.shl + (local.get $0) + (i32.const 1) ) ) ) - (i32.const 7) ) ) - (i32.const 1) - ) - (i32.shl - (local.get $0) - (i32.const 1) - ) - ) - ) - (i32.const 0) - ) - ) - (local.set $3 - (i32.sub - (i32.const 0) - (local.get $2) - ) - ) - (block $__rjto$3 - (block $__rjti$3 - (if - (local.tee $0 - (i32.load offset=480 - (i32.shl - (local.get $14) - (i32.const 2) + (else + (i32.const 0) ) ) ) - (block - (local.set $6 + (local.set $3 + (i32.sub (i32.const 0) + (local.get $2) ) - (local.set $8 - (i32.shl - (local.get $2) - (select - (i32.const 0) - (i32.sub - (i32.const 25) - (i32.shr_u + ) + (block $__rjto$3 + (block $__rjti$3 + (if + (local.tee $0 + (i32.load offset=480 + (i32.shl (local.get $14) - (i32.const 1) + (i32.const 2) ) ) - (i32.eq - (local.get $14) - (i32.const 31) - ) ) - ) - ) - (local.set $1 - (i32.const 0) - ) - (loop $while-in14 - (if - (i32.lt_u - (local.tee $4 - (i32.sub - (local.tee $9 - (i32.and - (i32.load offset=4 - (local.get $0) + (then + (block + (local.set $6 + (i32.const 0) + ) + (local.set $8 + (i32.shl + (local.get $2) + (select + (i32.const 0) + (i32.sub + (i32.const 25) + (i32.shr_u + (local.get $14) + (i32.const 1) + ) + ) + (i32.eq + (local.get $14) + (i32.const 31) ) - (i32.const -8) ) ) - (local.get $2) - ) - ) - (local.get $3) - ) - (if - (i32.eq - (local.get $9) - (local.get $2) - ) - (block - (local.set $1 - (local.get $4) - ) - (local.set $3 - (local.get $0) - ) - (br $__rjti$3) - ) - (block - (local.set $3 - (local.get $4) ) (local.set $1 - (local.get $0) - ) - ) - ) - ) - (local.set $0 - (select - (local.get $6) - (local.tee $4 - (i32.load offset=20 - (local.get $0) - ) - ) - (i32.or - (i32.eqz - (local.get $4) + (i32.const 0) ) - (i32.eq - (local.get $4) - (local.tee $9 - (i32.load - (i32.add - (i32.add - (local.get $0) - (i32.const 16) - ) - (i32.shl - (i32.shr_u - (local.get $8) - (i32.const 31) + (loop $while-in14 + (if + (i32.lt_u + (local.tee $4 + (i32.sub + (local.tee $9 + (i32.and + (i32.load offset=4 + (local.get $0) + ) + (i32.const -8) + ) ) - (i32.const 2) + (local.get $2) ) ) + (local.get $3) ) - ) - ) - ) - ) - ) - (local.set $4 - (i32.shl - (local.get $8) - (i32.xor - (local.tee $6 - (i32.eqz - (local.get $9) - ) - ) - (i32.const 1) - ) - ) - ) - (if - (local.get $6) - (block - (local.set $4 - (local.get $0) - ) - (local.set $0 - (local.get $1) - ) - ) - (block - (local.set $6 - (local.get $0) - ) - (local.set $8 - (local.get $4) - ) - (local.set $0 - (local.get $9) - ) - (br $while-in14) - ) - ) - ) - ) - (block - (local.set $4 - (i32.const 0) - ) - (local.set $0 - (i32.const 0) - ) - ) - ) - (if - (i32.and - (i32.eqz - (local.get $4) - ) - (i32.eqz - (local.get $0) - ) - ) - (block - (if - (i32.eqz - (local.tee $1 - (i32.and - (local.get $18) - (i32.or - (local.tee $1 - (i32.shl - (i32.const 2) - (local.get $14) - ) - ) - (i32.sub - (i32.const 0) - (local.get $1) - ) - ) - ) - ) - ) - (block - (local.set $0 - (local.get $2) - ) - (br $do-once) - ) - ) - (local.set $9 - (i32.and - (i32.shr_u - (local.tee $1 - (i32.add - (i32.and - (local.get $1) - (i32.sub - (i32.const 0) - (local.get $1) - ) - ) - (i32.const -1) - ) - ) - (i32.const 12) - ) - (i32.const 16) - ) - ) - (local.set $4 - (i32.load offset=480 - (i32.shl - (i32.add - (i32.or - (i32.or - (i32.or - (i32.or - (local.tee $1 - (i32.and - (i32.shr_u - (local.tee $4 - (i32.shr_u - (local.get $1) - (local.get $9) - ) - ) - (i32.const 5) + (then + (if + (i32.eq + (local.get $9) + (local.get $2) + ) + (then + (block + (local.set $1 + (local.get $4) + ) + (local.set $3 + (local.get $0) ) - (i32.const 8) + (br $__rjti$3) ) ) - (local.get $9) - ) - (local.tee $1 - (i32.and - (i32.shr_u - (local.tee $4 - (i32.shr_u - (local.get $4) - (local.get $1) - ) + (else + (block + (local.set $3 + (local.get $4) + ) + (local.set $1 + (local.get $0) ) - (i32.const 2) ) - (i32.const 4) ) ) ) - (local.tee $1 - (i32.and - (i32.shr_u - (local.tee $4 - (i32.shr_u - (local.get $4) - (local.get $1) + ) + (local.set $0 + (select + (local.get $6) + (local.tee $4 + (i32.load offset=20 + (local.get $0) + ) + ) + (i32.or + (i32.eqz + (local.get $4) + ) + (i32.eq + (local.get $4) + (local.tee $9 + (i32.load + (i32.add + (i32.add + (local.get $0) + (i32.const 16) + ) + (i32.shl + (i32.shr_u + (local.get $8) + (i32.const 31) + ) + (i32.const 2) + ) + ) ) ) - (i32.const 1) ) - (i32.const 2) ) ) ) - (local.tee $1 - (i32.and - (i32.shr_u - (local.tee $4 - (i32.shr_u - (local.get $4) - (local.get $1) + (local.set $4 + (i32.shl + (local.get $8) + (i32.xor + (local.tee $6 + (i32.eqz + (local.get $9) ) ) (i32.const 1) ) - (i32.const 1) + ) + ) + (if + (local.get $6) + (then + (block + (local.set $4 + (local.get $0) + ) + (local.set $0 + (local.get $1) + ) + ) + ) + (else + (block + (local.set $6 + (local.get $0) + ) + (local.set $8 + (local.get $4) + ) + (local.set $0 + (local.get $9) + ) + (br $while-in14) + ) ) ) ) - (i32.shr_u - (local.get $4) - (local.get $1) + ) + ) + (else + (block + (local.set $4 + (i32.const 0) + ) + (local.set $0 + (i32.const 0) ) ) - (i32.const 2) ) ) - ) - ) - ) - (if - (local.get $4) - (block - (local.set $1 - (local.get $3) - ) - (local.set $3 - (local.get $4) - ) - (br $__rjti$3) - ) - (local.set $4 - (local.get $0) - ) - ) - (br $__rjto$3) - ) - (loop $while-in16 - (local.set $9 - (i32.lt_u - (local.tee $4 - (i32.sub + (if (i32.and - (i32.load offset=4 - (local.get $3) + (i32.eqz + (local.get $4) + ) + (i32.eqz + (local.get $0) ) - (i32.const -8) ) - (local.get $2) - ) - ) - (local.get $1) - ) - ) - (local.set $1 - (select - (local.get $4) - (local.get $1) - (local.get $9) - ) - ) - (local.set $0 - (select - (local.get $3) - (local.get $0) - (local.get $9) - ) - ) - (if - (local.tee $4 - (i32.load offset=16 - (local.get $3) - ) - ) - (block - (local.set $3 - (local.get $4) - ) - (br $while-in16) - ) - ) - (br_if $while-in16 - (local.tee $3 - (i32.load offset=20 - (local.get $3) - ) - ) - ) - (local.set $3 - (local.get $1) - ) - (local.set $4 - (local.get $0) - ) - ) - ) - (if - (local.get $4) - (if - (i32.lt_u - (local.get $3) - (i32.sub - (i32.load - (i32.const 184) - ) - (local.get $2) - ) - ) - (block - (if - (i32.lt_u - (local.get $4) - (local.tee $12 - (i32.load - (i32.const 192) - ) - ) - ) - (call $_abort) - ) - (if - (i32.ge_u - (local.get $4) - (local.tee $6 - (i32.add - (local.get $4) - (local.get $2) - ) - ) - ) - (call $_abort) - ) - (local.set $9 - (i32.load offset=24 - (local.get $4) - ) - ) - (block $do-once17 - (if - (i32.eq - (local.tee $0 - (i32.load offset=12 - (local.get $4) - ) - ) - (local.get $4) - ) - (block - (if - (i32.eqz - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add - (local.get $4) - (i32.const 20) + (then + (block + (if + (i32.eqz + (local.tee $1 + (i32.and + (local.get $18) + (i32.or + (local.tee $1 + (i32.shl + (i32.const 2) + (local.get $14) + ) + ) + (i32.sub + (i32.const 0) + (local.get $1) + ) + ) ) ) ) - ) - ) - (if - (i32.eqz - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add - (local.get $4) - (i32.const 16) - ) + (then + (block + (local.set $0 + (local.get $2) ) + (br $do-once) ) ) ) - (block - (local.set $11 - (i32.const 0) - ) - (br $do-once17) - ) - ) - ) - (loop $while-in20 - (if - (local.tee $7 - (i32.load - (local.tee $10 - (i32.add - (local.get $1) - (i32.const 20) + (local.set $9 + (i32.and + (i32.shr_u + (local.tee $1 + (i32.add + (i32.and + (local.get $1) + (i32.sub + (i32.const 0) + (local.get $1) + ) + ) + (i32.const -1) + ) ) + (i32.const 12) ) + (i32.const 16) ) ) - (block - (local.set $1 - (local.get $7) - ) - (local.set $0 - (local.get $10) - ) - (br $while-in20) - ) - ) - (if - (local.tee $7 - (i32.load - (local.tee $10 + (local.set $4 + (i32.load offset=480 + (i32.shl (i32.add - (local.get $1) - (i32.const 16) + (i32.or + (i32.or + (i32.or + (i32.or + (local.tee $1 + (i32.and + (i32.shr_u + (local.tee $4 + (i32.shr_u + (local.get $1) + (local.get $9) + ) + ) + (i32.const 5) + ) + (i32.const 8) + ) + ) + (local.get $9) + ) + (local.tee $1 + (i32.and + (i32.shr_u + (local.tee $4 + (i32.shr_u + (local.get $4) + (local.get $1) + ) + ) + (i32.const 2) + ) + (i32.const 4) + ) + ) + ) + (local.tee $1 + (i32.and + (i32.shr_u + (local.tee $4 + (i32.shr_u + (local.get $4) + (local.get $1) + ) + ) + (i32.const 1) + ) + (i32.const 2) + ) + ) + ) + (local.tee $1 + (i32.and + (i32.shr_u + (local.tee $4 + (i32.shr_u + (local.get $4) + (local.get $1) + ) + ) + (i32.const 1) + ) + (i32.const 1) + ) + ) + ) + (i32.shr_u + (local.get $4) + (local.get $1) + ) ) + (i32.const 2) ) ) ) - (block - (local.set $1 - (local.get $7) - ) - (local.set $0 - (local.get $10) - ) - (br $while-in20) - ) ) ) - (if - (i32.lt_u - (local.get $0) - (local.get $12) - ) - (call $_abort) + ) + (if + (local.get $4) + (then (block - (i32.store - (local.get $0) - (i32.const 0) + (local.set $1 + (local.get $3) ) - (local.set $11 - (local.get $1) + (local.set $3 + (local.get $4) ) + (br $__rjti$3) + ) + ) + (else + (local.set $4 + (local.get $0) ) ) ) - (block - (if - (i32.lt_u - (local.tee $10 - (i32.load offset=8 - (local.get $4) + (br $__rjto$3) + ) + (loop $while-in16 + (local.set $9 + (i32.lt_u + (local.tee $4 + (i32.sub + (i32.and + (i32.load offset=4 + (local.get $3) + ) + (i32.const -8) ) + (local.get $2) ) - (local.get $12) ) - (call $_abort) + (local.get $1) ) - (if - (i32.ne - (i32.load - (local.tee $7 - (i32.add - (local.get $10) - (i32.const 12) - ) - ) - ) - (local.get $4) - ) - (call $_abort) + ) + (local.set $1 + (select + (local.get $4) + (local.get $1) + (local.get $9) ) - (if - (i32.eq - (i32.load - (local.tee $1 - (i32.add - (local.get $0) - (i32.const 8) - ) - ) - ) - (local.get $4) + ) + (local.set $0 + (select + (local.get $3) + (local.get $0) + (local.get $9) + ) + ) + (if + (local.tee $4 + (i32.load offset=16 + (local.get $3) ) + ) + (then (block - (i32.store - (local.get $7) - (local.get $0) - ) - (i32.store - (local.get $1) - (local.get $10) - ) - (local.set $11 - (local.get $0) + (local.set $3 + (local.get $4) ) + (br $while-in16) + ) + ) + ) + (br_if $while-in16 + (local.tee $3 + (i32.load offset=20 + (local.get $3) ) - (call $_abort) ) ) + (local.set $3 + (local.get $1) + ) + (local.set $4 + (local.get $0) + ) ) ) - (block $do-once21 - (if - (local.get $9) - (block - (if - (i32.eq - (local.get $4) + (if + (local.get $4) + (then + (if + (i32.lt_u + (local.get $3) + (i32.sub (i32.load - (local.tee $0 - (i32.add - (i32.shl - (local.tee $1 - (i32.load offset=28 - (local.get $4) - ) - ) - (i32.const 2) - ) - (i32.const 480) - ) - ) + (i32.const 184) ) + (local.get $2) ) + ) + (then (block - (i32.store - (local.get $0) - (local.get $11) - ) (if - (i32.eqz - (local.get $11) - ) - (block - (i32.store - (i32.const 180) - (i32.and - (i32.load - (i32.const 180) - ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $1) - ) - (i32.const -1) - ) + (i32.lt_u + (local.get $4) + (local.tee $12 + (i32.load + (i32.const 192) ) ) - (br $do-once21) ) - ) - ) - (block - (if - (i32.lt_u - (local.get $9) - (i32.load - (i32.const 192) - ) + (then + (call $_abort) ) - (call $_abort) ) (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $9) - (i32.const 16) - ) + (i32.ge_u + (local.get $4) + (local.tee $6 + (i32.add + (local.get $4) + (local.get $2) ) ) - (local.get $4) - ) - (i32.store - (local.get $0) - (local.get $11) - ) - (i32.store offset=20 - (local.get $9) - (local.get $11) - ) - ) - (br_if $do-once21 - (i32.eqz - (local.get $11) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $11) - (local.tee $0 - (i32.load - (i32.const 192) - ) - ) - ) - (call $_abort) - ) - (i32.store offset=24 - (local.get $11) - (local.get $9) - ) - (if - (local.tee $1 - (i32.load offset=16 - (local.get $4) - ) - ) - (if - (i32.lt_u - (local.get $1) - (local.get $0) - ) - (call $_abort) - (block - (i32.store offset=16 - (local.get $11) - (local.get $1) - ) - (i32.store offset=24 - (local.get $1) - (local.get $11) - ) - ) - ) - ) - (if - (local.tee $0 - (i32.load offset=20 - (local.get $4) - ) - ) - (if - (i32.lt_u - (local.get $0) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (i32.store offset=20 - (local.get $11) - (local.get $0) - ) - (i32.store offset=24 - (local.get $0) - (local.get $11) ) - ) - ) - ) - ) - ) - ) - (block $do-once25 - (if - (i32.lt_u - (local.get $3) - (i32.const 16) - ) - (block - (i32.store offset=4 - (local.get $4) - (i32.or - (local.tee $0 - (i32.add - (local.get $3) - (local.get $2) + (then + (call $_abort) ) ) - (i32.const 3) - ) - ) - (i32.store - (local.tee $0 - (i32.add - (i32.add + (local.set $9 + (i32.load offset=24 (local.get $4) - (local.get $0) ) - (i32.const 4) - ) - ) - (i32.or - (i32.load - (local.get $0) ) - (i32.const 1) - ) - ) - ) - (block - (i32.store offset=4 - (local.get $4) - (i32.or - (local.get $2) - (i32.const 3) - ) - ) - (i32.store offset=4 - (local.get $6) - (i32.or - (local.get $3) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $6) - (local.get $3) - ) - (local.get $3) - ) - (local.set $0 - (i32.shr_u - (local.get $3) - (i32.const 3) - ) - ) - (if - (i32.lt_u - (local.get $3) - (i32.const 256) - ) - (block - (local.set $3 - (i32.add - (i32.shl - (local.get $0) - (i32.const 3) + (block $do-once17 + (if + (i32.eq + (local.tee $0 + (i32.load offset=12 + (local.get $4) + ) + ) + (local.get $4) ) - (i32.const 216) - ) - ) - (if - (i32.and - (local.tee $1 - (i32.load - (i32.const 176) + (then + (block + (if + (i32.eqz + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.get $4) + (i32.const 20) + ) + ) + ) + ) + ) + (then + (if + (i32.eqz + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.get $4) + (i32.const 16) + ) + ) + ) + ) + ) + (then + (block + (local.set $11 + (i32.const 0) + ) + (br $do-once17) + ) + ) + ) + ) + ) + (loop $while-in20 + (if + (local.tee $7 + (i32.load + (local.tee $10 + (i32.add + (local.get $1) + (i32.const 20) + ) + ) + ) + ) + (then + (block + (local.set $1 + (local.get $7) + ) + (local.set $0 + (local.get $10) + ) + (br $while-in20) + ) + ) + ) + (if + (local.tee $7 + (i32.load + (local.tee $10 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + ) + ) + (then + (block + (local.set $1 + (local.get $7) + ) + (local.set $0 + (local.get $10) + ) + (br $while-in20) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $0) + (local.get $12) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $0) + (i32.const 0) + ) + (local.set $11 + (local.get $1) + ) + ) + ) + ) ) ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $0) + (else + (block + (if + (i32.lt_u + (local.tee $10 + (i32.load offset=8 + (local.get $4) + ) + ) + (local.get $12) + ) + (then + (call $_abort) + ) + ) + (if + (i32.ne + (i32.load + (local.tee $7 + (i32.add + (local.get $10) + (i32.const 12) + ) + ) + ) + (local.get $4) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $1 + (i32.add + (local.get $0) + (i32.const 8) + ) + ) + ) + (local.get $4) + ) + (then + (block + (i32.store + (local.get $7) + (local.get $0) + ) + (i32.store + (local.get $1) + (local.get $10) + ) + (local.set $11 + (local.get $0) + ) + ) + ) + (else + (call $_abort) + ) + ) ) ) ) + ) + (block $do-once21 (if - (i32.lt_u - (local.tee $0 - (i32.load + (local.get $9) + (then + (block + (if + (i32.eq + (local.get $4) + (i32.load + (local.tee $0 + (i32.add + (i32.shl + (local.tee $1 + (i32.load offset=28 + (local.get $4) + ) + ) + (i32.const 2) + ) + (i32.const 480) + ) + ) + ) + ) + (then + (block + (i32.store + (local.get $0) + (local.get $11) + ) + (if + (i32.eqz + (local.get $11) + ) + (then + (block + (i32.store + (i32.const 180) + (i32.and + (i32.load + (i32.const 180) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $1) + ) + (i32.const -1) + ) + ) + ) + (br $do-once21) + ) + ) + ) + ) + ) + (else + (block + (if + (i32.lt_u + (local.get $9) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $9) + (i32.const 16) + ) + ) + ) + (local.get $4) + ) + (then + (i32.store + (local.get $0) + (local.get $11) + ) + ) + (else + (i32.store offset=20 + (local.get $9) + (local.get $11) + ) + ) + ) + (br_if $do-once21 + (i32.eqz + (local.get $11) + ) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $11) + (local.tee $0 + (i32.load + (i32.const 192) + ) + ) + ) + (then + (call $_abort) + ) + ) + (i32.store offset=24 + (local.get $11) + (local.get $9) + ) + (if (local.tee $1 + (i32.load offset=16 + (local.get $4) + ) + ) + (then + (if + (i32.lt_u + (local.get $1) + (local.get $0) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=16 + (local.get $11) + (local.get $1) + ) + (i32.store offset=24 + (local.get $1) + (local.get $11) + ) + ) + ) + ) + ) + ) + (if + (local.tee $0 + (i32.load offset=20 + (local.get $4) + ) + ) + (then + (if + (i32.lt_u + (local.get $0) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=20 + (local.get $11) + (local.get $0) + ) + (i32.store offset=24 + (local.get $0) + (local.get $11) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (block $do-once25 + (if + (i32.lt_u + (local.get $3) + (i32.const 16) + ) + (then + (block + (i32.store offset=4 + (local.get $4) + (i32.or + (local.tee $0 + (i32.add + (local.get $3) + (local.get $2) + ) + ) + (i32.const 3) + ) + ) + (i32.store + (local.tee $0 (i32.add - (local.get $3) - (i32.const 8) + (i32.add + (local.get $4) + (local.get $0) + ) + (i32.const 4) + ) + ) + (i32.or + (i32.load + (local.get $0) + ) + (i32.const 1) + ) + ) + ) + ) + (else + (block + (i32.store offset=4 + (local.get $4) + (i32.or + (local.get $2) + (i32.const 3) + ) + ) + (i32.store offset=4 + (local.get $6) + (i32.or + (local.get $3) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (local.get $6) + (local.get $3) + ) + (local.get $3) + ) + (local.set $0 + (i32.shr_u + (local.get $3) + (i32.const 3) + ) + ) + (if + (i32.lt_u + (local.get $3) + (i32.const 256) + ) + (then + (block + (local.set $3 + (i32.add + (i32.shl + (local.get $0) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (if + (i32.and + (local.tee $1 + (i32.load + (i32.const 176) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $0) + ) + ) + ) + (then + (if + (i32.lt_u + (local.tee $0 + (i32.load + (local.tee $1 + (i32.add + (local.get $3) + (i32.const 8) + ) + ) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (local.set $13 + (local.get $1) + ) + (local.set $5 + (local.get $0) + ) + ) + ) + ) + ) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (local.set $13 + (i32.add + (local.get $3) + (i32.const 8) + ) + ) + (local.set $5 + (local.get $3) + ) + ) + ) + ) + (i32.store + (local.get $13) + (local.get $6) + ) + (i32.store offset=12 + (local.get $5) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $5) + ) + (i32.store offset=12 + (local.get $6) + (local.get $3) + ) + (br $do-once25) ) ) ) - ) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (local.set $13 - (local.get $1) - ) - (local.set $5 - (local.get $0) - ) - ) - ) - (block - (i32.store - (i32.const 176) - (i32.or - (local.get $1) - (local.get $0) - ) - ) - (local.set $13 - (i32.add - (local.get $3) - (i32.const 8) - ) - ) - (local.set $5 - (local.get $3) - ) - ) - ) - (i32.store - (local.get $13) - (local.get $6) - ) - (i32.store offset=12 - (local.get $5) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $5) - ) - (i32.store offset=12 - (local.get $6) - (local.get $3) - ) - (br $do-once25) - ) - ) - (local.set $2 - (i32.add - (i32.shl - (local.tee $7 - (if (result i32) - (local.tee $0 - (i32.shr_u - (local.get $3) - (i32.const 8) - ) - ) - (if (result i32) - (i32.gt_u - (local.get $3) - (i32.const 16777215) - ) - (i32.const 31) - (i32.or - (i32.and - (i32.shr_u - (local.get $3) - (i32.add - (local.tee $0 - (i32.add - (i32.sub - (i32.const 14) - (i32.or + (local.set $2 + (i32.add + (i32.shl + (local.tee $7 + (if (result i32) + (local.tee $0 + (i32.shr_u + (local.get $3) + (i32.const 8) + ) + ) + (then + (if (result i32) + (i32.gt_u + (local.get $3) + (i32.const 16777215) + ) + (then + (i32.const 31) + ) + (else (i32.or - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $0) - (local.tee $2 - (i32.and - (i32.shr_u - (i32.add - (local.get $0) - (i32.const 1048320) + (i32.and + (i32.shr_u + (local.get $3) + (i32.add + (local.tee $0 + (i32.add + (i32.sub + (i32.const 14) + (i32.or + (i32.or + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $0) + (local.tee $2 + (i32.and + (i32.shr_u + (i32.add + (local.get $0) + (i32.const 1048320) + ) + (i32.const 16) + ) + (i32.const 8) + ) + ) + ) + ) + (i32.const 520192) + ) + (i32.const 16) + ) + (i32.const 4) ) - (i32.const 16) ) - (i32.const 8) + (local.get $2) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $1) + (local.get $0) + ) + ) + (i32.const 245760) + ) + (i32.const 16) + ) + (i32.const 2) + ) ) ) ) + (i32.shr_u + (i32.shl + (local.get $1) + (local.get $0) + ) + (i32.const 15) + ) ) - (i32.const 520192) ) - (i32.const 16) + (i32.const 7) ) - (i32.const 4) ) + (i32.const 1) + ) + (i32.shl + (local.get $0) + (i32.const 1) ) - (local.get $2) ) - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $1) - (local.get $0) - ) - ) - (i32.const 245760) - ) - (i32.const 16) - ) - (i32.const 2) + ) + ) + ) + (else + (i32.const 0) + ) + ) + ) + (i32.const 2) + ) + (i32.const 480) + ) + ) + (i32.store offset=28 + (local.get $6) + (local.get $7) + ) + (i32.store offset=4 + (local.tee $0 + (i32.add + (local.get $6) + (i32.const 16) + ) + ) + (i32.const 0) + ) + (i32.store + (local.get $0) + (i32.const 0) + ) + (if + (i32.eqz + (i32.and + (local.tee $1 + (i32.load + (i32.const 180) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $7) + ) + ) + ) + ) + (then + (block + (i32.store + (i32.const 180) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (i32.store + (local.get $2) + (local.get $6) + ) + (i32.store offset=24 + (local.get $6) + (local.get $2) + ) + (i32.store offset=12 + (local.get $6) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $6) + ) + (br $do-once25) + ) + ) + ) + (local.set $7 + (i32.shl + (local.get $3) + (select + (i32.const 0) + (i32.sub + (i32.const 25) + (i32.shr_u + (local.get $7) + (i32.const 1) + ) + ) + (i32.eq + (local.get $7) + (i32.const 31) + ) + ) + ) + ) + (local.set $0 + (i32.load + (local.get $2) + ) + ) + (block $__rjto$1 + (block $__rjti$1 + (loop $while-in28 + (br_if $__rjti$1 + (i32.eq + (i32.and + (i32.load offset=4 + (local.get $0) + ) + (i32.const -8) + ) + (local.get $3) + ) + ) + (local.set $2 + (i32.shl + (local.get $7) + (i32.const 1) + ) + ) + (if + (local.tee $1 + (i32.load + (local.tee $7 + (i32.add + (i32.add + (local.get $0) + (i32.const 16) + ) + (i32.shl + (i32.shr_u + (local.get $7) + (i32.const 31) ) + (i32.const 2) ) ) ) - (i32.shr_u - (i32.shl - (local.get $1) + ) + ) + (then + (block + (local.set $7 + (local.get $2) + ) + (local.set $0 + (local.get $1) + ) + (br $while-in28) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $7) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $7) + (local.get $6) + ) + (i32.store offset=24 + (local.get $6) + (local.get $0) + ) + (i32.store offset=12 + (local.get $6) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $6) + ) + (br $do-once25) + ) + ) + ) + (br $__rjto$1) + ) + (if + (i32.and + (i32.ge_u + (local.tee $2 + (i32.load + (local.tee $3 + (i32.add (local.get $0) + (i32.const 8) ) - (i32.const 15) ) ) ) - (i32.const 7) + (local.tee $1 + (i32.load + (i32.const 192) + ) + ) + ) + (i32.ge_u + (local.get $0) + (local.get $1) ) ) - (i32.const 1) - ) - (i32.shl - (local.get $0) - (i32.const 1) - ) - ) - ) - (i32.const 0) - ) - ) - (i32.const 2) - ) - (i32.const 480) - ) - ) - (i32.store offset=28 - (local.get $6) - (local.get $7) - ) - (i32.store offset=4 - (local.tee $0 - (i32.add - (local.get $6) - (i32.const 16) - ) - ) - (i32.const 0) - ) - (i32.store - (local.get $0) - (i32.const 0) - ) - (if - (i32.eqz - (i32.and - (local.tee $1 - (i32.load - (i32.const 180) - ) - ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $7) - ) - ) - ) - ) - (block - (i32.store - (i32.const 180) - (i32.or - (local.get $1) - (local.get $0) - ) - ) - (i32.store - (local.get $2) - (local.get $6) - ) - (i32.store offset=24 - (local.get $6) - (local.get $2) - ) - (i32.store offset=12 - (local.get $6) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $6) - ) - (br $do-once25) - ) - ) - (local.set $7 - (i32.shl - (local.get $3) - (select - (i32.const 0) - (i32.sub - (i32.const 25) - (i32.shr_u - (local.get $7) - (i32.const 1) - ) - ) - (i32.eq - (local.get $7) - (i32.const 31) - ) - ) - ) - ) - (local.set $0 - (i32.load - (local.get $2) - ) - ) - (block $__rjto$1 - (block $__rjti$1 - (loop $while-in28 - (br_if $__rjti$1 - (i32.eq - (i32.and - (i32.load offset=4 - (local.get $0) - ) - (i32.const -8) - ) - (local.get $3) - ) - ) - (local.set $2 - (i32.shl - (local.get $7) - (i32.const 1) - ) - ) - (if - (local.tee $1 - (i32.load - (local.tee $7 - (i32.add - (i32.add - (local.get $0) - (i32.const 16) - ) - (i32.shl - (i32.shr_u - (local.get $7) - (i32.const 31) + (then + (block + (i32.store offset=12 + (local.get $2) + (local.get $6) + ) + (i32.store + (local.get $3) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $2) + ) + (i32.store offset=12 + (local.get $6) + (local.get $0) + ) + (i32.store offset=24 + (local.get $6) + (i32.const 0) + ) ) - (i32.const 2) + ) + (else + (call $_abort) ) ) ) ) ) - (block - (local.set $7 - (local.get $2) - ) - (local.set $0 - (local.get $1) - ) - (br $while-in28) - ) ) ) - (if - (i32.lt_u - (local.get $7) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (i32.store - (local.get $7) - (local.get $6) - ) - (i32.store offset=24 - (local.get $6) - (local.get $0) - ) - (i32.store offset=12 - (local.get $6) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $6) - ) - (br $do-once25) + (return + (i32.add + (local.get $4) + (i32.const 8) ) ) - (br $__rjto$1) ) - (if - (i32.and - (i32.ge_u - (local.tee $2 - (i32.load - (local.tee $3 - (i32.add - (local.get $0) - (i32.const 8) - ) - ) - ) - ) - (local.tee $1 - (i32.load - (i32.const 192) - ) - ) - ) - (i32.ge_u - (local.get $0) - (local.get $1) - ) - ) - (block - (i32.store offset=12 - (local.get $2) - (local.get $6) - ) - (i32.store - (local.get $3) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $2) - ) - (i32.store offset=12 - (local.get $6) - (local.get $0) - ) - (i32.store offset=24 - (local.get $6) - (i32.const 0) - ) - ) - (call $_abort) + ) + (else + (local.set $0 + (local.get $2) ) ) ) ) + (else + (local.set $0 + (local.get $2) + ) + ) ) - (return - (i32.add - (local.get $4) - (i32.const 8) - ) - ) ) + ) + (else (local.set $0 (local.get $2) ) ) - (local.set $0 - (local.get $2) - ) ) ) - (local.set $0 - (local.get $2) - ) ) ) ) @@ -23425,97 +24679,103 @@ ) (local.get $0) ) - (block - (local.set $2 - (i32.load - (i32.const 196) - ) - ) - (if - (i32.gt_u - (local.tee $3 - (i32.sub - (local.get $1) - (local.get $0) - ) + (then + (block + (local.set $2 + (i32.load + (i32.const 196) ) - (i32.const 15) ) - (block - (i32.store - (i32.const 196) - (local.tee $1 - (i32.add - (local.get $2) + (if + (i32.gt_u + (local.tee $3 + (i32.sub + (local.get $1) (local.get $0) ) ) + (i32.const 15) ) - (i32.store - (i32.const 184) - (local.get $3) - ) - (i32.store offset=4 - (local.get $1) - (i32.or - (local.get $3) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $1) - (local.get $3) - ) - (local.get $3) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $0) - (i32.const 3) - ) - ) - ) - (block - (i32.store - (i32.const 184) - (i32.const 0) - ) - (i32.store - (i32.const 196) - (i32.const 0) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $1) - (i32.const 3) - ) - ) - (i32.store - (local.tee $0 - (i32.add + (then + (block + (i32.store + (i32.const 196) + (local.tee $1 + (i32.add + (local.get $2) + (local.get $0) + ) + ) + ) + (i32.store + (i32.const 184) + (local.get $3) + ) + (i32.store offset=4 + (local.get $1) + (i32.or + (local.get $3) + (i32.const 1) + ) + ) + (i32.store (i32.add - (local.get $2) (local.get $1) + (local.get $3) + ) + (local.get $3) + ) + (i32.store offset=4 + (local.get $2) + (i32.or + (local.get $0) + (i32.const 3) ) - (i32.const 4) ) ) - (i32.or - (i32.load - (local.get $0) + ) + (else + (block + (i32.store + (i32.const 184) + (i32.const 0) + ) + (i32.store + (i32.const 196) + (i32.const 0) + ) + (i32.store offset=4 + (local.get $2) + (i32.or + (local.get $1) + (i32.const 3) + ) + ) + (i32.store + (local.tee $0 + (i32.add + (i32.add + (local.get $2) + (local.get $1) + ) + (i32.const 4) + ) + ) + (i32.or + (i32.load + (local.get $0) + ) + (i32.const 1) + ) ) - (i32.const 1) ) ) ) - ) - (return - (i32.add - (local.get $2) - (i32.const 8) + (return + (i32.add + (local.get $2) + (i32.const 8) + ) ) ) ) @@ -23536,54 +24796,60 @@ (i32.const 648) ) ) - (if - (i32.and - (i32.add - (local.tee $1 - (call $_sysconf - (i32.const 30) + (then + (if + (i32.and + (i32.add + (local.tee $1 + (call $_sysconf + (i32.const 30) + ) ) + (i32.const -1) ) - (i32.const -1) - ) - (local.get $1) - ) - (call $_abort) - (block - (i32.store - (i32.const 656) (local.get $1) ) - (i32.store - (i32.const 652) - (local.get $1) - ) - (i32.store - (i32.const 660) - (i32.const -1) - ) - (i32.store - (i32.const 664) - (i32.const -1) - ) - (i32.store - (i32.const 668) - (i32.const 0) - ) - (i32.store - (i32.const 620) - (i32.const 0) + (then + (call $_abort) ) - (i32.store - (i32.const 648) - (i32.xor - (i32.and - (call $_time - (i32.const 0) + (else + (block + (i32.store + (i32.const 656) + (local.get $1) + ) + (i32.store + (i32.const 652) + (local.get $1) + ) + (i32.store + (i32.const 660) + (i32.const -1) + ) + (i32.store + (i32.const 664) + (i32.const -1) + ) + (i32.store + (i32.const 668) + (i32.const 0) + ) + (i32.store + (i32.const 620) + (i32.const 0) + ) + (i32.store + (i32.const 648) + (i32.xor + (i32.and + (call $_time + (i32.const 0) + ) + (i32.const -16) + ) + (i32.const 1431655768) ) - (i32.const -16) ) - (i32.const 1431655768) ) ) ) @@ -23618,8 +24884,10 @@ ) (local.get $0) ) - (return - (i32.const 0) + (then + (return + (i32.const 0) + ) ) ) (if @@ -23628,29 +24896,33 @@ (i32.const 616) ) ) - (if - (i32.or - (i32.le_u - (local.tee $1 - (i32.add - (local.tee $3 - (i32.load - (i32.const 608) + (then + (if + (i32.or + (i32.le_u + (local.tee $1 + (i32.add + (local.tee $3 + (i32.load + (i32.const 608) + ) ) + (local.get $5) ) - (local.get $5) ) + (local.get $3) + ) + (i32.gt_u + (local.get $1) + (local.get $2) ) - (local.get $3) ) - (i32.gt_u - (local.get $1) - (local.get $2) + (then + (return + (i32.const 0) + ) ) ) - (return - (i32.const 0) - ) ) ) (local.set $11 @@ -23669,317 +24941,353 @@ ) (i32.const 4) ) - ) - (block - (block $label$break$L279 - (block $__rjti$5 - (block $__rjti$4 - (br_if $__rjti$4 - (i32.eqz - (local.tee $4 - (i32.load - (i32.const 200) + ) + (then + (block + (block $label$break$L279 + (block $__rjti$5 + (block $__rjti$4 + (br_if $__rjti$4 + (i32.eqz + (local.tee $4 + (i32.load + (i32.const 200) + ) ) ) ) - ) - (local.set $1 - (i32.const 624) - ) - (loop $while-in34 - (block $while-out33 - (if - (i32.le_u - (local.tee $3 - (i32.load - (local.get $1) - ) - ) - (local.get $4) - ) + (local.set $1 + (i32.const 624) + ) + (loop $while-in34 + (block $while-out33 (if - (i32.gt_u - (i32.add - (local.get $3) + (i32.le_u + (local.tee $3 (i32.load - (local.tee $2 - (i32.add + (local.get $1) + ) + ) + (local.get $4) + ) + (then + (if + (i32.gt_u + (i32.add + (local.get $3) + (i32.load + (local.tee $2 + (i32.add + (local.get $1) + (i32.const 4) + ) + ) + ) + ) + (local.get $4) + ) + (then + (block + (local.set $4 (local.get $1) - (i32.const 4) ) + (br $while-out33) ) ) ) - (local.get $4) ) - (block - (local.set $4 + ) + (br_if $while-in34 + (local.tee $1 + (i32.load offset=8 (local.get $1) ) - (br $while-out33) ) ) + (br $__rjti$4) ) - (br_if $while-in34 - (local.tee $1 - (i32.load offset=8 - (local.get $1) + ) + (if + (i32.lt_u + (local.tee $3 + (i32.and + (i32.sub + (local.get $6) + (i32.load + (i32.const 188) + ) + ) + (local.get $9) + ) + ) + (i32.const 2147483647) + ) + (then + (if + (i32.eq + (local.tee $1 + (call $_sbrk + (local.get $3) + ) + ) + (i32.add + (i32.load + (local.get $4) + ) + (i32.load + (local.get $2) + ) + ) + ) + (then + (br_if $__rjti$13 + (i32.ne + (local.get $1) + (i32.const -1) + ) + ) + ) + (else + (block + (local.set $2 + (local.get $1) + ) + (br $__rjti$5) + ) ) ) ) - (br $__rjti$4) ) + (br $label$break$L279) ) (if - (i32.lt_u - (local.tee $3 - (i32.and - (i32.sub - (local.get $6) - (i32.load - (i32.const 188) - ) - ) - (local.get $9) + (i32.ne + (local.tee $1 + (call $_sbrk + (i32.const 0) ) ) - (i32.const 2147483647) + (i32.const -1) ) - (if - (i32.eq - (local.tee $1 - (call $_sbrk + (then + (block + (local.set $3 + (if (result i32) + (i32.and + (local.tee $2 + (i32.add + (local.tee $4 + (i32.load + (i32.const 652) + ) + ) + (i32.const -1) + ) + ) + (local.tee $3 + (local.get $1) + ) + ) + (then + (i32.add + (i32.sub + (local.get $5) + (local.get $3) + ) + (i32.and + (i32.add + (local.get $2) + (local.get $3) + ) + (i32.sub + (i32.const 0) + (local.get $4) + ) + ) + ) + ) + (else + (local.get $5) + ) + ) + ) + (local.set $9 + (i32.add + (local.tee $4 + (i32.load + (i32.const 608) + ) + ) (local.get $3) ) ) - (i32.add - (i32.load - (local.get $4) + (if + (i32.and + (i32.gt_u + (local.get $3) + (local.get $0) + ) + (i32.lt_u + (local.get $3) + (i32.const 2147483647) + ) ) - (i32.load - (local.get $2) + (then + (block + (if + (local.tee $2 + (i32.load + (i32.const 616) + ) + ) + (then + (br_if $label$break$L279 + (i32.or + (i32.le_u + (local.get $9) + (local.get $4) + ) + (i32.gt_u + (local.get $9) + (local.get $2) + ) + ) + ) + ) + ) + (br_if $__rjti$13 + (i32.eq + (local.tee $2 + (call $_sbrk + (local.get $3) + ) + ) + (local.get $1) + ) + ) + (br $__rjti$5) + ) ) ) ) - (br_if $__rjti$13 - (i32.ne - (local.get $1) - (i32.const -1) - ) - ) - (block - (local.set $2 - (local.get $1) - ) - (br $__rjti$5) - ) ) ) (br $label$break$L279) ) + (local.set $1 + (local.get $3) + ) + (local.set $4 + (i32.sub + (i32.const 0) + (local.get $1) + ) + ) (if - (i32.ne - (local.tee $1 - (call $_sbrk - (i32.const 0) + (i32.and + (i32.gt_u + (local.get $11) + (local.get $1) + ) + (i32.and + (i32.lt_u + (local.get $1) + (i32.const 2147483647) + ) + (i32.ne + (local.get $2) + (i32.const -1) ) ) - (i32.const -1) ) - (block - (local.set $3 - (if (result i32) - (i32.and - (local.tee $2 - (i32.add - (local.tee $4 - (i32.load - (i32.const 652) - ) - ) - (i32.const -1) - ) - ) - (local.tee $3 - (local.get $1) - ) - ) - (i32.add - (i32.sub - (local.get $5) - (local.get $3) - ) + (then + (if + (i32.lt_u + (local.tee $3 (i32.and (i32.add - (local.get $2) - (local.get $3) + (i32.sub + (local.get $8) + (local.get $1) + ) + (local.tee $3 + (i32.load + (i32.const 656) + ) + ) ) (i32.sub (i32.const 0) - (local.get $4) + (local.get $3) ) ) ) - (local.get $5) - ) - ) - (local.set $9 - (i32.add - (local.tee $4 - (i32.load - (i32.const 608) - ) - ) - (local.get $3) - ) - ) - (if - (i32.and - (i32.gt_u - (local.get $3) - (local.get $0) - ) - (i32.lt_u - (local.get $3) - (i32.const 2147483647) - ) + (i32.const 2147483647) ) - (block + (then (if - (local.tee $2 - (i32.load - (i32.const 616) + (i32.eq + (call $_sbrk + (local.get $3) ) + (i32.const -1) ) - (br_if $label$break$L279 - (i32.or - (i32.le_u - (local.get $9) - (local.get $4) - ) - (i32.gt_u - (local.get $9) - (local.get $2) + (then + (block + (drop + (call $_sbrk + (local.get $4) + ) ) + (br $label$break$L279) ) ) - ) - (br_if $__rjti$13 - (i32.eq - (local.tee $2 - (call $_sbrk + (else + (local.set $3 + (i32.add (local.get $3) + (local.get $1) ) ) - (local.get $1) ) ) - (br $__rjti$5) + ) + (else + (local.set $3 + (local.get $1) + ) ) ) ) - ) - (br $label$break$L279) - ) - (local.set $1 - (local.get $3) - ) - (local.set $4 - (i32.sub - (i32.const 0) - (local.get $1) - ) - ) - (if - (i32.and - (i32.gt_u - (local.get $11) - (local.get $1) - ) - (i32.and - (i32.lt_u + (else + (local.set $3 (local.get $1) - (i32.const 2147483647) - ) - (i32.ne - (local.get $2) - (i32.const -1) ) ) ) (if - (i32.lt_u - (local.tee $3 - (i32.and - (i32.add - (i32.sub - (local.get $8) - (local.get $1) - ) - (local.tee $3 - (i32.load - (i32.const 656) - ) - ) - ) - (i32.sub - (i32.const 0) - (local.get $3) - ) - ) - ) - (i32.const 2147483647) + (i32.ne + (local.get $2) + (i32.const -1) ) - (if - (i32.eq - (call $_sbrk - (local.get $3) - ) - (i32.const -1) - ) + (then (block - (drop - (call $_sbrk - (local.get $4) - ) - ) - (br $label$break$L279) - ) - (local.set $3 - (i32.add - (local.get $3) - (local.get $1) + (local.set $1 + (local.get $2) ) + (br $__rjti$13) ) ) - (local.set $3 - (local.get $1) - ) - ) - (local.set $3 - (local.get $1) ) ) - (if - (i32.ne - (local.get $2) - (i32.const -1) - ) - (block - (local.set $1 - (local.get $2) + (i32.store + (i32.const 620) + (i32.or + (i32.load + (i32.const 620) ) - (br $__rjti$13) - ) - ) - ) - (i32.store - (i32.const 620) - (i32.or - (i32.load - (i32.const 620) + (i32.const 4) ) - (i32.const 4) ) ) ) @@ -23989,42 +25297,46 @@ (local.get $5) (i32.const 2147483647) ) - (if - (i32.and - (i32.lt_u - (local.tee $1 - (call $_sbrk - (local.get $5) + (then + (if + (i32.and + (i32.lt_u + (local.tee $1 + (call $_sbrk + (local.get $5) + ) ) - ) - (local.tee $3 - (call $_sbrk - (i32.const 0) + (local.tee $3 + (call $_sbrk + (i32.const 0) + ) ) ) - ) - (i32.and - (i32.ne - (local.get $1) - (i32.const -1) - ) - (i32.ne - (local.get $3) - (i32.const -1) - ) - ) - ) - (br_if $__rjti$13 - (i32.gt_u - (local.tee $3 - (i32.sub - (local.get $3) + (i32.and + (i32.ne (local.get $1) + (i32.const -1) + ) + (i32.ne + (local.get $3) + (i32.const -1) ) ) - (i32.add - (local.get $0) - (i32.const 40) + ) + (then + (br_if $__rjti$13 + (i32.gt_u + (local.tee $3 + (i32.sub + (local.get $3) + (local.get $1) + ) + ) + (i32.add + (local.get $0) + (i32.const 40) + ) + ) ) ) ) @@ -24050,9 +25362,11 @@ (i32.const 612) ) ) - (i32.store - (i32.const 612) - (local.get $2) + (then + (i32.store + (i32.const 612) + (local.get $2) + ) ) ) (block $do-once40 @@ -24062,2134 +25376,2286 @@ (i32.const 200) ) ) - (block - (local.set $2 - (i32.const 624) - ) - (block $__rjto$10 - (block $__rjti$10 - (loop $while-in45 - (br_if $__rjti$10 - (i32.eq - (local.get $1) - (i32.add - (local.tee $11 - (i32.load - (local.get $2) + (then + (block + (local.set $2 + (i32.const 624) + ) + (block $__rjto$10 + (block $__rjti$10 + (loop $while-in45 + (br_if $__rjti$10 + (i32.eq + (local.get $1) + (i32.add + (local.tee $11 + (i32.load + (local.get $2) + ) ) - ) - (local.tee $5 - (i32.load - (local.tee $4 - (i32.add - (local.get $2) - (i32.const 4) + (local.tee $5 + (i32.load + (local.tee $4 + (i32.add + (local.get $2) + (i32.const 4) + ) ) ) ) ) ) ) - ) - (br_if $while-in45 - (local.tee $2 - (i32.load offset=8 - (local.get $2) + (br_if $while-in45 + (local.tee $2 + (i32.load offset=8 + (local.get $2) + ) ) ) ) - ) - (br $__rjto$10) - ) - (if - (i32.eqz - (i32.and - (i32.load offset=12 - (local.get $2) - ) - (i32.const 8) - ) + (br $__rjto$10) ) (if - (i32.and - (i32.lt_u - (local.get $6) - (local.get $1) - ) - (i32.ge_u - (local.get $6) - (local.get $11) + (i32.eqz + (i32.and + (i32.load offset=12 + (local.get $2) + ) + (i32.const 8) ) ) - (block - (i32.store - (local.get $4) - (i32.add - (local.get $5) - (local.get $3) + (then + (if + (i32.and + (i32.lt_u + (local.get $6) + (local.get $1) + ) + (i32.ge_u + (local.get $6) + (local.get $11) + ) ) - ) - (local.set $2 - (i32.add - (local.get $6) - (local.tee $1 - (select - (i32.and - (i32.sub - (i32.const 0) - (local.tee $1 - (i32.add - (local.get $6) - (i32.const 8) + (then + (block + (i32.store + (local.get $4) + (i32.add + (local.get $5) + (local.get $3) + ) + ) + (local.set $2 + (i32.add + (local.get $6) + (local.tee $1 + (select + (i32.and + (i32.sub + (i32.const 0) + (local.tee $1 + (i32.add + (local.get $6) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 0) + (i32.and + (local.get $1) + (i32.const 7) ) ) ) - (i32.const 7) ) - (i32.const 0) - (i32.and + ) + (local.set $1 + (i32.add + (i32.sub + (local.get $3) + (local.get $1) + ) + (i32.load + (i32.const 188) + ) + ) + ) + (i32.store + (i32.const 200) + (local.get $2) + ) + (i32.store + (i32.const 188) + (local.get $1) + ) + (i32.store offset=4 + (local.get $2) + (i32.or (local.get $1) - (i32.const 7) + (i32.const 1) ) ) + (i32.store offset=4 + (i32.add + (local.get $2) + (local.get $1) + ) + (i32.const 40) + ) + (i32.store + (i32.const 204) + (i32.load + (i32.const 664) + ) + ) + (br $do-once40) ) ) ) - (local.set $1 - (i32.add - (i32.sub - (local.get $3) - (local.get $1) - ) - (i32.load - (i32.const 188) - ) - ) - ) - (i32.store - (i32.const 200) - (local.get $2) + ) + ) + ) + (if + (i32.lt_u + (local.get $1) + (local.tee $4 + (i32.load + (i32.const 192) ) + ) + ) + (then + (block (i32.store - (i32.const 188) + (i32.const 192) (local.get $1) ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $1) - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.add - (local.get $2) - (local.get $1) - ) - (i32.const 40) - ) - (i32.store - (i32.const 204) - (i32.load - (i32.const 664) - ) + (local.set $4 + (local.get $1) ) - (br $do-once40) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $1) - (local.tee $4 - (i32.load - (i32.const 192) ) ) ) - (block - (i32.store - (i32.const 192) - (local.get $1) - ) - (local.set $4 + (local.set $11 + (i32.add (local.get $1) + (local.get $3) ) ) - ) - (local.set $11 - (i32.add - (local.get $1) - (local.get $3) - ) - ) - (local.set $2 - (i32.const 624) - ) - (block $__rjto$11 - (block $__rjti$11 - (loop $while-in47 - (if - (i32.eq - (i32.load - (local.get $2) - ) - (local.get $11) - ) - (block - (local.set $5 - (local.get $2) - ) - (br $__rjti$11) - ) - ) - (br_if $while-in47 - (local.tee $2 - (i32.load offset=8 - (local.get $2) - ) - ) - ) - (local.set $4 - (i32.const 624) - ) - ) - (br $__rjto$11) + (local.set $2 + (i32.const 624) ) - (if - (i32.and - (i32.load offset=12 - (local.get $2) - ) - (i32.const 8) - ) - (local.set $4 - (i32.const 624) - ) - (block - (i32.store - (local.get $5) - (local.get $1) - ) - (i32.store - (local.tee $2 - (i32.add - (local.get $2) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (local.get $2) + (block $__rjto$11 + (block $__rjti$11 + (loop $while-in47 + (if + (i32.eq + (i32.load + (local.get $2) + ) + (local.get $11) ) - (local.get $3) - ) - ) - (local.set $8 - (i32.add - (local.tee $9 - (i32.add - (local.get $1) - (select - (i32.and - (i32.sub - (i32.const 0) - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 0) - (i32.and - (local.get $1) - (i32.const 7) - ) + (then + (block + (local.set $5 + (local.get $2) ) + (br $__rjti$11) ) ) - (local.get $0) ) - ) - (local.set $7 - (i32.sub - (i32.sub - (local.tee $5 - (i32.add - (local.get $11) - (select - (i32.and - (i32.sub - (i32.const 0) - (local.tee $1 - (i32.add - (local.get $11) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 0) - (i32.and - (local.get $1) - (i32.const 7) - ) - ) - ) + (br_if $while-in47 + (local.tee $2 + (i32.load offset=8 + (local.get $2) ) - (local.get $9) ) - (local.get $0) + ) + (local.set $4 + (i32.const 624) ) ) - (i32.store offset=4 - (local.get $9) - (i32.or - (local.get $0) - (i32.const 3) + (br $__rjto$11) + ) + (if + (i32.and + (i32.load offset=12 + (local.get $2) ) + (i32.const 8) ) - (block $do-once48 - (if - (i32.eq + (then + (local.set $4 + (i32.const 624) + ) + ) + (else + (block + (i32.store (local.get $5) - (local.get $6) + (local.get $1) ) - (block - (i32.store - (i32.const 188) - (local.tee $0 + (i32.store + (local.tee $2 + (i32.add + (local.get $2) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (local.get $2) + ) + (local.get $3) + ) + ) + (local.set $8 + (i32.add + (local.tee $9 (i32.add - (i32.load - (i32.const 188) + (local.get $1) + (select + (i32.and + (i32.sub + (i32.const 0) + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 0) + (i32.and + (local.get $1) + (i32.const 7) + ) ) - (local.get $7) ) ) + (local.get $0) ) - (i32.store - (i32.const 200) - (local.get $8) - ) - (i32.store offset=4 - (local.get $8) - (i32.or - (local.get $0) - (i32.const 1) + ) + (local.set $7 + (i32.sub + (i32.sub + (local.tee $5 + (i32.add + (local.get $11) + (select + (i32.and + (i32.sub + (i32.const 0) + (local.tee $1 + (i32.add + (local.get $11) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 0) + (i32.and + (local.get $1) + (i32.const 7) + ) + ) + ) + ) + (local.get $9) ) + (local.get $0) ) ) - (block + (i32.store offset=4 + (local.get $9) + (i32.or + (local.get $0) + (i32.const 3) + ) + ) + (block $do-once48 (if (i32.eq (local.get $5) - (i32.load - (i32.const 196) - ) + (local.get $6) ) - (block - (i32.store - (i32.const 184) - (local.tee $0 - (i32.add - (i32.load - (i32.const 184) + (then + (block + (i32.store + (i32.const 188) + (local.tee $0 + (i32.add + (i32.load + (i32.const 188) + ) + (local.get $7) ) - (local.get $7) ) ) - ) - (i32.store - (i32.const 196) - (local.get $8) - ) - (i32.store offset=4 - (local.get $8) - (i32.or - (local.get $0) - (i32.const 1) + (i32.store + (i32.const 200) + (local.get $8) ) - ) - (i32.store - (i32.add + (i32.store offset=4 (local.get $8) - (local.get $0) + (i32.or + (local.get $0) + (i32.const 1) + ) ) - (local.get $0) ) - (br $do-once48) ) - ) - (i32.store - (local.tee $0 - (i32.add - (local.tee $0 - (if (result i32) - (i32.eq - (i32.and + (else + (block + (if + (i32.eq + (local.get $5) + (i32.load + (i32.const 196) + ) + ) + (then + (block + (i32.store + (i32.const 184) (local.tee $0 - (i32.load offset=4 - (local.get $5) + (i32.add + (i32.load + (i32.const 184) + ) + (local.get $7) ) ) - (i32.const 3) ) - (i32.const 1) - ) - (block (result i32) - (local.set $11 - (i32.and + (i32.store + (i32.const 196) + (local.get $8) + ) + (i32.store offset=4 + (local.get $8) + (i32.or (local.get $0) - (i32.const -8) + (i32.const 1) ) ) - (local.set $1 - (i32.shr_u + (i32.store + (i32.add + (local.get $8) (local.get $0) - (i32.const 3) ) + (local.get $0) ) - (block $label$break$L331 - (if - (i32.lt_u - (local.get $0) - (i32.const 256) - ) - (block - (local.set $2 - (i32.load offset=12 - (local.get $5) - ) - ) - (block $do-once51 - (if - (i32.ne - (local.tee $3 - (i32.load offset=8 - (local.get $5) - ) - ) - (local.tee $0 - (i32.add - (i32.shl - (local.get $1) - (i32.const 3) - ) - (i32.const 216) - ) - ) - ) - (block - (if - (i32.lt_u - (local.get $3) - (local.get $4) - ) - (call $_abort) - ) - (br_if $do-once51 - (i32.eq - (i32.load offset=12 - (local.get $3) - ) - (local.get $5) - ) - ) - (call $_abort) + (br $do-once48) + ) + ) + ) + (i32.store + (local.tee $0 + (i32.add + (local.tee $0 + (if (result i32) + (i32.eq + (i32.and + (local.tee $0 + (i32.load offset=4 + (local.get $5) ) ) + (i32.const 3) ) - (if - (i32.eq - (local.get $2) - (local.get $3) - ) - (block - (i32.store - (i32.const 176) - (i32.and - (i32.load - (i32.const 176) - ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $1) - ) - (i32.const -1) - ) - ) + (i32.const 1) + ) + (then + (block (result i32) + (local.set $11 + (i32.and + (local.get $0) + (i32.const -8) ) - (br $label$break$L331) ) - ) - (block $do-once53 - (if - (i32.eq - (local.get $2) + (local.set $1 + (i32.shr_u (local.get $0) + (i32.const 3) ) - (local.set $15 - (i32.add - (local.get $2) - (i32.const 8) - ) - ) - (block - (if - (i32.lt_u - (local.get $2) - (local.get $4) - ) - (call $_abort) + ) + (block $label$break$L331 + (if + (i32.lt_u + (local.get $0) + (i32.const 256) ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add + (then + (block + (local.set $2 + (i32.load offset=12 + (local.get $5) + ) + ) + (block $do-once51 + (if + (i32.ne + (local.tee $3 + (i32.load offset=8 + (local.get $5) + ) + ) + (local.tee $0 + (i32.add + (i32.shl + (local.get $1) + (i32.const 3) + ) + (i32.const 216) + ) + ) + ) + (then + (block + (if + (i32.lt_u + (local.get $3) + (local.get $4) + ) + (then + (call $_abort) + ) + ) + (br_if $do-once51 + (i32.eq + (i32.load offset=12 + (local.get $3) + ) + (local.get $5) + ) + ) + (call $_abort) + ) + ) + ) + ) + (if + (i32.eq + (local.get $2) + (local.get $3) + ) + (then + (block + (i32.store + (i32.const 176) + (i32.and + (i32.load + (i32.const 176) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $1) + ) + (i32.const -1) + ) + ) + ) + (br $label$break$L331) + ) + ) + ) + (block $do-once53 + (if + (i32.eq (local.get $2) - (i32.const 8) + (local.get $0) + ) + (then + (local.set $15 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + ) + (else + (block + (if + (i32.lt_u + (local.get $2) + (local.get $4) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + ) + (local.get $5) + ) + (then + (block + (local.set $15 + (local.get $0) + ) + (br $do-once53) + ) + ) + ) + (call $_abort) + ) ) ) ) - (local.get $5) - ) - (block - (local.set $15 - (local.get $0) + (i32.store offset=12 + (local.get $3) + (local.get $2) + ) + (i32.store + (local.get $15) + (local.get $3) ) - (br $do-once53) - ) - ) - (call $_abort) - ) - ) - ) - (i32.store offset=12 - (local.get $3) - (local.get $2) - ) - (i32.store - (local.get $15) - (local.get $3) - ) - ) - (block - (local.set $6 - (i32.load offset=24 - (local.get $5) - ) - ) - (block $do-once55 - (if - (i32.eq - (local.tee $0 - (i32.load offset=12 - (local.get $5) ) ) - (local.get $5) - ) - (block - (if - (i32.eqz - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add - (local.tee $3 - (i32.add + (else + (block + (local.set $6 + (i32.load offset=24 + (local.get $5) + ) + ) + (block $do-once55 + (if + (i32.eq + (local.tee $0 + (i32.load offset=12 + (local.get $5) + ) + ) + (local.get $5) + ) + (then + (block + (if + (i32.eqz + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.tee $3 + (i32.add + (local.get $5) + (i32.const 16) + ) + ) + (i32.const 4) + ) + ) + ) + ) + ) + (then + (if + (local.tee $1 + (i32.load + (local.get $3) + ) + ) + (then + (local.set $0 + (local.get $3) + ) + ) + (else + (block + (local.set $12 + (i32.const 0) + ) + (br $do-once55) + ) + ) + ) + ) + ) + (loop $while-in58 + (if + (local.tee $3 + (i32.load + (local.tee $2 + (i32.add + (local.get $1) + (i32.const 20) + ) + ) + ) + ) + (then + (block + (local.set $1 + (local.get $3) + ) + (local.set $0 + (local.get $2) + ) + (br $while-in58) + ) + ) + ) + (if + (local.tee $3 + (i32.load + (local.tee $2 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + ) + ) + (then + (block + (local.set $1 + (local.get $3) + ) + (local.set $0 + (local.get $2) + ) + (br $while-in58) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $0) + (local.get $4) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $0) + (i32.const 0) + ) + (local.set $12 + (local.get $1) + ) + ) + ) + ) + ) + ) + (else + (block + (if + (i32.lt_u + (local.tee $2 + (i32.load offset=8 + (local.get $5) + ) + ) + (local.get $4) + ) + (then + (call $_abort) + ) + ) + (if + (i32.ne + (i32.load + (local.tee $3 + (i32.add + (local.get $2) + (i32.const 12) + ) + ) + ) (local.get $5) - (i32.const 16) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $1 + (i32.add + (local.get $0) + (i32.const 8) + ) + ) + ) + (local.get $5) + ) + (then + (block + (i32.store + (local.get $3) + (local.get $0) + ) + (i32.store + (local.get $1) + (local.get $2) + ) + (local.set $12 + (local.get $0) + ) + ) + ) + (else + (call $_abort) ) ) - (i32.const 4) ) ) ) ) - ) - (if - (local.tee $1 - (i32.load - (local.get $3) - ) - ) - (local.set $0 - (local.get $3) - ) - (block - (local.set $12 - (i32.const 0) + (br_if $label$break$L331 + (i32.eqz + (local.get $6) ) - (br $do-once55) ) - ) - ) - (loop $while-in58 - (if - (local.tee $3 - (i32.load - (local.tee $2 - (i32.add - (local.get $1) - (i32.const 20) + (block $do-once59 + (if + (i32.eq + (local.get $5) + (i32.load + (local.tee $0 + (i32.add + (i32.shl + (local.tee $1 + (i32.load offset=28 + (local.get $5) + ) + ) + (i32.const 2) + ) + (i32.const 480) + ) + ) ) ) - ) - ) - (block - (local.set $1 - (local.get $3) - ) - (local.set $0 - (local.get $2) - ) - (br $while-in58) - ) - ) - (if - (local.tee $3 - (i32.load - (local.tee $2 - (i32.add - (local.get $1) - (i32.const 16) + (then + (block + (i32.store + (local.get $0) + (local.get $12) + ) + (br_if $do-once59 + (local.get $12) + ) + (i32.store + (i32.const 180) + (i32.and + (i32.load + (i32.const 180) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $1) + ) + (i32.const -1) + ) + ) + ) + (br $label$break$L331) ) ) - ) - ) - (block - (local.set $1 - (local.get $3) - ) - (local.set $0 - (local.get $2) - ) - (br $while-in58) - ) - ) - ) - (if - (i32.lt_u - (local.get $0) - (local.get $4) - ) - (call $_abort) - (block - (i32.store - (local.get $0) - (i32.const 0) - ) - (local.set $12 - (local.get $1) - ) - ) - ) - ) - (block - (if - (i32.lt_u - (local.tee $2 - (i32.load offset=8 - (local.get $5) - ) - ) - (local.get $4) - ) - (call $_abort) - ) - (if - (i32.ne - (i32.load - (local.tee $3 - (i32.add - (local.get $2) - (i32.const 12) - ) - ) - ) - (local.get $5) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $1 - (i32.add - (local.get $0) - (i32.const 8) + (else + (block + (if + (i32.lt_u + (local.get $6) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $6) + (i32.const 16) + ) + ) + ) + (local.get $5) + ) + (then + (i32.store + (local.get $0) + (local.get $12) + ) + ) + (else + (i32.store offset=20 + (local.get $6) + (local.get $12) + ) + ) + ) + (br_if $label$break$L331 + (i32.eqz + (local.get $12) + ) + ) + ) ) ) ) - (local.get $5) - ) - (block - (i32.store - (local.get $3) - (local.get $0) - ) - (i32.store - (local.get $1) - (local.get $2) - ) - (local.set $12 - (local.get $0) - ) - ) - (call $_abort) - ) - ) - ) - ) - (br_if $label$break$L331 - (i32.eqz - (local.get $6) - ) - ) - (block $do-once59 - (if - (i32.eq - (local.get $5) - (i32.load - (local.tee $0 - (i32.add - (i32.shl + (if + (i32.lt_u + (local.get $12) (local.tee $1 - (i32.load offset=28 - (local.get $5) + (i32.load + (i32.const 192) ) ) - (i32.const 2) ) - (i32.const 480) + (then + (call $_abort) + ) ) - ) - ) - ) - (block - (i32.store - (local.get $0) - (local.get $12) - ) - (br_if $do-once59 - (local.get $12) - ) - (i32.store - (i32.const 180) - (i32.and - (i32.load - (i32.const 180) + (i32.store offset=24 + (local.get $12) + (local.get $6) ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $1) + (if + (local.tee $3 + (i32.load + (local.tee $0 + (i32.add + (local.get $5) + (i32.const 16) + ) + ) + ) + ) + (then + (if + (i32.lt_u + (local.get $3) + (local.get $1) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=16 + (local.get $12) + (local.get $3) + ) + (i32.store offset=24 + (local.get $3) + (local.get $12) + ) + ) + ) + ) ) - (i32.const -1) - ) - ) - ) - (br $label$break$L331) - ) - (block - (if - (i32.lt_u - (local.get $6) - (i32.load - (i32.const 192) ) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $6) - (i32.const 16) + (br_if $label$break$L331 + (i32.eqz + (local.tee $0 + (i32.load offset=4 + (local.get $0) + ) + ) + ) + ) + (if + (i32.lt_u + (local.get $0) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=20 + (local.get $12) + (local.get $0) + ) + (i32.store offset=24 + (local.get $0) + (local.get $12) + ) ) ) ) - (local.get $5) - ) - (i32.store - (local.get $0) - (local.get $12) - ) - (i32.store offset=20 - (local.get $6) - (local.get $12) - ) - ) - (br_if $label$break$L331 - (i32.eqz - (local.get $12) - ) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $12) - (local.tee $1 - (i32.load - (i32.const 192) - ) - ) - ) - (call $_abort) - ) - (i32.store offset=24 - (local.get $12) - (local.get $6) - ) - (if - (local.tee $3 - (i32.load - (local.tee $0 - (i32.add - (local.get $5) - (i32.const 16) ) ) ) ) - (if - (i32.lt_u - (local.get $3) - (local.get $1) - ) - (call $_abort) - (block - (i32.store offset=16 - (local.get $12) - (local.get $3) - ) - (i32.store offset=24 - (local.get $3) - (local.get $12) - ) - ) - ) - ) - (br_if $label$break$L331 - (i32.eqz - (local.tee $0 - (i32.load offset=4 - (local.get $0) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $0) - (i32.load - (i32.const 192) + (local.set $7 + (i32.add + (local.get $11) + (local.get $7) ) ) - (call $_abort) - (block - (i32.store offset=20 - (local.get $12) - (local.get $0) - ) - (i32.store offset=24 - (local.get $0) - (local.get $12) - ) + (i32.add + (local.get $5) + (local.get $11) ) ) ) + (else + (local.get $5) + ) ) ) - (local.set $7 - (i32.add - (local.get $11) - (local.get $7) - ) - ) - (i32.add - (local.get $5) - (local.get $11) - ) + (i32.const 4) ) - (local.get $5) + ) + (i32.and + (i32.load + (local.get $0) + ) + (i32.const -2) ) ) - (i32.const 4) - ) - ) - (i32.and - (i32.load - (local.get $0) - ) - (i32.const -2) - ) - ) - (i32.store offset=4 - (local.get $8) - (i32.or - (local.get $7) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $8) - (local.get $7) - ) - (local.get $7) - ) - (local.set $0 - (i32.shr_u - (local.get $7) - (i32.const 3) - ) - ) - (if - (i32.lt_u - (local.get $7) - (i32.const 256) - ) - (block - (local.set $3 - (i32.add - (i32.shl - (local.get $0) + (i32.store offset=4 + (local.get $8) + (i32.or + (local.get $7) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (local.get $8) + (local.get $7) + ) + (local.get $7) + ) + (local.set $0 + (i32.shr_u + (local.get $7) (i32.const 3) ) - (i32.const 216) ) - ) - (block $do-once63 (if - (i32.and - (local.tee $1 - (i32.load - (i32.const 176) - ) - ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $0) - ) - ) + (i32.lt_u + (local.get $7) + (i32.const 256) ) - (block - (if - (i32.ge_u - (local.tee $0 - (i32.load + (then + (block + (local.set $3 + (i32.add + (i32.shl + (local.get $0) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (block $do-once63 + (if + (i32.and (local.tee $1 - (i32.add + (i32.load + (i32.const 176) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $0) + ) + ) + ) + (then + (block + (if + (i32.ge_u + (local.tee $0 + (i32.load + (local.tee $1 + (i32.add + (local.get $3) + (i32.const 8) + ) + ) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (block + (local.set $16 + (local.get $1) + ) + (local.set $10 + (local.get $0) + ) + (br $do-once63) + ) + ) + ) + (call $_abort) + ) + ) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (local.set $16 + (i32.add + (local.get $3) + (i32.const 8) + ) + ) + (local.set $10 (local.get $3) - (i32.const 8) ) ) ) ) - (i32.load - (i32.const 192) - ) ) - (block - (local.set $16 - (local.get $1) - ) - (local.set $10 - (local.get $0) - ) - (br $do-once63) + (i32.store + (local.get $16) + (local.get $8) ) - ) - (call $_abort) - ) - (block - (i32.store - (i32.const 176) - (i32.or - (local.get $1) - (local.get $0) + (i32.store offset=12 + (local.get $10) + (local.get $8) ) - ) - (local.set $16 - (i32.add + (i32.store offset=8 + (local.get $8) + (local.get $10) + ) + (i32.store offset=12 + (local.get $8) (local.get $3) - (i32.const 8) ) - ) - (local.set $10 - (local.get $3) + (br $do-once48) ) ) ) - ) - (i32.store - (local.get $16) - (local.get $8) - ) - (i32.store offset=12 - (local.get $10) - (local.get $8) - ) - (i32.store offset=8 - (local.get $8) - (local.get $10) - ) - (i32.store offset=12 - (local.get $8) - (local.get $3) - ) - (br $do-once48) - ) - ) - (local.set $3 - (i32.add - (i32.shl - (local.tee $2 - (block $do-once65 (result i32) - (if (result i32) - (local.tee $0 - (i32.shr_u - (local.get $7) - (i32.const 8) - ) - ) - (block (result i32) - (drop - (br_if $do-once65 - (i32.const 31) - (i32.gt_u - (local.get $7) - (i32.const 16777215) + (local.set $3 + (i32.add + (i32.shl + (local.tee $2 + (block $do-once65 (result i32) + (if (result i32) + (local.tee $0 + (i32.shr_u + (local.get $7) + (i32.const 8) + ) ) - ) - ) - (i32.or - (i32.and - (i32.shr_u - (local.get $7) - (i32.add - (local.tee $0 - (i32.add - (i32.sub - (i32.const 14) - (i32.or - (i32.or - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $0) - (local.tee $3 - (i32.and - (i32.shr_u - (i32.add + (then + (block (result i32) + (drop + (br_if $do-once65 + (i32.const 31) + (i32.gt_u + (local.get $7) + (i32.const 16777215) + ) + ) + ) + (i32.or + (i32.and + (i32.shr_u + (local.get $7) + (i32.add + (local.tee $0 + (i32.add + (i32.sub + (i32.const 14) + (i32.or + (i32.or + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl (local.get $0) - (i32.const 1048320) + (local.tee $3 + (i32.and + (i32.shr_u + (i32.add + (local.get $0) + (i32.const 1048320) + ) + (i32.const 16) + ) + (i32.const 8) + ) + ) ) - (i32.const 16) ) - (i32.const 8) + (i32.const 520192) ) + (i32.const 16) ) + (i32.const 4) ) ) - (i32.const 520192) + (local.get $3) + ) + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $1) + (local.get $0) + ) + ) + (i32.const 245760) + ) + (i32.const 16) + ) + (i32.const 2) + ) ) - (i32.const 16) ) - (i32.const 4) ) - ) - (local.get $3) - ) - (local.tee $0 - (i32.and (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $1) - (local.get $0) - ) - ) - (i32.const 245760) + (i32.shl + (local.get $1) + (local.get $0) ) - (i32.const 16) + (i32.const 15) ) - (i32.const 2) ) ) + (i32.const 7) ) ) - (i32.shr_u - (i32.shl - (local.get $1) - (local.get $0) - ) - (i32.const 15) - ) + (i32.const 1) ) - ) - (i32.const 7) - ) - ) - (i32.const 1) - ) - (i32.shl - (local.get $0) - (i32.const 1) - ) - ) - ) - (i32.const 0) - ) - ) - ) - (i32.const 2) - ) - (i32.const 480) - ) - ) - (i32.store offset=28 - (local.get $8) - (local.get $2) - ) - (i32.store offset=4 - (local.tee $0 - (i32.add - (local.get $8) - (i32.const 16) - ) - ) - (i32.const 0) - ) - (i32.store - (local.get $0) - (i32.const 0) - ) - (if - (i32.eqz - (i32.and - (local.tee $1 - (i32.load - (i32.const 180) - ) - ) - (local.tee $0 - (i32.shl - (i32.const 1) - (local.get $2) - ) - ) - ) - ) - (block - (i32.store - (i32.const 180) - (i32.or - (local.get $1) - (local.get $0) - ) - ) - (i32.store - (local.get $3) - (local.get $8) - ) - (i32.store offset=24 - (local.get $8) - (local.get $3) - ) - (i32.store offset=12 - (local.get $8) - (local.get $8) - ) - (i32.store offset=8 - (local.get $8) - (local.get $8) - ) - (br $do-once48) - ) - ) - (local.set $2 - (i32.shl - (local.get $7) - (select - (i32.const 0) - (i32.sub - (i32.const 25) - (i32.shr_u - (local.get $2) - (i32.const 1) - ) - ) - (i32.eq - (local.get $2) - (i32.const 31) - ) - ) - ) - ) - (local.set $0 - (i32.load - (local.get $3) - ) - ) - (block $__rjto$7 - (block $__rjti$7 - (loop $while-in68 - (br_if $__rjti$7 - (i32.eq - (i32.and - (i32.load offset=4 - (local.get $0) + (i32.shl + (local.get $0) + (i32.const 1) + ) + ) + ) + ) + (else + (i32.const 0) + ) + ) + ) ) - (i32.const -8) + (i32.const 2) ) - (local.get $7) + (i32.const 480) ) ) - (local.set $3 - (i32.shl - (local.get $2) - (i32.const 1) + (i32.store offset=28 + (local.get $8) + (local.get $2) + ) + (i32.store offset=4 + (local.tee $0 + (i32.add + (local.get $8) + (i32.const 16) + ) ) + (i32.const 0) + ) + (i32.store + (local.get $0) + (i32.const 0) ) (if - (local.tee $1 - (i32.load - (local.tee $2 - (i32.add - (i32.add - (local.get $0) - (i32.const 16) - ) - (i32.shl - (i32.shr_u - (local.get $2) - (i32.const 31) - ) - (i32.const 2) - ) + (i32.eqz + (i32.and + (local.tee $1 + (i32.load + (i32.const 180) + ) + ) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $2) ) ) ) ) - (block - (local.set $2 - (local.get $3) - ) - (local.set $0 - (local.get $1) + (then + (block + (i32.store + (i32.const 180) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (i32.store + (local.get $3) + (local.get $8) + ) + (i32.store offset=24 + (local.get $8) + (local.get $3) + ) + (i32.store offset=12 + (local.get $8) + (local.get $8) + ) + (i32.store offset=8 + (local.get $8) + (local.get $8) + ) + (br $do-once48) ) - (br $while-in68) ) ) - ) - (if - (i32.lt_u - (local.get $2) - (i32.load - (i32.const 192) + (local.set $2 + (i32.shl + (local.get $7) + (select + (i32.const 0) + (i32.sub + (i32.const 25) + (i32.shr_u + (local.get $2) + (i32.const 1) + ) + ) + (i32.eq + (local.get $2) + (i32.const 31) + ) + ) ) ) - (call $_abort) - (block - (i32.store - (local.get $2) - (local.get $8) - ) - (i32.store offset=24 - (local.get $8) - (local.get $0) - ) - (i32.store offset=12 - (local.get $8) - (local.get $8) - ) - (i32.store offset=8 - (local.get $8) - (local.get $8) + (local.set $0 + (i32.load + (local.get $3) ) - (br $do-once48) ) - ) - (br $__rjto$7) - ) - (if - (i32.and - (i32.ge_u - (local.tee $2 - (i32.load - (local.tee $3 - (i32.add - (local.get $0) - (i32.const 8) + (block $__rjto$7 + (block $__rjti$7 + (loop $while-in68 + (br_if $__rjti$7 + (i32.eq + (i32.and + (i32.load offset=4 + (local.get $0) + ) + (i32.const -8) + ) + (local.get $7) + ) + ) + (local.set $3 + (i32.shl + (local.get $2) + (i32.const 1) + ) + ) + (if + (local.tee $1 + (i32.load + (local.tee $2 + (i32.add + (i32.add + (local.get $0) + (i32.const 16) + ) + (i32.shl + (i32.shr_u + (local.get $2) + (i32.const 31) + ) + (i32.const 2) + ) + ) + ) + ) + ) + (then + (block + (local.set $2 + (local.get $3) + ) + (local.set $0 + (local.get $1) + ) + (br $while-in68) + ) ) ) ) - ) - (local.tee $1 - (i32.load - (i32.const 192) + (if + (i32.lt_u + (local.get $2) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $2) + (local.get $8) + ) + (i32.store offset=24 + (local.get $8) + (local.get $0) + ) + (i32.store offset=12 + (local.get $8) + (local.get $8) + ) + (i32.store offset=8 + (local.get $8) + (local.get $8) + ) + (br $do-once48) + ) + ) + ) + (br $__rjto$7) + ) + (if + (i32.and + (i32.ge_u + (local.tee $2 + (i32.load + (local.tee $3 + (i32.add + (local.get $0) + (i32.const 8) + ) + ) + ) + ) + (local.tee $1 + (i32.load + (i32.const 192) + ) + ) + ) + (i32.ge_u + (local.get $0) + (local.get $1) + ) + ) + (then + (block + (i32.store offset=12 + (local.get $2) + (local.get $8) + ) + (i32.store + (local.get $3) + (local.get $8) + ) + (i32.store offset=8 + (local.get $8) + (local.get $2) + ) + (i32.store offset=12 + (local.get $8) + (local.get $0) + ) + (i32.store offset=24 + (local.get $8) + (i32.const 0) + ) + ) + ) + (else + (call $_abort) ) ) - ) - (i32.ge_u - (local.get $0) - (local.get $1) - ) - ) - (block - (i32.store offset=12 - (local.get $2) - (local.get $8) - ) - (i32.store - (local.get $3) - (local.get $8) - ) - (i32.store offset=8 - (local.get $8) - (local.get $2) - ) - (i32.store offset=12 - (local.get $8) - (local.get $0) - ) - (i32.store offset=24 - (local.get $8) - (i32.const 0) ) ) - (call $_abort) ) ) ) - ) - ) - (return - (i32.add - (local.get $9) - (i32.const 8) + (return + (i32.add + (local.get $9) + (i32.const 8) + ) + ) ) ) ) ) - ) - (loop $while-in70 - (block $while-out69 - (if - (i32.le_u - (local.tee $2 - (i32.load - (local.get $4) + (loop $while-in70 + (block $while-out69 + (if + (i32.le_u + (local.tee $2 + (i32.load + (local.get $4) + ) ) + (local.get $6) ) - (local.get $6) - ) - (br_if $while-out69 - (i32.gt_u - (local.tee $2 - (i32.add - (local.get $2) - (i32.load offset=4 - (local.get $4) + (then + (br_if $while-out69 + (i32.gt_u + (local.tee $2 + (i32.add + (local.get $2) + (i32.load offset=4 + (local.get $4) + ) + ) ) + (local.get $6) ) ) - (local.get $6) ) ) - ) - (local.set $4 - (i32.load offset=8 - (local.get $4) + (local.set $4 + (i32.load offset=8 + (local.get $4) + ) ) + (br $while-in70) ) - (br $while-in70) ) - ) - (local.set $10 - (i32.add - (local.tee $4 - (i32.add - (local.get $2) - (i32.const -47) + (local.set $10 + (i32.add + (local.tee $4 + (i32.add + (local.get $2) + (i32.const -47) + ) ) + (i32.const 8) ) - (i32.const 8) ) - ) - (local.set $12 - (i32.add - (local.tee $11 - (select - (local.get $6) - (local.tee $4 - (i32.add - (local.get $4) - (select - (i32.and - (i32.sub - (i32.const 0) + (local.set $12 + (i32.add + (local.tee $11 + (select + (local.get $6) + (local.tee $4 + (i32.add + (local.get $4) + (select + (i32.and + (i32.sub + (i32.const 0) + (local.get $10) + ) + (i32.const 7) + ) + (i32.const 0) + (i32.and (local.get $10) + (i32.const 7) ) - (i32.const 7) - ) - (i32.const 0) - (i32.and - (local.get $10) - (i32.const 7) ) ) ) - ) - (i32.lt_u - (local.get $4) - (local.tee $10 - (i32.add - (local.get $6) - (i32.const 16) + (i32.lt_u + (local.get $4) + (local.tee $10 + (i32.add + (local.get $6) + (i32.const 16) + ) ) ) ) ) + (i32.const 8) ) - (i32.const 8) ) - ) - (i32.store - (i32.const 200) - (local.tee $5 - (i32.add - (local.get $1) - (local.tee $4 - (select - (i32.and - (i32.sub - (i32.const 0) - (local.tee $4 - (i32.add - (local.get $1) - (i32.const 8) + (i32.store + (i32.const 200) + (local.tee $5 + (i32.add + (local.get $1) + (local.tee $4 + (select + (i32.and + (i32.sub + (i32.const 0) + (local.tee $4 + (i32.add + (local.get $1) + (i32.const 8) + ) ) ) + (i32.const 7) + ) + (i32.const 0) + (i32.and + (local.get $4) + (i32.const 7) ) - (i32.const 7) - ) - (i32.const 0) - (i32.and - (local.get $4) - (i32.const 7) ) ) ) ) ) - ) - (i32.store - (i32.const 188) - (local.tee $4 - (i32.sub - (i32.add - (local.get $3) - (i32.const -40) + (i32.store + (i32.const 188) + (local.tee $4 + (i32.sub + (i32.add + (local.get $3) + (i32.const -40) + ) + (local.get $4) ) - (local.get $4) ) ) - ) - (i32.store offset=4 - (local.get $5) - (i32.or - (local.get $4) - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.add + (i32.store offset=4 (local.get $5) - (local.get $4) - ) - (i32.const 40) - ) - (i32.store - (i32.const 204) - (i32.load - (i32.const 664) + (i32.or + (local.get $4) + (i32.const 1) + ) ) - ) - (i32.store - (local.tee $4 + (i32.store offset=4 (i32.add - (local.get $11) - (i32.const 4) + (local.get $5) + (local.get $4) ) + (i32.const 40) ) - (i32.const 27) - ) - (i32.store - (local.get $12) - (i32.load - (i32.const 624) + (i32.store + (i32.const 204) + (i32.load + (i32.const 664) + ) ) - ) - (i32.store offset=4 - (local.get $12) - (i32.load - (i32.const 628) + (i32.store + (local.tee $4 + (i32.add + (local.get $11) + (i32.const 4) + ) + ) + (i32.const 27) ) - ) - (i32.store offset=8 - (local.get $12) - (i32.load - (i32.const 632) + (i32.store + (local.get $12) + (i32.load + (i32.const 624) + ) ) - ) - (i32.store offset=12 - (local.get $12) - (i32.load - (i32.const 636) + (i32.store offset=4 + (local.get $12) + (i32.load + (i32.const 628) + ) ) - ) - (i32.store - (i32.const 624) - (local.get $1) - ) - (i32.store - (i32.const 628) - (local.get $3) - ) - (i32.store - (i32.const 636) - (i32.const 0) - ) - (i32.store - (i32.const 632) - (local.get $12) - ) - (local.set $1 - (i32.add - (local.get $11) - (i32.const 24) + (i32.store offset=8 + (local.get $12) + (i32.load + (i32.const 632) + ) + ) + (i32.store offset=12 + (local.get $12) + (i32.load + (i32.const 636) + ) + ) + (i32.store + (i32.const 624) + (local.get $1) ) - ) - (loop $while-in72 (i32.store - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 4) - ) - ) - (i32.const 7) + (i32.const 628) + (local.get $3) ) - (br_if $while-in72 - (i32.lt_u - (i32.add - (local.get $1) - (i32.const 4) - ) - (local.get $2) - ) + (i32.store + (i32.const 636) + (i32.const 0) ) - ) - (if - (i32.ne - (local.get $11) - (local.get $6) + (i32.store + (i32.const 632) + (local.get $12) ) - (block + (local.set $1 + (i32.add + (local.get $11) + (i32.const 24) + ) + ) + (loop $while-in72 (i32.store - (local.get $4) - (i32.and - (i32.load - (local.get $4) + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 4) ) - (i32.const -2) ) + (i32.const 7) ) - (i32.store offset=4 - (local.get $6) - (i32.or - (local.tee $5 - (i32.sub - (local.get $11) - (local.get $6) - ) + (br_if $while-in72 + (i32.lt_u + (i32.add + (local.get $1) + (i32.const 4) ) - (i32.const 1) + (local.get $2) ) ) - (i32.store + ) + (if + (i32.ne (local.get $11) - (local.get $5) - ) - (local.set $1 - (i32.shr_u - (local.get $5) - (i32.const 3) - ) + (local.get $6) ) - (if - (i32.lt_u - (local.get $5) - (i32.const 256) - ) + (then (block - (local.set $2 - (i32.add - (i32.shl - (local.get $1) - (i32.const 3) + (i32.store + (local.get $4) + (i32.and + (i32.load + (local.get $4) ) - (i32.const 216) + (i32.const -2) ) ) - (if - (i32.and - (local.tee $3 - (i32.load - (i32.const 176) - ) - ) - (local.tee $1 - (i32.shl - (i32.const 1) - (local.get $1) + (i32.store offset=4 + (local.get $6) + (i32.or + (local.tee $5 + (i32.sub + (local.get $11) + (local.get $6) ) ) + (i32.const 1) ) - (if - (i32.lt_u - (local.tee $1 - (i32.load + ) + (i32.store + (local.get $11) + (local.get $5) + ) + (local.set $1 + (i32.shr_u + (local.get $5) + (i32.const 3) + ) + ) + (if + (i32.lt_u + (local.get $5) + (i32.const 256) + ) + (then + (block + (local.set $2 + (i32.add + (i32.shl + (local.get $1) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (if + (i32.and (local.tee $3 - (i32.add + (i32.load + (i32.const 176) + ) + ) + (local.tee $1 + (i32.shl + (i32.const 1) + (local.get $1) + ) + ) + ) + (then + (if + (i32.lt_u + (local.tee $1 + (i32.load + (local.tee $3 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (local.set $17 + (local.get $3) + ) + (local.set $7 + (local.get $1) + ) + ) + ) + ) + ) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $3) + (local.get $1) + ) + ) + (local.set $17 + (i32.add + (local.get $2) + (i32.const 8) + ) + ) + (local.set $7 (local.get $2) - (i32.const 8) ) ) ) ) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (local.set $17 - (local.get $3) + (i32.store + (local.get $17) + (local.get $6) ) - (local.set $7 - (local.get $1) + (i32.store offset=12 + (local.get $7) + (local.get $6) ) - ) - ) - (block - (i32.store - (i32.const 176) - (i32.or - (local.get $3) - (local.get $1) + (i32.store offset=8 + (local.get $6) + (local.get $7) ) - ) - (local.set $17 - (i32.add + (i32.store offset=12 + (local.get $6) (local.get $2) - (i32.const 8) ) - ) - (local.set $7 - (local.get $2) + (br $do-once40) ) ) ) - (i32.store - (local.get $17) - (local.get $6) - ) - (i32.store offset=12 - (local.get $7) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $7) - ) - (i32.store offset=12 - (local.get $6) - (local.get $2) - ) - (br $do-once40) - ) - ) - (local.set $2 - (i32.add - (i32.shl - (local.tee $4 - (if (result i32) - (local.tee $1 - (i32.shr_u - (local.get $5) - (i32.const 8) - ) - ) - (if (result i32) - (i32.gt_u - (local.get $5) - (i32.const 16777215) - ) - (i32.const 31) - (i32.or - (i32.and + (local.set $2 + (i32.add + (i32.shl + (local.tee $4 + (if (result i32) + (local.tee $1 (i32.shr_u (local.get $5) - (i32.add - (local.tee $1 - (i32.add - (i32.sub - (i32.const 14) - (i32.or - (i32.or - (local.tee $1 - (i32.and - (i32.shr_u - (i32.add - (local.tee $3 - (i32.shl - (local.get $1) - (local.tee $2 - (i32.and - (i32.shr_u - (i32.add + (i32.const 8) + ) + ) + (then + (if (result i32) + (i32.gt_u + (local.get $5) + (i32.const 16777215) + ) + (then + (i32.const 31) + ) + (else + (i32.or + (i32.and + (i32.shr_u + (local.get $5) + (i32.add + (local.tee $1 + (i32.add + (i32.sub + (i32.const 14) + (i32.or + (i32.or + (local.tee $1 + (i32.and + (i32.shr_u + (i32.add + (local.tee $3 + (i32.shl (local.get $1) - (i32.const 1048320) + (local.tee $2 + (i32.and + (i32.shr_u + (i32.add + (local.get $1) + (i32.const 1048320) + ) + (i32.const 16) + ) + (i32.const 8) + ) + ) ) - (i32.const 16) ) - (i32.const 8) + (i32.const 520192) ) + (i32.const 16) ) + (i32.const 4) ) ) - (i32.const 520192) + (local.get $2) + ) + (local.tee $1 + (i32.and + (i32.shr_u + (i32.add + (local.tee $3 + (i32.shl + (local.get $3) + (local.get $1) + ) + ) + (i32.const 245760) + ) + (i32.const 16) + ) + (i32.const 2) + ) ) - (i32.const 16) ) - (i32.const 4) ) - ) - (local.get $2) - ) - (local.tee $1 - (i32.and (i32.shr_u - (i32.add - (local.tee $3 - (i32.shl - (local.get $3) - (local.get $1) - ) - ) - (i32.const 245760) + (i32.shl + (local.get $3) + (local.get $1) ) - (i32.const 16) + (i32.const 15) ) - (i32.const 2) ) ) + (i32.const 7) ) ) - (i32.shr_u - (i32.shl - (local.get $3) - (local.get $1) - ) - (i32.const 15) - ) + (i32.const 1) + ) + (i32.shl + (local.get $1) + (i32.const 1) ) ) - (i32.const 7) ) ) - (i32.const 1) ) - (i32.shl - (local.get $1) - (i32.const 1) + (else + (i32.const 0) ) ) ) - (i32.const 0) - ) - ) - (i32.const 2) - ) - (i32.const 480) - ) - ) - (i32.store offset=28 - (local.get $6) - (local.get $4) - ) - (i32.store offset=20 - (local.get $6) - (i32.const 0) - ) - (i32.store - (local.get $10) - (i32.const 0) - ) - (if - (i32.eqz - (i32.and - (local.tee $3 - (i32.load - (i32.const 180) - ) - ) - (local.tee $1 - (i32.shl - (i32.const 1) - (local.get $4) + (i32.const 2) ) + (i32.const 480) ) ) - ) - (block - (i32.store - (i32.const 180) - (i32.or - (local.get $3) - (local.get $1) - ) - ) - (i32.store - (local.get $2) + (i32.store offset=28 (local.get $6) + (local.get $4) ) - (i32.store offset=24 + (i32.store offset=20 (local.get $6) - (local.get $2) + (i32.const 0) ) - (i32.store offset=12 - (local.get $6) - (local.get $6) + (i32.store + (local.get $10) + (i32.const 0) ) - (i32.store offset=8 - (local.get $6) - (local.get $6) + (if + (i32.eqz + (i32.and + (local.tee $3 + (i32.load + (i32.const 180) + ) + ) + (local.tee $1 + (i32.shl + (i32.const 1) + (local.get $4) + ) + ) + ) + ) + (then + (block + (i32.store + (i32.const 180) + (i32.or + (local.get $3) + (local.get $1) + ) + ) + (i32.store + (local.get $2) + (local.get $6) + ) + (i32.store offset=24 + (local.get $6) + (local.get $2) + ) + (i32.store offset=12 + (local.get $6) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $6) + ) + (br $do-once40) + ) + ) ) - (br $do-once40) - ) - ) - (local.set $4 - (i32.shl - (local.get $5) - (select - (i32.const 0) - (i32.sub - (i32.const 25) - (i32.shr_u - (local.get $4) - (i32.const 1) + (local.set $4 + (i32.shl + (local.get $5) + (select + (i32.const 0) + (i32.sub + (i32.const 25) + (i32.shr_u + (local.get $4) + (i32.const 1) + ) + ) + (i32.eq + (local.get $4) + (i32.const 31) + ) ) ) - (i32.eq - (local.get $4) - (i32.const 31) + ) + (local.set $1 + (i32.load + (local.get $2) ) ) - ) - ) - (local.set $1 - (i32.load - (local.get $2) - ) - ) - (block $__rjto$9 - (block $__rjti$9 - (loop $while-in74 - (br_if $__rjti$9 - (i32.eq - (i32.and - (i32.load offset=4 - (local.get $1) + (block $__rjto$9 + (block $__rjti$9 + (loop $while-in74 + (br_if $__rjti$9 + (i32.eq + (i32.and + (i32.load offset=4 + (local.get $1) + ) + (i32.const -8) + ) + (local.get $5) + ) + ) + (local.set $2 + (i32.shl + (local.get $4) + (i32.const 1) + ) + ) + (if + (local.tee $3 + (i32.load + (local.tee $4 + (i32.add + (i32.add + (local.get $1) + (i32.const 16) + ) + (i32.shl + (i32.shr_u + (local.get $4) + (i32.const 31) + ) + (i32.const 2) + ) + ) + ) + ) + ) + (then + (block + (local.set $4 + (local.get $2) + ) + (local.set $1 + (local.get $3) + ) + (br $while-in74) + ) ) - (i32.const -8) ) - (local.get $5) ) - ) - (local.set $2 - (i32.shl - (local.get $4) - (i32.const 1) + (if + (i32.lt_u + (local.get $4) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $4) + (local.get $6) + ) + (i32.store offset=24 + (local.get $6) + (local.get $1) + ) + (i32.store offset=12 + (local.get $6) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $6) + ) + (br $do-once40) + ) + ) ) + (br $__rjto$9) ) (if - (local.tee $3 - (i32.load + (i32.and + (i32.ge_u (local.tee $4 - (i32.add - (i32.add - (local.get $1) - (i32.const 16) - ) - (i32.shl - (i32.shr_u - (local.get $4) - (i32.const 31) + (i32.load + (local.tee $2 + (i32.add + (local.get $1) + (i32.const 8) ) - (i32.const 2) ) ) ) + (local.tee $3 + (i32.load + (i32.const 192) + ) + ) ) - ) - (block - (local.set $4 - (local.get $2) - ) - (local.set $1 + (i32.ge_u + (local.get $1) (local.get $3) ) - (br $while-in74) - ) - ) - ) - (if - (i32.lt_u - (local.get $4) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (i32.store - (local.get $4) - (local.get $6) - ) - (i32.store offset=24 - (local.get $6) - (local.get $1) - ) - (i32.store offset=12 - (local.get $6) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $6) ) - (br $do-once40) - ) - ) - (br $__rjto$9) - ) - (if - (i32.and - (i32.ge_u - (local.tee $4 - (i32.load - (local.tee $2 - (i32.add - (local.get $1) - (i32.const 8) - ) + (then + (block + (i32.store offset=12 + (local.get $4) + (local.get $6) + ) + (i32.store + (local.get $2) + (local.get $6) + ) + (i32.store offset=8 + (local.get $6) + (local.get $4) + ) + (i32.store offset=12 + (local.get $6) + (local.get $1) + ) + (i32.store offset=24 + (local.get $6) + (i32.const 0) ) ) ) - (local.tee $3 - (i32.load - (i32.const 192) - ) + (else + (call $_abort) ) ) - (i32.ge_u - (local.get $1) - (local.get $3) - ) - ) - (block - (i32.store offset=12 - (local.get $4) - (local.get $6) - ) - (i32.store - (local.get $2) - (local.get $6) - ) - (i32.store offset=8 - (local.get $6) - (local.get $4) - ) - (i32.store offset=12 - (local.get $6) - (local.get $1) - ) - (i32.store offset=24 - (local.get $6) - (i32.const 0) - ) ) - (call $_abort) ) ) ) ) ) - (block - (if - (i32.or - (i32.eqz - (local.tee $2 - (i32.load - (i32.const 192) + (else + (block + (if + (i32.or + (i32.eqz + (local.tee $2 + (i32.load + (i32.const 192) + ) ) ) + (i32.lt_u + (local.get $1) + (local.get $2) + ) ) - (i32.lt_u - (local.get $1) - (local.get $2) + (then + (i32.store + (i32.const 192) + (local.get $1) + ) ) ) (i32.store - (i32.const 192) + (i32.const 624) (local.get $1) ) - ) - (i32.store - (i32.const 624) - (local.get $1) - ) - (i32.store - (i32.const 628) - (local.get $3) - ) - (i32.store - (i32.const 636) - (i32.const 0) - ) - (i32.store - (i32.const 212) - (i32.load - (i32.const 648) + (i32.store + (i32.const 628) + (local.get $3) ) - ) - (i32.store - (i32.const 208) - (i32.const -1) - ) - (local.set $2 - (i32.const 0) - ) - (loop $while-in43 - (i32.store offset=12 - (local.tee $4 - (i32.add - (i32.shl - (local.get $2) - (i32.const 3) - ) - (i32.const 216) - ) + (i32.store + (i32.const 636) + (i32.const 0) + ) + (i32.store + (i32.const 212) + (i32.load + (i32.const 648) ) - (local.get $4) ) - (i32.store offset=8 - (local.get $4) - (local.get $4) + (i32.store + (i32.const 208) + (i32.const -1) ) - (br_if $while-in43 - (i32.ne - (local.tee $2 + (local.set $2 + (i32.const 0) + ) + (loop $while-in43 + (i32.store offset=12 + (local.tee $4 (i32.add - (local.get $2) - (i32.const 1) + (i32.shl + (local.get $2) + (i32.const 3) + ) + (i32.const 216) + ) + ) + (local.get $4) + ) + (i32.store offset=8 + (local.get $4) + (local.get $4) + ) + (br_if $while-in43 + (i32.ne + (local.tee $2 + (i32.add + (local.get $2) + (i32.const 1) + ) ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (i32.store - (i32.const 200) - (local.tee $2 - (i32.add - (local.get $1) - (local.tee $1 - (select - (i32.and - (i32.sub - (i32.const 0) - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 8) + (i32.store + (i32.const 200) + (local.tee $2 + (i32.add + (local.get $1) + (local.tee $1 + (select + (i32.and + (i32.sub + (i32.const 0) + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 8) + ) ) ) + (i32.const 7) + ) + (i32.const 0) + (i32.and + (local.get $1) + (i32.const 7) ) - (i32.const 7) - ) - (i32.const 0) - (i32.and - (local.get $1) - (i32.const 7) ) ) ) ) ) - ) - (i32.store - (i32.const 188) - (local.tee $1 - (i32.sub - (i32.add - (local.get $3) - (i32.const -40) + (i32.store + (i32.const 188) + (local.tee $1 + (i32.sub + (i32.add + (local.get $3) + (i32.const -40) + ) + (local.get $1) ) - (local.get $1) ) ) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $1) - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.add + (i32.store offset=4 (local.get $2) - (local.get $1) + (i32.or + (local.get $1) + (i32.const 1) + ) ) - (i32.const 40) - ) - (i32.store - (i32.const 204) - (i32.load - (i32.const 664) + (i32.store offset=4 + (i32.add + (local.get $2) + (local.get $1) + ) + (i32.const 40) + ) + (i32.store + (i32.const 204) + (i32.load + (i32.const 664) + ) ) ) ) @@ -26275,7 +27741,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u @@ -26291,7 +27759,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -26310,7 +27780,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (i32.add @@ -26329,7 +27801,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -26337,7 +27809,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (i32.load ;; CHECK-NEXT: (local.get $1) @@ -26347,7 +27819,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u @@ -26362,7 +27836,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.add @@ -26377,7 +27853,7 @@ ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne ;; CHECK-NEXT: (i32.and @@ -26395,7 +27871,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -26444,7 +27920,7 @@ ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.load offset=12 ;; CHECK-NEXT: (local.get $1) @@ -26467,13 +27943,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -26482,7 +27960,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -26491,7 +27971,7 @@ ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.and @@ -26521,19 +28001,23 @@ ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -26547,10 +28031,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -26586,7 +28074,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.tee $5 @@ -26605,20 +28093,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $5 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $5 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -26634,7 +28126,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) @@ -26655,7 +28147,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) @@ -26671,8 +28163,10 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (i32.const 0) @@ -26683,7 +28177,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.tee $10 @@ -26693,7 +28187,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -26707,7 +28203,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -26721,7 +28219,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: (local.get $4) @@ -26734,14 +28232,16 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $1) @@ -26761,7 +28261,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $6) @@ -26770,7 +28270,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.and @@ -26796,7 +28296,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $12) @@ -26804,7 +28304,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -26818,20 +28320,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $12) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $12) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -26852,7 +28358,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=24 ;; CHECK-NEXT: (local.get $6) @@ -26869,20 +28377,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $5) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=16 - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -26893,32 +28405,36 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -26928,7 +28444,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -26945,7 +28461,9 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz @@ -26963,14 +28481,16 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.and @@ -26993,7 +28513,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $8) @@ -27001,7 +28521,7 @@ ;; CHECK-NEXT: (i32.const 200) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 188) ;; CHECK-NEXT: (local.tee $0 @@ -27031,7 +28551,9 @@ ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 196) @@ -27051,7 +28573,7 @@ ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: (local.tee $0 @@ -27105,7 +28627,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.load offset=12 ;; CHECK-NEXT: (local.get $8) @@ -27128,7 +28650,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) @@ -27136,7 +28658,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -27145,7 +28669,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27154,7 +28680,7 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.and @@ -27178,13 +28704,15 @@ ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $4) @@ -27192,7 +28720,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -27206,10 +28736,14 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $14 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $14 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27222,7 +28756,7 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.load offset=24 ;; CHECK-NEXT: (local.get $8) @@ -27238,7 +28772,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.tee $3 @@ -27257,20 +28791,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $9 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $do-once6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $do-once6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27286,7 +28824,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -27307,7 +28845,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -27325,8 +28863,10 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) @@ -27337,7 +28877,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.tee $4 @@ -27349,7 +28889,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.ne @@ -27363,7 +28905,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -27377,7 +28921,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $0) @@ -27390,14 +28934,16 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (local.get $8) @@ -27417,7 +28963,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $9) @@ -27426,7 +28972,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $9) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.and @@ -27446,7 +28992,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $6) @@ -27454,7 +29000,9 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eq @@ -27468,13 +29016,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $do-once4 @@ -27493,7 +29045,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store offset=24 ;; CHECK-NEXT: (local.get $9) @@ -27510,20 +29064,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=16 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=16 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27534,22 +29092,26 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (i32.store offset=20 - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.store offset=24 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.store offset=20 + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=24 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27580,15 +29142,17 @@ ;; CHECK-NEXT: (i32.const 196) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 184) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -27604,7 +29168,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.const 256) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (i32.shl @@ -27628,33 +29192,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (local.tee $3 - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 192) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.load - ;; CHECK-NEXT: (i32.const 192) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (local.set $15 - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $13 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $15 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $13 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 176) ;; CHECK-NEXT: (i32.or @@ -27703,93 +29271,101 @@ ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.gt_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.const 16777215) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 31) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 16777215) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (i32.const 14) - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (i32.or - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.tee $4 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1048320) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 8) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 520192) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 520192) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.tee $0 - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 245760) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 245760) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shr_u - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 15) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.shl - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) @@ -27824,7 +29400,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.shl ;; CHECK-NEXT: (local.get $3) @@ -27889,7 +29465,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) @@ -27907,8 +29483,10 @@ ;; CHECK-NEXT: (i32.const 192) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: (local.get $2) @@ -27954,7 +29532,7 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store offset=12 ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: (local.get $2) @@ -27976,11 +29554,13 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $_abort) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 180) ;; CHECK-NEXT: (i32.or @@ -28020,9 +29600,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i32.const 632) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 632) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $while-in17 @@ -28065,7 +29649,9 @@ (i32.eqz (local.get $0) ) - (return) + (then + (return) + ) ) (if (i32.lt_u @@ -28081,7 +29667,9 @@ ) ) ) - (call $_abort) + (then + (call $_abort) + ) ) (if (i32.eq @@ -28100,7 +29688,9 @@ ) (i32.const 1) ) - (call $_abort) + (then + (call $_abort) + ) ) (local.set $8 (i32.add @@ -28119,184 +29709,269 @@ (local.get $7) (i32.const 1) ) - (block - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) - ) - ) - (block - (local.set $7 - (i32.load + (then + (block + (local.set $2 (local.get $1) ) - ) - (if - (i32.eqz - (local.get $5) + (local.set $3 + (local.get $0) ) - (return) ) - (if - (i32.lt_u - (local.tee $1 - (i32.add - (local.get $1) - (i32.sub - (i32.const 0) - (local.get $7) + ) + (else + (block + (local.set $7 + (i32.load + (local.get $1) + ) + ) + (if + (i32.eqz + (local.get $5) + ) + (then + (return) + ) + ) + (if + (i32.lt_u + (local.tee $1 + (i32.add + (local.get $1) + (i32.sub + (i32.const 0) + (local.get $7) + ) ) ) + (local.get $11) + ) + (then + (call $_abort) ) - (local.get $11) - ) - (call $_abort) - ) - (local.set $0 - (i32.add - (local.get $7) - (local.get $0) ) - ) - (if - (i32.eq - (local.get $1) - (i32.load - (i32.const 196) + (local.set $0 + (i32.add + (local.get $7) + (local.get $0) ) ) - (block - (if - (i32.ne - (i32.and - (local.tee $3 - (i32.load - (local.tee $2 - (i32.add - (local.get $8) - (i32.const 4) + (if + (i32.eq + (local.get $1) + (i32.load + (i32.const 196) + ) + ) + (then + (block + (if + (i32.ne + (i32.and + (local.tee $3 + (i32.load + (local.tee $2 + (i32.add + (local.get $8) + (i32.const 4) + ) + ) ) ) + (i32.const 3) + ) + (i32.const 3) + ) + (then + (block + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + (br $do-once) ) ) - (i32.const 3) ) - (i32.const 3) - ) - (block - (local.set $2 + (i32.store + (i32.const 184) + (local.get $0) + ) + (i32.store + (local.get $2) + (i32.and + (local.get $3) + (i32.const -2) + ) + ) + (i32.store offset=4 (local.get $1) + (i32.or + (local.get $0) + (i32.const 1) + ) ) - (local.set $3 + (i32.store + (i32.add + (local.get $1) + (local.get $0) + ) (local.get $0) ) - (br $do-once) - ) - ) - (i32.store - (i32.const 184) - (local.get $0) - ) - (i32.store - (local.get $2) - (i32.and - (local.get $3) - (i32.const -2) + (return) ) ) - (i32.store offset=4 - (local.get $1) - (i32.or - (local.get $0) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $1) - (local.get $0) - ) - (local.get $0) - ) - (return) - ) - ) - (local.set $5 - (i32.shr_u - (local.get $7) - (i32.const 3) ) - ) - (if - (i32.lt_u - (local.get $7) - (i32.const 256) + (local.set $5 + (i32.shr_u + (local.get $7) + (i32.const 3) + ) ) - (block - (local.set $6 - (i32.load offset=12 - (local.get $1) - ) + (if + (i32.lt_u + (local.get $7) + (i32.const 256) ) - (if - (i32.ne - (local.tee $2 - (i32.load offset=8 + (then + (block + (local.set $6 + (i32.load offset=12 (local.get $1) ) ) - (local.tee $3 - (i32.add - (i32.shl - (local.get $5) - (i32.const 3) + (if + (i32.ne + (local.tee $2 + (i32.load offset=8 + (local.get $1) + ) + ) + (local.tee $3 + (i32.add + (i32.shl + (local.get $5) + (i32.const 3) + ) + (i32.const 216) + ) + ) + ) + (then + (block + (if + (i32.lt_u + (local.get $2) + (local.get $11) + ) + (then + (call $_abort) + ) + ) + (if + (i32.ne + (i32.load offset=12 + (local.get $2) + ) + (local.get $1) + ) + (then + (call $_abort) + ) + ) ) - (i32.const 216) ) ) - ) - (block (if - (i32.lt_u + (i32.eq + (local.get $6) (local.get $2) - (local.get $11) ) - (call $_abort) - ) - (if - (i32.ne - (i32.load offset=12 - (local.get $2) + (then + (block + (i32.store + (i32.const 176) + (i32.and + (i32.load + (i32.const 176) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $5) + ) + (i32.const -1) + ) + ) + ) + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + (br $do-once) ) - (local.get $1) ) - (call $_abort) ) - ) - ) - (if - (i32.eq - (local.get $6) - (local.get $2) - ) - (block - (i32.store - (i32.const 176) - (i32.and - (i32.load - (i32.const 176) + (if + (i32.eq + (local.get $6) + (local.get $3) + ) + (then + (local.set $4 + (i32.add + (local.get $6) + (i32.const 8) + ) ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $5) + ) + (else + (block + (if + (i32.lt_u + (local.get $6) + (local.get $11) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $3 + (i32.add + (local.get $6) + (i32.const 8) + ) + ) + ) + (local.get $1) + ) + (then + (local.set $4 + (local.get $3) + ) + ) + (else + (call $_abort) + ) ) - (i32.const -1) ) ) ) + (i32.store offset=12 + (local.get $2) + (local.get $6) + ) + (i32.store + (local.get $4) + (local.get $2) + ) (local.set $2 (local.get $1) ) @@ -28306,408 +29981,423 @@ (br $do-once) ) ) + ) + (local.set $12 + (i32.load offset=24 + (local.get $1) + ) + ) + (block $do-once0 (if (i32.eq - (local.get $6) - (local.get $3) - ) - (local.set $4 - (i32.add - (local.get $6) - (i32.const 8) - ) - ) - (block - (if - (i32.lt_u - (local.get $6) - (local.get $11) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $3 - (i32.add - (local.get $6) - (i32.const 8) - ) - ) - ) + (local.tee $4 + (i32.load offset=12 (local.get $1) ) - (local.set $4 - (local.get $3) - ) - (call $_abort) - ) - ) - ) - (i32.store offset=12 - (local.get $2) - (local.get $6) - ) - (i32.store - (local.get $4) - (local.get $2) - ) - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) - ) - (br $do-once) - ) - ) - (local.set $12 - (i32.load offset=24 - (local.get $1) - ) - ) - (block $do-once0 - (if - (i32.eq - (local.tee $4 - (i32.load offset=12 - (local.get $1) ) + (local.get $1) ) - (local.get $1) - ) - (block - (if - (i32.eqz - (local.tee $5 - (i32.load - (local.tee $4 - (i32.add - (local.tee $7 + (then + (block + (if + (i32.eqz + (local.tee $5 + (i32.load + (local.tee $4 (i32.add - (local.get $1) - (i32.const 16) + (local.tee $7 + (i32.add + (local.get $1) + (i32.const 16) + ) + ) + (i32.const 4) ) ) - (i32.const 4) ) ) ) - ) - ) - (if - (local.tee $5 - (i32.load - (local.get $7) - ) - ) - (local.set $4 - (local.get $7) - ) - (block - (local.set $6 - (i32.const 0) - ) - (br $do-once0) - ) - ) - ) - (loop $while-in - (if - (local.tee $7 - (i32.load - (local.tee $10 - (i32.add - (local.get $5) - (i32.const 20) + (then + (if + (local.tee $5 + (i32.load + (local.get $7) + ) + ) + (then + (local.set $4 + (local.get $7) + ) + ) + (else + (block + (local.set $6 + (i32.const 0) + ) + (br $do-once0) + ) ) ) ) ) - (block - (local.set $5 - (local.get $7) - ) - (local.set $4 - (local.get $10) + (loop $while-in + (if + (local.tee $7 + (i32.load + (local.tee $10 + (i32.add + (local.get $5) + (i32.const 20) + ) + ) + ) + ) + (then + (block + (local.set $5 + (local.get $7) + ) + (local.set $4 + (local.get $10) + ) + (br $while-in) + ) + ) ) - (br $while-in) - ) - ) - (if - (local.tee $7 - (i32.load - (local.tee $10 - (i32.add - (local.get $5) - (i32.const 16) + (if + (local.tee $7 + (i32.load + (local.tee $10 + (i32.add + (local.get $5) + (i32.const 16) + ) + ) + ) + ) + (then + (block + (local.set $5 + (local.get $7) + ) + (local.set $4 + (local.get $10) + ) + (br $while-in) ) ) ) ) - (block - (local.set $5 - (local.get $7) + (if + (i32.lt_u + (local.get $4) + (local.get $11) ) - (local.set $4 - (local.get $10) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $4) + (i32.const 0) + ) + (local.set $6 + (local.get $5) + ) + ) ) - (br $while-in) ) ) ) - (if - (i32.lt_u - (local.get $4) - (local.get $11) - ) - (call $_abort) + (else (block - (i32.store - (local.get $4) - (i32.const 0) - ) - (local.set $6 - (local.get $5) + (if + (i32.lt_u + (local.tee $10 + (i32.load offset=8 + (local.get $1) + ) + ) + (local.get $11) + ) + (then + (call $_abort) + ) ) - ) - ) - ) - (block - (if - (i32.lt_u - (local.tee $10 - (i32.load offset=8 + (if + (i32.ne + (i32.load + (local.tee $7 + (i32.add + (local.get $10) + (i32.const 12) + ) + ) + ) (local.get $1) ) + (then + (call $_abort) + ) ) - (local.get $11) - ) - (call $_abort) - ) - (if - (i32.ne - (i32.load - (local.tee $7 - (i32.add - (local.get $10) - (i32.const 12) + (if + (i32.eq + (i32.load + (local.tee $5 + (i32.add + (local.get $4) + (i32.const 8) + ) + ) ) + (local.get $1) ) - ) - (local.get $1) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $5 - (i32.add - (local.get $4) - (i32.const 8) + (then + (block + (i32.store + (local.get $7) + (local.get $4) + ) + (i32.store + (local.get $5) + (local.get $10) + ) + (local.set $6 + (local.get $4) + ) ) ) - ) - (local.get $1) - ) - (block - (i32.store - (local.get $7) - (local.get $4) - ) - (i32.store - (local.get $5) - (local.get $10) - ) - (local.set $6 - (local.get $4) + (else + (call $_abort) + ) ) ) - (call $_abort) ) ) ) - ) - (if - (local.get $12) - (block - (if - (i32.eq - (local.get $1) - (i32.load - (local.tee $4 - (i32.add - (i32.shl - (local.tee $5 - (i32.load offset=28 - (local.get $1) + (if + (local.get $12) + (then + (block + (if + (i32.eq + (local.get $1) + (i32.load + (local.tee $4 + (i32.add + (i32.shl + (local.tee $5 + (i32.load offset=28 + (local.get $1) + ) + ) + (i32.const 2) ) + (i32.const 480) ) - (i32.const 2) ) - (i32.const 480) ) ) - ) - ) - (block - (i32.store - (local.get $4) - (local.get $6) - ) - (if - (i32.eqz - (local.get $6) - ) - (block - (i32.store - (i32.const 180) - (i32.and - (i32.load - (i32.const 180) + (then + (block + (i32.store + (local.get $4) + (local.get $6) + ) + (if + (i32.eqz + (local.get $6) ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $5) + (then + (block + (i32.store + (i32.const 180) + (i32.and + (i32.load + (i32.const 180) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $5) + ) + (i32.const -1) + ) + ) + ) + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + (br $do-once) ) - (i32.const -1) ) ) ) - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) + ) + (else + (block + (if + (i32.lt_u + (local.get $12) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $4 + (i32.add + (local.get $12) + (i32.const 16) + ) + ) + ) + (local.get $1) + ) + (then + (i32.store + (local.get $4) + (local.get $6) + ) + ) + (else + (i32.store offset=20 + (local.get $12) + (local.get $6) + ) + ) + ) + (if + (i32.eqz + (local.get $6) + ) + (then + (block + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + (br $do-once) + ) + ) + ) ) - (br $do-once) ) ) - ) - (block (if (i32.lt_u - (local.get $12) - (i32.load - (i32.const 192) + (local.get $6) + (local.tee $5 + (i32.load + (i32.const 192) + ) ) ) - (call $_abort) + (then + (call $_abort) + ) + ) + (i32.store offset=24 + (local.get $6) + (local.get $12) ) (if - (i32.eq + (local.tee $7 (i32.load (local.tee $4 (i32.add - (local.get $12) + (local.get $1) (i32.const 16) ) ) ) - (local.get $1) - ) - (i32.store - (local.get $4) - (local.get $6) - ) - (i32.store offset=20 - (local.get $12) - (local.get $6) - ) - ) - (if - (i32.eqz - (local.get $6) ) - (block - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) + (then + (if + (i32.lt_u + (local.get $7) + (local.get $5) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=16 + (local.get $6) + (local.get $7) + ) + (i32.store offset=24 + (local.get $7) + (local.get $6) + ) + ) + ) ) - (br $do-once) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $6) - (local.tee $5 - (i32.load - (i32.const 192) ) ) - ) - (call $_abort) - ) - (i32.store offset=24 - (local.get $6) - (local.get $12) - ) - (if - (local.tee $7 - (i32.load + (if (local.tee $4 - (i32.add - (local.get $1) - (i32.const 16) + (i32.load offset=4 + (local.get $4) ) ) - ) - ) - (if - (i32.lt_u - (local.get $7) - (local.get $5) - ) - (call $_abort) - (block - (i32.store offset=16 - (local.get $6) - (local.get $7) + (then + (if + (i32.lt_u + (local.get $4) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=20 + (local.get $6) + (local.get $4) + ) + (i32.store offset=24 + (local.get $4) + (local.get $6) + ) + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + ) + ) + ) ) - (i32.store offset=24 - (local.get $7) - (local.get $6) + (else + (block + (local.set $2 + (local.get $1) + ) + (local.set $3 + (local.get $0) + ) + ) ) ) ) ) - (if - (local.tee $4 - (i32.load offset=4 - (local.get $4) - ) - ) - (if - (i32.lt_u - (local.get $4) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (i32.store offset=20 - (local.get $6) - (local.get $4) - ) - (i32.store offset=24 - (local.get $4) - (local.get $6) - ) - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) - ) - ) - ) + (else (block (local.set $2 (local.get $1) @@ -28718,628 +30408,710 @@ ) ) ) - (block - (local.set $2 - (local.get $1) - ) - (local.set $3 - (local.get $0) - ) - ) - ) - ) - ) - ) - (if - (i32.ge_u - (local.get $2) - (local.get $8) - ) - (call $_abort) - ) - (if - (i32.eqz - (i32.and - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add - (local.get $8) - (i32.const 4) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (call $_abort) - ) - (if - (i32.and - (local.get $1) - (i32.const 2) - ) - (block - (i32.store - (local.get $0) - (i32.and - (local.get $1) - (i32.const -2) - ) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $3) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $2) - (local.get $3) - ) - (local.get $3) - ) - ) - (block - (if - (i32.eq - (local.get $8) - (i32.load - (i32.const 200) - ) - ) - (block - (i32.store - (i32.const 188) - (local.tee $0 - (i32.add - (i32.load - (i32.const 188) - ) - (local.get $3) - ) - ) - ) - (i32.store - (i32.const 200) - (local.get $2) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $0) - (i32.const 1) - ) - ) - (if - (i32.ne - (local.get $2) - (i32.load - (i32.const 196) - ) - ) - (return) - ) - (i32.store - (i32.const 196) - (i32.const 0) - ) - (i32.store - (i32.const 184) - (i32.const 0) - ) - (return) - ) - ) - (if - (i32.eq - (local.get $8) - (i32.load - (i32.const 196) - ) - ) - (block - (i32.store - (i32.const 184) - (local.tee $0 - (i32.add - (i32.load - (i32.const 184) - ) - (local.get $3) - ) - ) - ) - (i32.store - (i32.const 196) - (local.get $2) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $0) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $2) - (local.get $0) + ) + ) + ) + ) + (if + (i32.ge_u + (local.get $2) + (local.get $8) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eqz + (i32.and + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.get $8) + (i32.const 4) + ) ) - (local.get $0) ) - (return) ) + (i32.const 1) ) - (local.set $5 - (i32.add + ) + (then + (call $_abort) + ) + ) + (if + (i32.and + (local.get $1) + (i32.const 2) + ) + (then + (block + (i32.store + (local.get $0) (i32.and (local.get $1) - (i32.const -8) + (i32.const -2) ) - (local.get $3) ) - ) - (local.set $3 - (i32.shr_u - (local.get $1) - (i32.const 3) + (i32.store offset=4 + (local.get $2) + (i32.or + (local.get $3) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (local.get $2) + (local.get $3) + ) + (local.get $3) ) ) - (block $do-once4 + ) + (else + (block (if - (i32.lt_u - (local.get $1) - (i32.const 256) - ) - (block - (local.set $4 - (i32.load offset=12 - (local.get $8) - ) + (i32.eq + (local.get $8) + (i32.load + (i32.const 200) ) - (if - (i32.ne - (local.tee $1 - (i32.load offset=8 - (local.get $8) - ) - ) + ) + (then + (block + (i32.store + (i32.const 188) (local.tee $0 (i32.add - (i32.shl - (local.get $3) - (i32.const 3) + (i32.load + (i32.const 188) ) - (i32.const 216) + (local.get $3) ) ) ) - (block - (if - (i32.lt_u - (local.get $1) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) + (i32.store + (i32.const 200) + (local.get $2) + ) + (i32.store offset=4 + (local.get $2) + (i32.or + (local.get $0) + (i32.const 1) ) - (if - (i32.ne - (i32.load offset=12 - (local.get $1) - ) - (local.get $8) + ) + (if + (i32.ne + (local.get $2) + (i32.load + (i32.const 196) ) - (call $_abort) + ) + (then + (return) ) ) - ) - (if - (i32.eq - (local.get $4) - (local.get $1) + (i32.store + (i32.const 196) + (i32.const 0) ) - (block - (i32.store - (i32.const 176) - (i32.and + (i32.store + (i32.const 184) + (i32.const 0) + ) + (return) + ) + ) + ) + (if + (i32.eq + (local.get $8) + (i32.load + (i32.const 196) + ) + ) + (then + (block + (i32.store + (i32.const 184) + (local.tee $0 + (i32.add (i32.load - (i32.const 176) - ) - (i32.xor - (i32.shl - (i32.const 1) - (local.get $3) - ) - (i32.const -1) + (i32.const 184) ) + (local.get $3) ) ) - (br $do-once4) ) - ) - (if - (i32.eq - (local.get $4) - (local.get $0) + (i32.store + (i32.const 196) + (local.get $2) ) - (local.set $14 - (i32.add - (local.get $4) - (i32.const 8) + (i32.store offset=4 + (local.get $2) + (i32.or + (local.get $0) + (i32.const 1) ) ) - (block - (if - (i32.lt_u - (local.get $4) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $4) - (i32.const 8) - ) - ) - ) - (local.get $8) - ) - (local.set $14 - (local.get $0) - ) - (call $_abort) + (i32.store + (i32.add + (local.get $2) + (local.get $0) ) + (local.get $0) ) + (return) ) - (i32.store offset=12 - (local.get $1) - (local.get $4) - ) - (i32.store - (local.get $14) + ) + ) + (local.set $5 + (i32.add + (i32.and (local.get $1) + (i32.const -8) ) + (local.get $3) ) - (block - (local.set $6 - (i32.load offset=24 - (local.get $8) - ) + ) + (local.set $3 + (i32.shr_u + (local.get $1) + (i32.const 3) + ) + ) + (block $do-once4 + (if + (i32.lt_u + (local.get $1) + (i32.const 256) ) - (block $do-once6 - (if - (i32.eq - (local.tee $0 - (i32.load offset=12 - (local.get $8) - ) - ) - (local.get $8) - ) - (block - (if - (i32.eqz - (local.tee $3 - (i32.load - (local.tee $0 - (i32.add - (local.tee $1 - (i32.add - (local.get $8) - (i32.const 16) - ) - ) - (i32.const 4) - ) - ) - ) + (then + (block + (local.set $4 + (i32.load offset=12 + (local.get $8) + ) + ) + (if + (i32.ne + (local.tee $1 + (i32.load offset=8 + (local.get $8) ) ) - (if - (local.tee $3 - (i32.load - (local.get $1) - ) - ) - (local.set $0 - (local.get $1) - ) - (block - (local.set $9 - (i32.const 0) + (local.tee $0 + (i32.add + (i32.shl + (local.get $3) + (i32.const 3) ) - (br $do-once6) + (i32.const 216) ) ) ) - (loop $while-in9 - (if - (local.tee $1 - (i32.load - (local.tee $4 - (i32.add - (local.get $3) - (i32.const 20) - ) - ) - ) - ) - (block - (local.set $3 + (then + (block + (if + (i32.lt_u (local.get $1) + (i32.load + (i32.const 192) + ) ) - (local.set $0 - (local.get $4) + (then + (call $_abort) ) - (br $while-in9) ) - ) - (if - (local.tee $1 - (i32.load - (local.tee $4 - (i32.add - (local.get $3) - (i32.const 16) - ) + (if + (i32.ne + (i32.load offset=12 + (local.get $1) ) + (local.get $8) ) - ) - (block - (local.set $3 - (local.get $1) - ) - (local.set $0 - (local.get $4) + (then + (call $_abort) ) - (br $while-in9) ) ) ) - (if - (i32.lt_u - (local.get $0) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) + ) + (if + (i32.eq + (local.get $4) + (local.get $1) + ) + (then (block (i32.store - (local.get $0) - (i32.const 0) - ) - (local.set $9 - (local.get $3) + (i32.const 176) + (i32.and + (i32.load + (i32.const 176) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $3) + ) + (i32.const -1) + ) + ) ) + (br $do-once4) ) ) ) - (block - (if - (i32.lt_u - (local.tee $4 - (i32.load offset=8 - (local.get $8) - ) - ) - (i32.load - (i32.const 192) + (if + (i32.eq + (local.get $4) + (local.get $0) + ) + (then + (local.set $14 + (i32.add + (local.get $4) + (i32.const 8) ) ) - (call $_abort) ) - (if - (i32.ne - (i32.load - (local.tee $1 - (i32.add - (local.get $4) - (i32.const 12) + (else + (block + (if + (i32.lt_u + (local.get $4) + (i32.load + (i32.const 192) ) ) + (then + (call $_abort) + ) ) - (local.get $8) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $3 - (i32.add + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $4) + (i32.const 8) + ) + ) + ) + (local.get $8) + ) + (then + (local.set $14 (local.get $0) - (i32.const 8) ) ) - ) - (local.get $8) - ) - (block - (i32.store - (local.get $1) - (local.get $0) - ) - (i32.store - (local.get $3) - (local.get $4) - ) - (local.set $9 - (local.get $0) + (else + (call $_abort) + ) ) ) - (call $_abort) ) ) + (i32.store offset=12 + (local.get $1) + (local.get $4) + ) + (i32.store + (local.get $14) + (local.get $1) + ) ) ) - (if - (local.get $6) + (else (block - (if - (i32.eq + (local.set $6 + (i32.load offset=24 (local.get $8) - (i32.load + ) + ) + (block $do-once6 + (if + (i32.eq (local.tee $0 - (i32.add - (i32.shl + (i32.load offset=12 + (local.get $8) + ) + ) + (local.get $8) + ) + (then + (block + (if + (i32.eqz (local.tee $3 - (i32.load offset=28 - (local.get $8) + (i32.load + (local.tee $0 + (i32.add + (local.tee $1 + (i32.add + (local.get $8) + (i32.const 16) + ) + ) + (i32.const 4) + ) + ) + ) + ) + ) + (then + (if + (local.tee $3 + (i32.load + (local.get $1) + ) + ) + (then + (local.set $0 + (local.get $1) + ) + ) + (else + (block + (local.set $9 + (i32.const 0) + ) + (br $do-once6) + ) + ) + ) + ) + ) + (loop $while-in9 + (if + (local.tee $1 + (i32.load + (local.tee $4 + (i32.add + (local.get $3) + (i32.const 20) + ) + ) + ) + ) + (then + (block + (local.set $3 + (local.get $1) + ) + (local.set $0 + (local.get $4) + ) + (br $while-in9) + ) + ) + ) + (if + (local.tee $1 + (i32.load + (local.tee $4 + (i32.add + (local.get $3) + (i32.const 16) + ) + ) + ) + ) + (then + (block + (local.set $3 + (local.get $1) + ) + (local.set $0 + (local.get $4) + ) + (br $while-in9) ) ) - (i32.const 2) ) - (i32.const 480) ) - ) - ) - ) - (block - (i32.store - (local.get $0) - (local.get $9) - ) - (if - (i32.eqz - (local.get $9) - ) - (block - (i32.store - (i32.const 180) - (i32.and + (if + (i32.lt_u + (local.get $0) (i32.load - (i32.const 180) + (i32.const 192) ) - (i32.xor - (i32.shl - (i32.const 1) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store + (local.get $0) + (i32.const 0) + ) + (local.set $9 (local.get $3) ) - (i32.const -1) ) ) ) - (br $do-once4) ) ) - ) - (block - (if - (i32.lt_u - (local.get $6) - (i32.load - (i32.const 192) + (else + (block + (if + (i32.lt_u + (local.tee $4 + (i32.load offset=8 + (local.get $8) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) ) - ) - (call $_abort) - ) - (if - (i32.eq - (i32.load - (local.tee $0 - (i32.add - (local.get $6) - (i32.const 16) + (if + (i32.ne + (i32.load + (local.tee $1 + (i32.add + (local.get $4) + (i32.const 12) + ) + ) ) + (local.get $8) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $3 + (i32.add + (local.get $0) + (i32.const 8) + ) + ) + ) + (local.get $8) + ) + (then + (block + (i32.store + (local.get $1) + (local.get $0) + ) + (i32.store + (local.get $3) + (local.get $4) + ) + (local.set $9 + (local.get $0) + ) + ) + ) + (else + (call $_abort) ) ) - (local.get $8) - ) - (i32.store - (local.get $0) - (local.get $9) - ) - (i32.store offset=20 - (local.get $6) - (local.get $9) - ) - ) - (br_if $do-once4 - (i32.eqz - (local.get $9) ) ) ) ) (if - (i32.lt_u - (local.get $9) - (local.tee $3 - (i32.load - (i32.const 192) - ) - ) - ) - (call $_abort) - ) - (i32.store offset=24 - (local.get $9) (local.get $6) - ) - (if - (local.tee $1 - (i32.load - (local.tee $0 - (i32.add + (then + (block + (if + (i32.eq (local.get $8) - (i32.const 16) + (i32.load + (local.tee $0 + (i32.add + (i32.shl + (local.tee $3 + (i32.load offset=28 + (local.get $8) + ) + ) + (i32.const 2) + ) + (i32.const 480) + ) + ) + ) + ) + (then + (block + (i32.store + (local.get $0) + (local.get $9) + ) + (if + (i32.eqz + (local.get $9) + ) + (then + (block + (i32.store + (i32.const 180) + (i32.and + (i32.load + (i32.const 180) + ) + (i32.xor + (i32.shl + (i32.const 1) + (local.get $3) + ) + (i32.const -1) + ) + ) + ) + (br $do-once4) + ) + ) + ) + ) + ) + (else + (block + (if + (i32.lt_u + (local.get $6) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + ) + (if + (i32.eq + (i32.load + (local.tee $0 + (i32.add + (local.get $6) + (i32.const 16) + ) + ) + ) + (local.get $8) + ) + (then + (i32.store + (local.get $0) + (local.get $9) + ) + ) + (else + (i32.store offset=20 + (local.get $6) + (local.get $9) + ) + ) + ) + (br_if $do-once4 + (i32.eqz + (local.get $9) + ) + ) + ) ) ) - ) - ) - (if - (i32.lt_u - (local.get $1) - (local.get $3) - ) - (call $_abort) - (block - (i32.store offset=16 - (local.get $9) - (local.get $1) + (if + (i32.lt_u + (local.get $9) + (local.tee $3 + (i32.load + (i32.const 192) + ) + ) + ) + (then + (call $_abort) + ) ) (i32.store offset=24 - (local.get $1) (local.get $9) + (local.get $6) ) - ) - ) - ) - (if - (local.tee $0 - (i32.load offset=4 - (local.get $0) - ) - ) - (if - (i32.lt_u - (local.get $0) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (i32.store offset=20 - (local.get $9) - (local.get $0) + (if + (local.tee $1 + (i32.load + (local.tee $0 + (i32.add + (local.get $8) + (i32.const 16) + ) + ) + ) + ) + (then + (if + (i32.lt_u + (local.get $1) + (local.get $3) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=16 + (local.get $9) + (local.get $1) + ) + (i32.store offset=24 + (local.get $1) + (local.get $9) + ) + ) + ) + ) + ) ) - (i32.store offset=24 - (local.get $0) - (local.get $9) + (if + (local.tee $0 + (i32.load offset=4 + (local.get $0) + ) + ) + (then + (if + (i32.lt_u + (local.get $0) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (i32.store offset=20 + (local.get $9) + (local.get $0) + ) + (i32.store offset=24 + (local.get $0) + (local.get $9) + ) + ) + ) + ) + ) ) ) ) @@ -29348,38 +31120,42 @@ ) ) ) - ) - (i32.store offset=4 - (local.get $2) - (i32.or - (local.get $5) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (local.get $2) - (local.get $5) - ) - (local.get $5) - ) - (if - (i32.eq + (i32.store offset=4 (local.get $2) - (i32.load - (i32.const 196) + (i32.or + (local.get $5) + (i32.const 1) ) ) - (block - (i32.store - (i32.const 184) + (i32.store + (i32.add + (local.get $2) (local.get $5) ) - (return) - ) - (local.set $3 (local.get $5) ) + (if + (i32.eq + (local.get $2) + (i32.load + (i32.const 196) + ) + ) + (then + (block + (i32.store + (i32.const 184) + (local.get $5) + ) + (return) + ) + ) + (else + (local.set $3 + (local.get $5) + ) + ) + ) ) ) ) @@ -29394,92 +31170,102 @@ (local.get $3) (i32.const 256) ) - (block - (local.set $1 - (i32.add - (i32.shl - (local.get $0) - (i32.const 3) - ) - (i32.const 216) - ) - ) - (if - (i32.and - (local.tee $3 - (i32.load - (i32.const 176) - ) - ) - (local.tee $0 + (then + (block + (local.set $1 + (i32.add (i32.shl - (i32.const 1) (local.get $0) + (i32.const 3) ) + (i32.const 216) ) ) (if - (i32.lt_u - (local.tee $0 + (i32.and + (local.tee $3 (i32.load - (local.tee $3 - (i32.add - (local.get $1) - (i32.const 8) - ) - ) + (i32.const 176) ) ) - (i32.load - (i32.const 192) - ) - ) - (call $_abort) - (block - (local.set $15 - (local.get $3) - ) - (local.set $13 - (local.get $0) + (local.tee $0 + (i32.shl + (i32.const 1) + (local.get $0) + ) ) ) - ) - (block - (i32.store - (i32.const 176) - (i32.or - (local.get $3) - (local.get $0) + (then + (if + (i32.lt_u + (local.tee $0 + (i32.load + (local.tee $3 + (i32.add + (local.get $1) + (i32.const 8) + ) + ) + ) + ) + (i32.load + (i32.const 192) + ) + ) + (then + (call $_abort) + ) + (else + (block + (local.set $15 + (local.get $3) + ) + (local.set $13 + (local.get $0) + ) + ) + ) ) ) - (local.set $15 - (i32.add - (local.get $1) - (i32.const 8) + (else + (block + (i32.store + (i32.const 176) + (i32.or + (local.get $3) + (local.get $0) + ) + ) + (local.set $15 + (i32.add + (local.get $1) + (i32.const 8) + ) + ) + (local.set $13 + (local.get $1) + ) ) ) - (local.set $13 - (local.get $1) - ) ) + (i32.store + (local.get $15) + (local.get $2) + ) + (i32.store offset=12 + (local.get $13) + (local.get $2) + ) + (i32.store offset=8 + (local.get $2) + (local.get $13) + ) + (i32.store offset=12 + (local.get $2) + (local.get $1) + ) + (return) ) - (i32.store - (local.get $15) - (local.get $2) - ) - (i32.store offset=12 - (local.get $13) - (local.get $2) - ) - (i32.store offset=8 - (local.get $2) - (local.get $13) - ) - (i32.store offset=12 - (local.get $2) - (local.get $1) - ) - (return) ) ) (local.set $4 @@ -29488,98 +31274,106 @@ (local.tee $5 (if (result i32) (local.tee $0 - (i32.shr_u - (local.get $3) - (i32.const 8) - ) - ) - (if (result i32) - (i32.gt_u - (local.get $3) - (i32.const 16777215) - ) - (i32.const 31) - (i32.or - (i32.and - (i32.shr_u - (local.get $3) - (i32.add - (local.tee $0 + (i32.shr_u + (local.get $3) + (i32.const 8) + ) + ) + (then + (if (result i32) + (i32.gt_u + (local.get $3) + (i32.const 16777215) + ) + (then + (i32.const 31) + ) + (else + (i32.or + (i32.and + (i32.shr_u + (local.get $3) (i32.add - (i32.sub - (i32.const 14) - (i32.or - (i32.or - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $0) - (local.tee $4 - (i32.and - (i32.shr_u - (i32.add - (local.get $0) - (i32.const 1048320) + (local.tee $0 + (i32.add + (i32.sub + (i32.const 14) + (i32.or + (i32.or + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $0) + (local.tee $4 + (i32.and + (i32.shr_u + (i32.add + (local.get $0) + (i32.const 1048320) + ) + (i32.const 16) + ) + (i32.const 8) ) - (i32.const 16) ) - (i32.const 8) ) ) + (i32.const 520192) ) + (i32.const 16) ) - (i32.const 520192) + (i32.const 4) ) - (i32.const 16) ) - (i32.const 4) + (local.get $4) ) - ) - (local.get $4) - ) - (local.tee $0 - (i32.and - (i32.shr_u - (i32.add - (local.tee $1 - (i32.shl - (local.get $1) - (local.get $0) + (local.tee $0 + (i32.and + (i32.shr_u + (i32.add + (local.tee $1 + (i32.shl + (local.get $1) + (local.get $0) + ) + ) + (i32.const 245760) ) + (i32.const 16) ) - (i32.const 245760) + (i32.const 2) ) - (i32.const 16) ) - (i32.const 2) ) ) + (i32.shr_u + (i32.shl + (local.get $1) + (local.get $0) + ) + (i32.const 15) + ) ) ) - (i32.shr_u - (i32.shl - (local.get $1) - (local.get $0) - ) - (i32.const 15) - ) + (i32.const 7) ) ) - (i32.const 7) + (i32.const 1) + ) + (i32.shl + (local.get $0) + (i32.const 1) ) ) - (i32.const 1) - ) - (i32.shl - (local.get $0) - (i32.const 1) ) ) ) - (i32.const 0) + (else + (i32.const 0) + ) ) ) (i32.const 2) @@ -29614,185 +31408,199 @@ ) ) ) - (block - (local.set $5 - (i32.shl - (local.get $3) - (select - (i32.const 0) - (i32.sub - (i32.const 25) - (i32.shr_u + (then + (block + (local.set $5 + (i32.shl + (local.get $3) + (select + (i32.const 0) + (i32.sub + (i32.const 25) + (i32.shr_u + (local.get $5) + (i32.const 1) + ) + ) + (i32.eq (local.get $5) - (i32.const 1) + (i32.const 31) ) ) - (i32.eq - (local.get $5) - (i32.const 31) - ) ) ) - ) - (local.set $0 - (i32.load - (local.get $4) + (local.set $0 + (i32.load + (local.get $4) + ) ) - ) - (block $__rjto$1 - (block $__rjti$1 - (loop $while-in15 - (br_if $__rjti$1 - (i32.eq - (i32.and - (i32.load offset=4 - (local.get $0) + (block $__rjto$1 + (block $__rjti$1 + (loop $while-in15 + (br_if $__rjti$1 + (i32.eq + (i32.and + (i32.load offset=4 + (local.get $0) + ) + (i32.const -8) ) - (i32.const -8) + (local.get $3) ) - (local.get $3) ) - ) - (local.set $4 - (i32.shl - (local.get $5) - (i32.const 1) + (local.set $4 + (i32.shl + (local.get $5) + (i32.const 1) + ) ) - ) - (if - (local.tee $1 - (i32.load - (local.tee $5 - (i32.add + (if + (local.tee $1 + (i32.load + (local.tee $5 (i32.add - (local.get $0) - (i32.const 16) - ) - (i32.shl - (i32.shr_u - (local.get $5) - (i32.const 31) + (i32.add + (local.get $0) + (i32.const 16) + ) + (i32.shl + (i32.shr_u + (local.get $5) + (i32.const 31) + ) + (i32.const 2) ) - (i32.const 2) ) ) ) ) - ) - (block - (local.set $5 - (local.get $4) - ) - (local.set $0 - (local.get $1) + (then + (block + (local.set $5 + (local.get $4) + ) + (local.set $0 + (local.get $1) + ) + (br $while-in15) + ) ) - (br $while-in15) - ) - ) - ) - (if - (i32.lt_u - (local.get $5) - (i32.load - (i32.const 192) ) ) - (call $_abort) - (block - (i32.store + (if + (i32.lt_u (local.get $5) - (local.get $2) - ) - (i32.store offset=24 - (local.get $2) - (local.get $0) + (i32.load + (i32.const 192) + ) ) - (i32.store offset=12 - (local.get $2) - (local.get $2) + (then + (call $_abort) ) - (i32.store offset=8 - (local.get $2) - (local.get $2) + (else + (block + (i32.store + (local.get $5) + (local.get $2) + ) + (i32.store offset=24 + (local.get $2) + (local.get $0) + ) + (i32.store offset=12 + (local.get $2) + (local.get $2) + ) + (i32.store offset=8 + (local.get $2) + (local.get $2) + ) + (br $do-once12) + ) ) - (br $do-once12) ) - ) - (br $__rjto$1) - ) - (if - (i32.and - (i32.ge_u - (local.tee $4 - (i32.load - (local.tee $1 - (i32.add - (local.get $0) - (i32.const 8) + (br $__rjto$1) + ) + (if + (i32.and + (i32.ge_u + (local.tee $4 + (i32.load + (local.tee $1 + (i32.add + (local.get $0) + (i32.const 8) + ) ) ) ) - ) - (local.tee $3 - (i32.load - (i32.const 192) + (local.tee $3 + (i32.load + (i32.const 192) + ) ) ) + (i32.ge_u + (local.get $0) + (local.get $3) + ) ) - (i32.ge_u - (local.get $0) - (local.get $3) - ) - ) - (block - (i32.store offset=12 - (local.get $4) - (local.get $2) - ) - (i32.store - (local.get $1) - (local.get $2) - ) - (i32.store offset=8 - (local.get $2) - (local.get $4) - ) - (i32.store offset=12 - (local.get $2) - (local.get $0) + (then + (block + (i32.store offset=12 + (local.get $4) + (local.get $2) + ) + (i32.store + (local.get $1) + (local.get $2) + ) + (i32.store offset=8 + (local.get $2) + (local.get $4) + ) + (i32.store offset=12 + (local.get $2) + (local.get $0) + ) + (i32.store offset=24 + (local.get $2) + (i32.const 0) + ) + ) ) - (i32.store offset=24 - (local.get $2) - (i32.const 0) + (else + (call $_abort) ) ) - (call $_abort) ) ) ) - (block - (i32.store - (i32.const 180) - (i32.or - (local.get $1) - (local.get $0) + (else + (block + (i32.store + (i32.const 180) + (i32.or + (local.get $1) + (local.get $0) + ) + ) + (i32.store + (local.get $4) + (local.get $2) + ) + (i32.store offset=24 + (local.get $2) + (local.get $4) + ) + (i32.store offset=12 + (local.get $2) + (local.get $2) + ) + (i32.store offset=8 + (local.get $2) + (local.get $2) ) - ) - (i32.store - (local.get $4) - (local.get $2) - ) - (i32.store offset=24 - (local.get $2) - (local.get $4) - ) - (i32.store offset=12 - (local.get $2) - (local.get $2) - ) - (i32.store offset=8 - (local.get $2) - (local.get $2) ) ) ) @@ -29810,9 +31618,13 @@ ) (if (local.get $0) - (return) - (local.set $0 - (i32.const 632) + (then + (return) + ) + (else + (local.set $0 + (i32.const 632) + ) ) ) (loop $while-in17 @@ -29934,7 +31746,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 20) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $1) @@ -29948,7 +31760,7 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.sub ;; CHECK-NEXT: (i32.add @@ -29964,7 +31776,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -30014,7 +31826,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $3) @@ -30037,7 +31849,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -30072,98 +31884,106 @@ (local.get $2) (i32.const 20) ) - (block - (local.set $1 - (i32.and - (local.get $1) - (i32.const 255) - ) - ) - (if - (local.tee $3 + (then + (block + (local.set $1 (i32.and - (local.get $0) - (i32.const 3) + (local.get $1) + (i32.const 255) ) ) - (block - (local.set $3 - (i32.sub - (i32.add - (local.get $0) - (i32.const 4) - ) - (local.get $3) + (if + (local.tee $3 + (i32.and + (local.get $0) + (i32.const 3) ) ) - (loop $while-in - (if - (i32.lt_s - (local.get $0) - (local.get $3) - ) - (block - (i32.store8 - (local.get $0) - (local.get $1) - ) - (local.set $0 + (then + (block + (local.set $3 + (i32.sub (i32.add (local.get $0) - (i32.const 1) + (i32.const 4) + ) + (local.get $3) + ) + ) + (loop $while-in + (if + (i32.lt_s + (local.get $0) + (local.get $3) + ) + (then + (block + (i32.store8 + (local.get $0) + (local.get $1) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (br $while-in) + ) ) ) - (br $while-in) ) ) ) ) - ) - (local.set $3 - (i32.or + (local.set $3 (i32.or (i32.or - (local.get $1) + (i32.or + (local.get $1) + (i32.shl + (local.get $1) + (i32.const 8) + ) + ) (i32.shl (local.get $1) - (i32.const 8) + (i32.const 16) ) ) (i32.shl (local.get $1) - (i32.const 16) + (i32.const 24) ) ) - (i32.shl - (local.get $1) - (i32.const 24) - ) - ) - ) - (local.set $5 - (i32.and - (local.get $4) - (i32.const -4) ) - ) - (loop $while-in1 - (if - (i32.lt_s - (local.get $0) - (local.get $5) + (local.set $5 + (i32.and + (local.get $4) + (i32.const -4) ) - (block - (i32.store + ) + (loop $while-in1 + (if + (i32.lt_s (local.get $0) - (local.get $3) + (local.get $5) ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 4) + (then + (block + (i32.store + (local.get $0) + (local.get $3) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 4) + ) + ) + (br $while-in1) ) ) - (br $while-in1) ) ) ) @@ -30175,18 +31995,20 @@ (local.get $0) (local.get $4) ) - (block - (i32.store8 - (local.get $0) - (local.get $1) - ) - (local.set $0 - (i32.add + (then + (block + (i32.store8 (local.get $0) - (i32.const 1) + (local.get $1) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) ) + (br $while-in3) ) - (br $while-in3) ) ) ) @@ -30201,7 +32023,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $tempRet0 ;; CHECK-NEXT: (i32.shr_u ;; CHECK-NEXT: (local.get $1) @@ -30251,33 +32073,35 @@ (local.get $2) (i32.const 32) ) - (block - (global.set $tempRet0 - (i32.shr_u - (local.get $1) - (local.get $2) - ) - ) - (return - (i32.or + (then + (block + (global.set $tempRet0 (i32.shr_u - (local.get $0) + (local.get $1) (local.get $2) ) - (i32.shl - (i32.and - (local.get $1) - (i32.sub - (i32.shl + ) + (return + (i32.or + (i32.shr_u + (local.get $0) + (local.get $2) + ) + (i32.shl + (i32.and + (local.get $1) + (i32.sub + (i32.shl + (i32.const 1) + (local.get $2) + ) (i32.const 1) - (local.get $2) ) - (i32.const 1) ) - ) - (i32.sub - (i32.const 32) - (local.get $2) + (i32.sub + (i32.const 32) + (local.get $2) + ) ) ) ) @@ -30301,7 +32125,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $tempRet0 ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (i32.shl @@ -30357,41 +32181,43 @@ (local.get $2) (i32.const 32) ) - (block - (global.set $tempRet0 - (i32.or - (i32.shl - (local.get $1) - (local.get $2) - ) - (i32.shr_u - (i32.and - (local.get $0) - (i32.shl - (i32.sub - (i32.shl + (then + (block + (global.set $tempRet0 + (i32.or + (i32.shl + (local.get $1) + (local.get $2) + ) + (i32.shr_u + (i32.and + (local.get $0) + (i32.shl + (i32.sub + (i32.shl + (i32.const 1) + (local.get $2) + ) (i32.const 1) + ) + (i32.sub + (i32.const 32) (local.get $2) ) - (i32.const 1) - ) - (i32.sub - (i32.const 32) - (local.get $2) ) ) - ) - (i32.sub - (i32.const 32) - (local.get $2) + (i32.sub + (i32.const 32) + (local.get $2) + ) ) ) ) - ) - (return - (i32.shl - (local.get $0) - (local.get $2) + (return + (i32.shl + (local.get $0) + (local.get $2) + ) ) ) ) @@ -30414,11 +32240,13 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 4096) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (call $_emscripten_memcpy_big - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (call $_emscripten_memcpy_big + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -30436,20 +32264,22 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (loop $while-in ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.and ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.store8 @@ -30486,7 +32316,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.load @@ -30523,7 +32353,7 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.load8_s @@ -30561,11 +32391,13 @@ (local.get $2) (i32.const 4096) ) - (return - (call $_emscripten_memcpy_big - (local.get $0) - (local.get $1) - (local.get $2) + (then + (return + (call $_emscripten_memcpy_big + (local.get $0) + (local.get $1) + (local.get $2) + ) ) ) ) @@ -30583,82 +32415,90 @@ (i32.const 3) ) ) - (block - (loop $while-in - (if - (i32.and - (local.get $0) - (i32.const 3) - ) - (block - (if - (i32.eqz - (local.get $2) - ) - (return - (local.get $3) - ) - ) - (i32.store8 + (then + (block + (loop $while-in + (if + (i32.and (local.get $0) - (i32.load8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 1) - ) + (i32.const 3) ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 1) + (then + (block + (if + (i32.eqz + (local.get $2) + ) + (then + (return + (local.get $3) + ) + ) + ) + (i32.store8 + (local.get $0) + (i32.load8_s + (local.get $1) + ) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 1) + ) + ) + (br $while-in) ) ) - (br $while-in) ) ) - ) - (loop $while-in1 - (if - (i32.ge_s - (local.get $2) - (i32.const 4) - ) - (block - (i32.store - (local.get $0) - (i32.load - (local.get $1) - ) - ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 4) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 4) - ) + (loop $while-in1 + (if + (i32.ge_s + (local.get $2) + (i32.const 4) ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 4) + (then + (block + (i32.store + (local.get $0) + (i32.load + (local.get $1) + ) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 4) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 4) + ) + ) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 4) + ) + ) + (br $while-in1) ) ) - (br $while-in1) ) ) ) @@ -30670,32 +32510,34 @@ (local.get $2) (i32.const 0) ) - (block - (i32.store8 - (local.get $0) - (i32.load8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.add + (then + (block + (i32.store8 (local.get $0) - (i32.const 1) + (i32.load8_s + (local.get $1) + ) ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 1) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) ) - ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 1) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 1) + ) ) + (br $while-in3) ) - (br $while-in3) ) ) ) @@ -30809,11 +32651,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $r) - ;; CHECK-NEXT: (i64.store - ;; CHECK-NEXT: (local.get $r) - ;; CHECK-NEXT: (i64.rem_u - ;; CHECK-NEXT: (local.get $x64) - ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i64.store + ;; CHECK-NEXT: (local.get $r) + ;; CHECK-NEXT: (i64.rem_u + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -30866,11 +32710,13 @@ ) (if (local.get $r) - (i64.store - (local.get $r) - (i64.rem_u - (local.get $x64) - (local.get $y64) + (then + (i64.store + (local.get $r) + (i64.rem_u + (local.get $x64) + (local.get $y64) + ) ) ) ) diff --git a/test/lit/passes/inlining_enable-tail-call.wast b/test/lit/passes/inlining_enable-tail-call.wast index ff1a9efbf6c..d2d7772cdd4 100644 --- a/test/lit/passes/inlining_enable-tail-call.wast +++ b/test/lit/passes/inlining_enable-tail-call.wast @@ -294,8 +294,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $hangLimit) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 54) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 54) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $hangLimit @@ -308,27 +310,35 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (block $__inlined_func$func_3 (result i32) - ;; CHECK-NEXT: (local.set $8 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (local.get $8) - ;; CHECK-NEXT: (local.tee $8 - ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (block $__inlined_func$func_3 (result i32) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: (local.tee $8 + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $label$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label$0) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -346,8 +356,10 @@ (i32.eqz (global.get $hangLimit) ) - (return - (i32.const 54) + (then + (return + (i32.const 54) + ) ) ) (global.set $hangLimit @@ -360,14 +372,22 @@ (i32.eqz (if (result i32) (i32.const 1) - (if (result i32) - (i32.eqz - (call $func_3) + (then + (if (result i32) + (i32.eqz + (call $func_3) + ) + (then + (br $label$0) + ) + (else + (i32.const 0) + ) ) - (br $label$0) - (i32.const 0) ) - (unreachable) + (else + (unreachable) + ) ) ) ) @@ -396,8 +416,12 @@ ;; CHECK-NEXT: (call_indirect (type $T) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -410,8 +434,12 @@ (call_indirect (type $T) (if (result i32) ;; if copy must preserve the forced type (i32.const 0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) (i32.const 1) ) @@ -653,7 +681,9 @@ (func $2 (; 2 ;) (type $6) (if (global.get $global$0) - (return) + (then + (return) + ) ) (global.set $global$0 (i32.const 1) @@ -662,7 +692,9 @@ (func $13 (; 13 ;) (type $6) (if (global.get $global$0) - (unreachable) + (then + (unreachable) + ) ) (return_call $2) ) @@ -673,7 +705,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block @@ -681,7 +715,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (br $__inlined_func$2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $global$0 ;; CHECK-NEXT: (i32.const 1) @@ -714,26 +750,34 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $i) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (block $__inlined_func$is_odd (result i32) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $i) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return_call $is_even + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (block $__inlined_func$is_odd (result i32) + ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $i) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return_call $is_even + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -742,11 +786,15 @@ (func $is_even (param $i i32) (result i32) (if (result i32) (i32.eqz (local.get $i)) - (i32.const 1) - (return_call $is_odd - (i32.sub - (local.get $i) - (i32.const 1) + (then + (i32.const 1) + ) + (else + (return_call $is_odd + (i32.sub + (local.get $i) + (i32.const 1) + ) ) ) ) @@ -754,11 +802,15 @@ (func $is_odd (param $i i32) (result i32) (if (result i32) (i32.eqz (local.get $i)) - (i32.const 0) - (return_call $is_even - (i32.sub - (local.get $i) - (i32.const 1) + (then + (i32.const 0) + ) + (else + (return_call $is_even + (i32.sub + (local.get $i) + (i32.const 1) + ) ) ) ) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index 145a69016c3..b34f74cf4f5 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -38,7 +38,9 @@ ;; the rest will be outlined into a new function with suffix "outlined". (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -59,8 +61,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -74,8 +78,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -89,8 +95,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$maybe-work-hard + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -113,10 +121,12 @@ ;; As above, but all we have is an if. (if (local.get $x) - (loop $l - (call $import) - (br_if $l - (local.get $x) + (then + (loop $l + (call $import) + (br_if $l + (local.get $x) + ) ) ) ) @@ -132,8 +142,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (call $byn-split-outlined-B$just-if - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$just-if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -145,8 +157,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (call $byn-split-outlined-B$just-if - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$just-if + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -161,10 +175,16 @@ ;; CHECK-NEXT: (block $toplevel ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (br $toplevel) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $toplevel) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -173,13 +193,19 @@ (block $toplevel (if (local.get $x) - (block - (if - (local.get $x) - ;; A br to the toplevel block prevents us from outlining this code, - ;; as we can't outline a br without its target. - (br $toplevel) - (call $import) + (then + (block + (if + (local.get $x) + ;; A br to the toplevel block prevents us from outlining this code, + ;; as we can't outline a br without its target. + (then + (br $toplevel) + ) + (else + (call $import) + ) + ) ) ) ) @@ -203,7 +229,9 @@ ;; We can inline despite the non-initial, non-defaultable param. (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -224,7 +252,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (br $__inlined_func$nondefaultable-param$5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$nondefaultable-param$5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -243,7 +273,9 @@ ;; condition. (if (local.get $y) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -273,10 +305,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$many-params - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$many-params + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -296,10 +330,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$many-params - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$many-params + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -321,7 +357,9 @@ (i32.eqz (local.get $x) ) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -343,8 +381,10 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-eqz - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-eqz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -360,8 +400,10 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-eqz - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-eqz + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -376,7 +418,9 @@ (if ;; A global read, also worth splitting. (global.get $glob) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -391,7 +435,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $glob) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-global) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-global) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -401,7 +447,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $glob) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-global) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-global) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -417,7 +465,9 @@ (ref.is_null (local.get $x) ) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -439,8 +489,10 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-ref.is - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-ref.is + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -456,8 +508,10 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-ref.is - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$condition-ref.is + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -474,7 +528,9 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -488,7 +544,9 @@ (local.get $x) (local.get $x) ) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -514,7 +572,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -527,7 +587,9 @@ (i32.eqz (unreachable) ) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -551,7 +613,9 @@ ;; CHECK: (func $start-used-globally (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $glob) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -565,7 +629,9 @@ ;; it). (if (global.get $glob) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -580,7 +646,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $glob) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$start-used-globally) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$start-used-globally) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -590,7 +658,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $glob) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$start-used-globally) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$start-used-globally) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -606,7 +676,9 @@ ;; that is split out. (if (global.get $glob) - (return) + (then + (return) + ) ) ) @@ -615,7 +687,9 @@ ;; CHECK-NEXT: (block $__inlined_func$inlineable$16 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $glob) - ;; CHECK-NEXT: (br $__inlined_func$inlineable$16) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$inlineable$16) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -623,7 +697,9 @@ ;; CHECK-NEXT: (block $__inlined_func$inlineable$17 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $glob) - ;; CHECK-NEXT: (br $__inlined_func$inlineable$17) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$inlineable$17) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -637,7 +713,9 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -650,7 +728,9 @@ (nop) (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -674,8 +754,12 @@ ;; CHECK: (func $if-else (type $1) (param $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -686,8 +770,12 @@ ;; An else in the if prevents us from recognizing the pattern we want. (if (local.get $x) - (return) - (nop) + (then + (return) + ) + (else + (nop) + ) ) (loop $l (call $import) @@ -711,7 +799,9 @@ ;; CHECK: (func $if-non-return (type $1) (param $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (call $import) @@ -722,7 +812,9 @@ ;; Something other than a return in the if body prevents us from outlining. (if (local.get $x) - (unreachable) + (then + (unreachable) + ) ) (loop $l (call $import) @@ -748,7 +840,9 @@ ;; function after us. (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -768,8 +862,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$colliding-name_67 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$colliding-name_67 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -783,8 +879,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$colliding-name_67 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$colliding-name_67 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -817,9 +915,11 @@ (ref.is_null (local.get $x) ) - (block - (call $import) - (unreachable) + (then + (block + (call $import) + (unreachable) + ) ) ) (local.get $x) @@ -839,9 +939,11 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$error-if-null$20 - ;; CHECK-NEXT: (call $byn-split-outlined-B$error-if-null - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$error-if-null$20 + ;; CHECK-NEXT: (call $byn-split-outlined-B$error-if-null + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -861,9 +963,11 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$error-if-null$21 - ;; CHECK-NEXT: (call $byn-split-outlined-B$error-if-null - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$error-if-null$21 + ;; CHECK-NEXT: (call $byn-split-outlined-B$error-if-null + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -883,7 +987,7 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -896,9 +1000,11 @@ (ref.is_null (local.get $x) ) - (block - (call $import) - (unreachable) + (then + (block + (call $import) + (unreachable) + ) ) ) (nop) ;; An extra operation here prevents us from identifying the pattern. @@ -927,7 +1033,7 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -939,9 +1045,11 @@ (ref.is_null (local.get $x) ) - (block - (call $import) - (unreachable) + (then + (block + (call $import) + (unreachable) + ) ) ) (unreachable) ;; This prevents us from optimizing @@ -972,11 +1080,13 @@ ;; It is ok if the body is not unreachable (so long as it contains no ;; returns). We will optimize this, and just do a call to the outlined ;; code, without a return of a value here. - (block - ;; We need to have a loop here to avoid normal inlining from kicking in - ;; on the outlined code. - (loop $loop - (call $import) + (then + (block + ;; We need to have a loop here to avoid normal inlining from kicking in + ;; on the outlined code. + (loop $loop + (call $import) + ) ) ) ) @@ -997,8 +1107,10 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$reachable-if-body - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$reachable-if-body + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) @@ -1017,8 +1129,10 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$reachable-if-body - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$reachable-if-body + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) @@ -1038,7 +1152,9 @@ (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (local.get $x) ) @@ -1057,7 +1173,9 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -1075,7 +1193,9 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -1096,12 +1216,18 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) @@ -1111,13 +1237,19 @@ (ref.is_null (local.get $x) ) - (if - (i32.const 1) - ;; The return here prevents the optimization. - (return - (local.get $x) + (then + (if + (i32.const 1) + ;; The return here prevents the optimization. + (then + (return + (local.get $x) + ) + ) + (else + (call $import) + ) ) - (call $import) ) ) (local.get $x) @@ -1147,9 +1279,11 @@ ) ;; The if body is unreachable, but the function has no returned value. ;; When we outline this code, we should not try to return a value. - (block - (call $import) - (unreachable) + (then + (block + (call $import) + (unreachable) + ) ) ) ) @@ -1166,8 +1300,10 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$unreachable-if-body-no-result - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$unreachable-if-body-no-result + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1181,8 +1317,10 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$unreachable-if-body-no-result - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$unreachable-if-body-no-result + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1198,17 +1336,21 @@ (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) ;; A second if. We can outline both if bodies. (if (ref.is_null (local.get $x) ) - (loop $x - (call $import) - (br_if $x - (global.get $glob) + (then + (loop $x + (call $import) + (br_if $x + (global.get $glob) + ) ) ) ) @@ -1231,19 +1373,23 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-B$multi-if$30 - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-B$multi-if$30 + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$multi-if_76 - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$multi-if_76 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $0) @@ -1262,19 +1408,23 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-B$multi-if$31 - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-B$multi-if$31 + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-B$multi-if_76 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-B$multi-if_76 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) @@ -1293,31 +1443,41 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -1327,31 +1487,41 @@ (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (if (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (if (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (if (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (if (ref.is_null (local.get $x) ) - (call $import) + (then + (call $import) + ) ) (local.get $x) ) @@ -1468,7 +1638,9 @@ ;; CHECK: (func $0 (type $none_=>_none) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global$0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block $__inlined_func$1 @@ -1489,7 +1661,9 @@ ;; A function that is a good candidate to partially inline. (if (global.get $global$0) - (return) + (then + (return) + ) ) (call $1) (call $1) @@ -1501,37 +1675,43 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-A$0$3 - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $__inlined_func$byn-split-outlined-A$0$3 ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $__inlined_func$1 - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $__inlined_func$1 ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$0$4 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$0$4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $__inlined_func$1$1 - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $__inlined_func$1$1 ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block - ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$0$5 - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $__inlined_func$byn-split-inlineable-A$0$5 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1668,7 +1848,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $byn-split-outlined-A$0_21) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (call $byn-split-outlined-A$0_21) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1684,7 +1866,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $byn-split-outlined-A$0_21) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (call $byn-split-outlined-A$0_21) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1703,7 +1887,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $byn-split-outlined-A$0_22) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (call $byn-split-outlined-A$0_22) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1719,7 +1905,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (call $byn-split-outlined-A$0_22) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (call $byn-split-outlined-A$0_22) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1752,7 +1940,9 @@ ;; case, to avoid wasted work. (if (local.get $x) - (return) + (then + (return) + ) ) ;; 6x3 = 18 items, close to the default size limit of 20. With the if, we ;; hit that limit and are too big. But if we did partial inlining then the @@ -1779,7 +1969,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (br $__inlined_func$middle-size-A) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$middle-size-A) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) @@ -1819,7 +2011,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (br $__inlined_func$middle-size-A$1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$middle-size-A$1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) @@ -1869,7 +2063,9 @@ ;; it. (if (local.get $x) - (return) + (then + (return) + ) ) ;; 6x4 = 24 items, which is more than the inlining limit. (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) @@ -1890,8 +2086,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$big-size-A - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$big-size-A + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1905,8 +2103,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $byn-split-outlined-A$big-size-A - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $byn-split-outlined-A$big-size-A + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1926,11 +2126,13 @@ ;; As above, but for pattern B and not A. (if (local.get $x) - (block - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (unreachable) + (then + (block + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (unreachable) + ) ) ) (local.get $x) @@ -1948,7 +2150,7 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1993,7 +2195,7 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2049,12 +2251,14 @@ ;; it. (if (local.get $x) - (block - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) - (unreachable) + (then + (block + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0)) + (unreachable) + ) ) ) (local.get $x) @@ -2072,9 +2276,11 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$big-size-B$6 - ;; CHECK-NEXT: (call $byn-split-outlined-B$big-size-B - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$big-size-B$6 + ;; CHECK-NEXT: (call $byn-split-outlined-B$big-size-B + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2092,9 +2298,11 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$big-size-B$7 - ;; CHECK-NEXT: (call $byn-split-outlined-B$big-size-B - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $__inlined_func$byn-split-inlineable-B$big-size-B$7 + ;; CHECK-NEXT: (call $byn-split-outlined-B$big-size-B + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/inlining_splitting_basics.wast b/test/lit/passes/inlining_splitting_basics.wast index 017e043a7f2..fe07a3926cb 100644 --- a/test/lit/passes/inlining_splitting_basics.wast +++ b/test/lit/passes/inlining_splitting_basics.wast @@ -33,7 +33,9 @@ ;; NORMAL_: (func $pattern-A (type $1) (param $x i32) ;; NORMAL_-NEXT: (if ;; NORMAL_-NEXT: (local.get $x) - ;; NORMAL_-NEXT: (return) + ;; NORMAL_-NEXT: (then + ;; NORMAL_-NEXT: (return) + ;; NORMAL_-NEXT: ) ;; NORMAL_-NEXT: ) ;; NORMAL_-NEXT: (loop $l ;; NORMAL_-NEXT: (call $import) @@ -43,7 +45,9 @@ (func $pattern-A (param $x i32) (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -71,8 +75,10 @@ ;; PARTIAL-NEXT: (i32.eqz ;; PARTIAL-NEXT: (local.get $0) ;; PARTIAL-NEXT: ) - ;; PARTIAL-NEXT: (call $byn-split-outlined-A$pattern-A - ;; PARTIAL-NEXT: (local.get $0) + ;; PARTIAL-NEXT: (then + ;; PARTIAL-NEXT: (call $byn-split-outlined-A$pattern-A + ;; PARTIAL-NEXT: (local.get $0) + ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) @@ -86,8 +92,10 @@ ;; PARTIAL-NEXT: (i32.eqz ;; PARTIAL-NEXT: (local.get $1) ;; PARTIAL-NEXT: ) - ;; PARTIAL-NEXT: (call $byn-split-outlined-A$pattern-A - ;; PARTIAL-NEXT: (local.get $1) + ;; PARTIAL-NEXT: (then + ;; PARTIAL-NEXT: (call $byn-split-outlined-A$pattern-A + ;; PARTIAL-NEXT: (local.get $1) + ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) @@ -109,7 +117,7 @@ ;; NORMAL_-NEXT: (i32.eqz ;; NORMAL_-NEXT: (local.get $x) ;; NORMAL_-NEXT: ) - ;; NORMAL_-NEXT: (block + ;; NORMAL_-NEXT: (then ;; NORMAL_-NEXT: (call $import) ;; NORMAL_-NEXT: (unreachable) ;; NORMAL_-NEXT: ) @@ -121,9 +129,11 @@ (i32.eqz (local.get $x) ) - (block - (call $import) - (unreachable) + (then + (block + (call $import) + (unreachable) + ) ) ) (local.get $x) @@ -155,9 +165,11 @@ ;; PARTIAL-NEXT: (i32.eqz ;; PARTIAL-NEXT: (local.get $0) ;; PARTIAL-NEXT: ) - ;; PARTIAL-NEXT: (br $__inlined_func$byn-split-inlineable-B$pattern-B$2 - ;; PARTIAL-NEXT: (call $byn-split-outlined-B$pattern-B - ;; PARTIAL-NEXT: (local.get $0) + ;; PARTIAL-NEXT: (then + ;; PARTIAL-NEXT: (br $__inlined_func$byn-split-inlineable-B$pattern-B$2 + ;; PARTIAL-NEXT: (call $byn-split-outlined-B$pattern-B + ;; PARTIAL-NEXT: (local.get $0) + ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) @@ -177,9 +189,11 @@ ;; PARTIAL-NEXT: (i32.eqz ;; PARTIAL-NEXT: (local.get $1) ;; PARTIAL-NEXT: ) - ;; PARTIAL-NEXT: (br $__inlined_func$byn-split-inlineable-B$pattern-B$3 - ;; PARTIAL-NEXT: (call $byn-split-outlined-B$pattern-B - ;; PARTIAL-NEXT: (local.get $1) + ;; PARTIAL-NEXT: (then + ;; PARTIAL-NEXT: (br $__inlined_func$byn-split-inlineable-B$pattern-B$3 + ;; PARTIAL-NEXT: (call $byn-split-outlined-B$pattern-B + ;; PARTIAL-NEXT: (local.get $1) + ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) ;; PARTIAL-NEXT: ) diff --git a/test/lit/passes/j2cl-inline.wast b/test/lit/passes/j2cl-inline.wast index 263be0726fc..9b6d4127b9a 100644 --- a/test/lit/passes/j2cl-inline.wast +++ b/test/lit/passes/j2cl-inline.wast @@ -24,7 +24,9 @@ ;; CHECK: (func $clinit-non-trivial__@Zoo (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $$class-initialized@Zoo) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $$class-initialized@Zoo ;; CHECK-NEXT: (i32.const 1) @@ -32,7 +34,9 @@ ;; CHECK-NEXT: ) (func $clinit-non-trivial__@Zoo (if (global.get $$class-initialized@Zoo) - (return) + (then + (return) + ) ) (global.set $$class-initialized@Zoo (i32.const 1)) ) diff --git a/test/lit/passes/local-cse.wast b/test/lit/passes/local-cse.wast index c0e4c9b59cc..c38ca243a72 100644 --- a/test/lit/passes/local-cse.wast +++ b/test/lit/passes/local-cse.wast @@ -31,7 +31,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add @@ -77,7 +79,7 @@ (drop (i32.add (i32.const 1) (i32.const 2)) ) - (if (i32.const 0) (nop)) + (if (i32.const 0) (then (nop))) ;; This add is after an if, which means we are no longer in the same basic ;; block - which means we cannot optimize it with the previous identical ;; adds. @@ -399,13 +401,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -420,17 +426,21 @@ (if (i32.const 0) ;; This add is dominated by the above, so we can use a tee of it. - (drop - (i32.add - (i32.const 2) - (i32.const 3) + (then + (drop + (i32.add + (i32.const 2) + (i32.const 3) + ) ) ) ;; We could optimize this add as well, but do not yet. TODO - (drop - (i32.add - (i32.const 2) - (i32.const 3) + (else + (drop + (i32.add + (i32.const 2) + (i32.const 3) + ) ) ) ) diff --git a/test/lit/passes/local-subtyping-nn.wast b/test/lit/passes/local-subtyping-nn.wast index 04cade7e0e8..3754230d82f 100644 --- a/test/lit/passes/local-subtyping-nn.wast +++ b/test/lit/passes/local-subtyping-nn.wast @@ -44,9 +44,11 @@ ;; CHECK-NEXT: (local $x nullref) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $i) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -59,8 +61,10 @@ (if (local.get $i) ;; The only set to this local uses a non-nullable type. - (local.set $x - (ref.as_non_null (ref.null $struct)) + (then + (local.set $x + (ref.as_non_null (ref.null $struct)) + ) ) ) (drop diff --git a/test/lit/passes/local-subtyping.wast b/test/lit/passes/local-subtyping.wast index 17ad5dc135e..74f9d53a82f 100644 --- a/test/lit/passes/local-subtyping.wast +++ b/test/lit/passes/local-subtyping.wast @@ -30,11 +30,15 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref i31)) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (ref.i31 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (ref.i31 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -55,8 +59,12 @@ (drop (if (result anyref) (local.get $x) - (ref.i31 (i32.const 0)) - (ref.i31 (i32.const 1)) + (then + (ref.i31 (i32.const 0)) + ) + (else + (ref.i31 (i32.const 1)) + ) ) ) (drop @@ -324,8 +332,10 @@ ;; CHECK-NEXT: (local $x (ref null $2)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $i) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (ref.func $uses-default) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (ref.func $uses-default) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -337,7 +347,9 @@ (if (local.get $i) ;; The only set to this local uses a more specific type than funcref. - (local.set $x (ref.func $uses-default)) + (then + (local.set $x (ref.func $uses-default)) + ) ) (drop ;; This get may use the default value, but it is ok to have a null of a @@ -472,8 +484,10 @@ ;; CHECK-NEXT: (local $x (ref null $0)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (ref.func $become-non-nullable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (ref.func $become-non-nullable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -487,8 +501,10 @@ ;; though.) (if (i32.const 1) - (local.set $x - (ref.func $become-non-nullable) + (then + (local.set $x + (ref.func $become-non-nullable) + ) ) ) (drop diff --git a/test/lit/passes/memory-packing_all-features.wast b/test/lit/passes/memory-packing_all-features.wast index 1f0886d66a8..cf6c2aeef49 100644 --- a/test/lit/passes/memory-packing_all-features.wast +++ b/test/lit/passes/memory-packing_all-features.wast @@ -118,7 +118,9 @@ ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -186,7 +188,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -511,7 +515,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -573,7 +579,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_2) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -624,7 +632,9 @@ ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -763,7 +773,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (local.get $0) @@ -881,7 +893,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_2) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -993,7 +1007,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_3) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -1055,7 +1071,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_4) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -1112,7 +1130,9 @@ ;; CHECK-NEXT: (block ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_5) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -1175,7 +1195,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_6) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state_6 @@ -1209,7 +1231,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $zero-size-undropped @@ -1312,7 +1336,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_8) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state_8 @@ -1380,7 +1406,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state @@ -1414,7 +1442,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state_1 @@ -1448,7 +1478,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state_2 @@ -1481,7 +1513,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.get $__mem_segment_drop_state_3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (global.set $__mem_segment_drop_state_3 @@ -2234,7 +2268,9 @@ ;; CHECK: (func $0 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i32.const 0) @@ -2316,7 +2352,9 @@ ;; CHECK: (func $0 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (i64.const 0) @@ -2364,7 +2402,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (local.get $0) diff --git a/test/lit/passes/memory-packing_zero-filled-memory64.wast b/test/lit/passes/memory-packing_zero-filled-memory64.wast index 308666de3f1..23571184070 100644 --- a/test/lit/passes/memory-packing_zero-filled-memory64.wast +++ b/test/lit/passes/memory-packing_zero-filled-memory64.wast @@ -22,7 +22,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $__mem_segment_drop_state) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.fill ;; CHECK-NEXT: (local.get $1) diff --git a/test/lit/passes/merge-blocks.wast b/test/lit/passes/merge-blocks.wast index b6fa8f58532..66b0e8b71f5 100644 --- a/test/lit/passes/merge-blocks.wast +++ b/test/lit/passes/merge-blocks.wast @@ -192,13 +192,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) @@ -213,13 +213,17 @@ (drop (i32.const 0)) (i32.const 1) ) - (block (result i32) - (drop (i32.const 2)) - (i32.const 3) + (then + (block (result i32) + (drop (i32.const 2)) + (i32.const 3) + ) ) - (block (result i32) - (drop (i32.const 4)) - (i32.const 5) + (else + (block (result i32) + (drop (i32.const 4)) + (i32.const 5) + ) ) ) ) diff --git a/test/lit/passes/multi-memory-lowering.wast b/test/lit/passes/multi-memory-lowering.wast index 7463b7810ad..7508a5627ca 100644 --- a/test/lit/passes/multi-memory-lowering.wast +++ b/test/lit/passes/multi-memory-lowering.wast @@ -96,7 +96,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory1_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $0) ;; BOUNDS-NEXT: ) @@ -122,7 +124,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $1) ;; BOUNDS-NEXT: ) @@ -148,7 +152,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory3_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -212,7 +218,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory1_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $0) ;; BOUNDS-NEXT: ) @@ -237,7 +245,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $1) ;; BOUNDS-NEXT: ) @@ -262,7 +272,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory3_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -307,7 +319,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory1_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $1) ;; BOUNDS-NEXT: ) @@ -349,7 +363,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -392,7 +408,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory3_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $1) ;; BOUNDS-NEXT: ) @@ -432,7 +450,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $1) ;; BOUNDS-NEXT: ) @@ -506,7 +526,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory3_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -533,7 +555,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $3) ;; BOUNDS-NEXT: ) @@ -558,7 +582,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory1_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $4) ;; BOUNDS-NEXT: ) @@ -586,7 +612,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $5) ;; BOUNDS-NEXT: ) @@ -653,7 +681,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory1_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -708,7 +738,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -721,7 +753,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory3_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $0) ;; BOUNDS-NEXT: ) @@ -772,7 +806,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (call $memory2_size) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (if ;; BOUNDS-NEXT: (i32.gt_u @@ -782,7 +818,9 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (i32.const 1) ;; BOUNDS-NEXT: ) - ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: (then + ;; BOUNDS-NEXT: (unreachable) + ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $2) ;; BOUNDS-NEXT: ) @@ -851,8 +889,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.copy @@ -909,8 +949,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.copy @@ -954,8 +996,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $return_size) @@ -1013,8 +1057,10 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (i32.const -1) ;; BOUNDS-NEXT: ) -;; BOUNDS-NEXT: (return -;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: (then +;; BOUNDS-NEXT: (return +;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (memory.copy @@ -1071,8 +1117,10 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (i32.const -1) ;; BOUNDS-NEXT: ) -;; BOUNDS-NEXT: (return -;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: (then +;; BOUNDS-NEXT: (return +;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (memory.copy @@ -1116,8 +1164,10 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (i32.const -1) ;; BOUNDS-NEXT: ) -;; BOUNDS-NEXT: (return -;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: (then +;; BOUNDS-NEXT: (return +;; BOUNDS-NEXT: (i32.const -1) +;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: (local.get $return_size) diff --git a/test/lit/passes/no-inline.wast b/test/lit/passes/no-inline.wast index 5e5c1ea0e35..9fd95d0b769 100644 --- a/test/lit/passes/no-inline.wast +++ b/test/lit/passes/no-inline.wast @@ -49,7 +49,9 @@ (func $partial-yes-inline (param $x i32) (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -60,7 +62,9 @@ ;; NO_PART: (func $partial-maybe-inline (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) - ;; NO_PART-NEXT: (return) + ;; NO_PART-NEXT: (then + ;; NO_PART-NEXT: (return) + ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (loop $l ;; NO_PART-NEXT: (call $import) @@ -70,7 +74,9 @@ ;; NO_BOTH: (func $partial-maybe-inline (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) - ;; NO_BOTH-NEXT: (return) + ;; NO_BOTH-NEXT: (then + ;; NO_BOTH-NEXT: (return) + ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (loop $l ;; NO_BOTH-NEXT: (call $import) @@ -80,7 +86,9 @@ (func $partial-maybe-inline (param $x i32) (if (local.get $x) - (return) + (then + (return) + ) ) (loop $l (call $import) @@ -118,8 +126,10 @@ ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) - ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; YES_ALL-NEXT: (local.get $2) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; YES_ALL-NEXT: (local.get $2) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -133,8 +143,10 @@ ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) - ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline - ;; YES_ALL-NEXT: (local.get $3) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline + ;; YES_ALL-NEXT: (local.get $3) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -169,8 +181,10 @@ ;; NO_PART-NEXT: (i32.eqz ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) - ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_PART-NEXT: (local.get $2) + ;; NO_PART-NEXT: (then + ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_PART-NEXT: (local.get $2) + ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) @@ -203,8 +217,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -218,8 +234,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline - ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline + ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -248,8 +266,10 @@ ;; NO_BOTH-NEXT: (i32.eqz ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) - ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_BOTH-NEXT: (local.get $1) + ;; NO_BOTH-NEXT: (then + ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_BOTH-NEXT: (local.get $1) + ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) @@ -303,8 +323,10 @@ ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) - ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; YES_ALL-NEXT: (local.get $2) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; YES_ALL-NEXT: (local.get $2) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -318,8 +340,10 @@ ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) - ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline - ;; YES_ALL-NEXT: (local.get $3) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline + ;; YES_ALL-NEXT: (local.get $3) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -354,8 +378,10 @@ ;; NO_PART-NEXT: (i32.eqz ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) - ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_PART-NEXT: (local.get $2) + ;; NO_PART-NEXT: (then + ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_PART-NEXT: (local.get $2) + ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) @@ -388,8 +414,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -403,8 +431,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline - ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline + ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -433,8 +463,10 @@ ;; NO_BOTH-NEXT: (i32.eqz ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) - ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline - ;; NO_BOTH-NEXT: (local.get $1) + ;; NO_BOTH-NEXT: (then + ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline + ;; NO_BOTH-NEXT: (local.get $1) + ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) @@ -526,13 +558,17 @@ ;; NO_PART: (func $maybe-partial-or-full-1 (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) - ;; NO_PART-NEXT: (call $import) + ;; NO_PART-NEXT: (then + ;; NO_PART-NEXT: (call $import) + ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_BOTH: (func $maybe-partial-or-full-1 (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) - ;; NO_BOTH-NEXT: (call $import) + ;; NO_BOTH-NEXT: (then + ;; NO_BOTH-NEXT: (call $import) + ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $maybe-partial-or-full-1 (param $x i32) @@ -542,14 +578,18 @@ ;; partially inline it. (if (local.get $x) - (call $import) + (then + (call $import) + ) ) ) ;; NO_PART: (func $maybe-partial-or-full-2 (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) - ;; NO_PART-NEXT: (return) + ;; NO_PART-NEXT: (then + ;; NO_PART-NEXT: (return) + ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (nop) ;; NO_PART-NEXT: (drop @@ -580,7 +620,9 @@ ;; NO_BOTH: (func $maybe-partial-or-full-2 (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) - ;; NO_BOTH-NEXT: (return) + ;; NO_BOTH-NEXT: (then + ;; NO_BOTH-NEXT: (return) + ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (nop) ;; NO_BOTH-NEXT: (drop @@ -613,7 +655,9 @@ ;; some extra things to the function size for partial inlining to kick in. (if (local.get $x) - (return) + (then + (return) + ) ) (nop) (drop @@ -654,7 +698,9 @@ ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $0) - ;; YES_ALL-NEXT: (call $import) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $import) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -665,7 +711,9 @@ ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $1) - ;; YES_ALL-NEXT: (call $import) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (call $import) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) @@ -677,7 +725,9 @@ ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $2) - ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$2) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$2) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (nop) ;; YES_ALL-NEXT: (drop @@ -715,7 +765,9 @@ ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $3) - ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$3) + ;; YES_ALL-NEXT: (then + ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$3) + ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (nop) ;; YES_ALL-NEXT: (drop @@ -772,8 +824,10 @@ ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (local.get $0) - ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 - ;; NO_FULL-NEXT: (local.get $0) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 + ;; NO_FULL-NEXT: (local.get $0) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -785,8 +839,10 @@ ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (local.get $1) - ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 - ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 + ;; NO_FULL-NEXT: (local.get $1) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -800,8 +856,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 - ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 + ;; NO_FULL-NEXT: (local.get $2) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) @@ -815,8 +873,10 @@ ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $3) ;; NO_FULL-NEXT: ) - ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 - ;; NO_FULL-NEXT: (local.get $3) + ;; NO_FULL-NEXT: (then + ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 + ;; NO_FULL-NEXT: (local.get $3) + ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) diff --git a/test/lit/passes/once-reduction.wast b/test/lit/passes/once-reduction.wast index 45170a0e185..af9f4f113ed 100644 --- a/test/lit/passes/once-reduction.wast +++ b/test/lit/passes/once-reduction.wast @@ -14,7 +14,9 @@ ;; A minimal "once" function. It is so trivial we can remove its body. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -40,7 +42,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -52,7 +56,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ;; Add some more content in the function. @@ -62,7 +68,7 @@ ;; CHECK: (func $caller-if-1 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $once) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -76,11 +82,13 @@ ;; Add more calls, and ones that are conditional. (if (i32.const 1) - (block - (call $once) - (call $once) - (call $once) - (call $once) + (then + (block + (call $once) + (call $once) + (call $once) + (call $once) + ) ) ) (call $once) @@ -90,8 +98,10 @@ ;; CHECK: (func $caller-if-2 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (call $once) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -104,11 +114,15 @@ ;; call after the if is *not* optimized. (if (i32.const 1) - (call $once) - (block - (call $once) + (then (call $once) ) + (else + (block + (call $once) + (call $once) + ) + ) ) (call $once) (call $once) @@ -118,7 +132,9 @@ ;; CHECK-NEXT: (loop $loop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $once) ;; CHECK-NEXT: (nop) @@ -134,7 +150,9 @@ (loop $loop (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (call $once) @@ -148,7 +166,9 @@ ;; CHECK-NEXT: (loop $loop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $loop ;; CHECK-NEXT: (i32.const 1) @@ -162,7 +182,9 @@ (loop $loop (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (br_if $loop (i32.const 1)) ) @@ -202,7 +224,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -212,7 +236,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $foo) @@ -243,7 +269,9 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -254,7 +282,9 @@ (nop) (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $foo) @@ -283,7 +313,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (global.set $once @@ -294,7 +326,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (nop) (global.set $once (i32.const 1)) @@ -324,8 +358,12 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -335,8 +373,12 @@ (func $once (if (global.get $once) - (return) - (call $foo) + (then + (return) + ) + (else + (call $foo) + ) ) (global.set $once (i32.const 1)) (call $foo) @@ -364,7 +406,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once1) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once2 ;; CHECK-NEXT: (i32.const 1) @@ -373,7 +417,9 @@ (func $once (if (global.get $once1) - (return) + (then + (return) + ) ) (global.set $once2 (i32.const 1)) ) @@ -398,7 +444,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 0) @@ -407,7 +455,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 0)) ) @@ -432,7 +482,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -441,7 +493,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -475,7 +529,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 42)) ) @@ -517,7 +573,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -527,7 +585,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $once) @@ -546,7 +606,9 @@ ;; CHECK-NEXT: (i32.trunc_f64_s ;; CHECK-NEXT: (global.get $once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (f64.const 1) @@ -558,7 +620,9 @@ (i32.trunc_f64_s (global.get $once) ) - (return) + (then + (return) + ) ) (global.set $once (f64.const 1)) ) @@ -592,7 +656,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -617,7 +683,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.eqz @@ -630,7 +698,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.eqz (i32.eqz (i32.const 1)))) ) @@ -657,7 +727,9 @@ ;; CHECK: (func $once (type $0) (param $x i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -666,7 +738,9 @@ (func $once (param $x i32) (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -697,8 +771,10 @@ ;; CHECK: (func $once (type $0) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once @@ -709,7 +785,9 @@ (func $once (result i32) (if (global.get $once) - (return (i32.const 2)) + (then + (return (i32.const 2)) + ) ) (global.set $once (i32.const 1)) (i32.const 3) @@ -740,7 +818,9 @@ ;; CHECK-NEXT: (loop $loop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -751,7 +831,9 @@ (loop $loop (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -777,13 +859,17 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $once (if (global.get $once) - (return) + (then + (return) + ) ) ) @@ -807,7 +893,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -816,7 +904,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -845,7 +935,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -857,7 +949,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (drop (global.get $once)) @@ -887,7 +981,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -921,7 +1017,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -929,53 +1027,79 @@ ;; CHECK: (func $caller (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $once) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -983,53 +1107,79 @@ (func $caller (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (if (i32.const 1) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (call $once) (if (i32.const 1) - (nop) - (call $once) + (then + (nop) + ) + (else + (call $once) + ) ) (call $once) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (if (i32.const 1) - (nop) - (call $once) + (then + (nop) + ) + (else + (call $once) + ) ) (call $once) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) (call $once) (call $once) @@ -1056,7 +1206,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -1066,7 +1218,9 @@ ;; CHECK-NEXT: (do ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $once) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (catch $tag @@ -1081,7 +1235,9 @@ (do (if (i32.const 1) - (call $once) + (then + (call $once) + ) ) ) (catch $tag @@ -1111,7 +1267,9 @@ ;; CHECK: (func $once1 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once1) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once1 ;; CHECK-NEXT: (i32.const 1) @@ -1128,7 +1286,9 @@ (func $once1 (if (global.get $once1) - (return) + (then + (return) + ) ) (global.set $once1 (i32.const 1)) (call $once1) @@ -1144,7 +1304,9 @@ ;; CHECK: (func $many1 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $many1) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $many1 ;; CHECK-NEXT: (i32.const 0) @@ -1161,7 +1323,9 @@ (func $many1 (if (global.get $many1) - (return) + (then + (return) + ) ) (global.set $many1 (i32.const 0)) ;; prevent this global being "once" (call $many2) @@ -1177,7 +1341,9 @@ ;; CHECK: (func $once2 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once2) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once2 ;; CHECK-NEXT: (i32.const 2) @@ -1194,7 +1360,9 @@ (func $once2 (if (global.get $once2) - (return) + (then + (return) + ) ) (global.set $once2 (i32.const 2)) (call $once2) @@ -1210,7 +1378,9 @@ ;; CHECK: (func $many2 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $many2) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $many1 ;; CHECK-NEXT: (i32.const 0) @@ -1227,7 +1397,9 @@ (func $many2 (if (global.get $many2) - (return) + (then + (return) + ) ) (global.set $many1 (i32.const 0)) (call $many1) @@ -1256,7 +1428,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -1324,7 +1498,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -1333,7 +1509,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -1362,7 +1540,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -1371,7 +1551,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -1406,7 +1588,9 @@ ;; two lines here (the early-exit logic). (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $once.1) @@ -1420,7 +1604,9 @@ ;; out. (if (global.get $once.1) - (return) + (then + (return) + ) ) (global.set $once.1 (i32.const 1)) ) @@ -1501,7 +1687,9 @@ ;; logic. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $once.1) @@ -1510,7 +1698,9 @@ ;; CHECK: (func $once.1 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once.1) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once.1 ;; CHECK-NEXT: (i32.const 1) @@ -1523,7 +1713,9 @@ ;; cannot do so here (it would risk an infinite loop). (if (global.get $once.1) - (return) + (then + (return) + ) ) (global.set $once.1 (i32.const 1)) (call $once) ;; This call was added. @@ -1593,7 +1785,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -1607,7 +1801,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) (call $once.1) @@ -1634,7 +1830,9 @@ ;; CHECK: (func $once.1 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once.1) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once.1 ;; CHECK-NEXT: (i32.const 1) @@ -1648,7 +1846,9 @@ (func $once.1 (if (global.get $once.1) - (return) + (then + (return) + ) ) (global.set $once.1 (i32.const 1)) (call $once) @@ -1662,7 +1862,9 @@ ;; CHECK: (func $once.2 (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once.2) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once.2 ;; CHECK-NEXT: (i32.const 1) @@ -1676,7 +1878,9 @@ (func $once.2 (if (global.get $once.2) - (return) + (then + (return) + ) ) (global.set $once.2 (i32.const 1)) (call $once) @@ -1699,7 +1903,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -1709,7 +1915,9 @@ (func $once (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ;; A recursive call. This of course does not recurse infinitely since the @@ -1743,7 +1951,9 @@ ;; A minimal "once" function. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ) @@ -1789,7 +1999,9 @@ ;; CHECK: (func $once (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -1800,7 +2012,9 @@ ;; We should not remove this early-exit logic. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1)) ;; A call to a non-"once" function. diff --git a/test/lit/passes/optimize-casts.wast b/test/lit/passes/optimize-casts.wast index d0b4d05d79f..512a04e9dc4 100644 --- a/test/lit/passes/optimize-casts.wast +++ b/test/lit/passes/optimize-casts.wast @@ -437,7 +437,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) @@ -453,7 +455,9 @@ ;; this atm. (if (i32.const 0) - (return) + (then + (return) + ) ) (drop (local.get $x) @@ -1291,7 +1295,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (ref.as_non_null @@ -1322,17 +1326,19 @@ ) (if (i32.const 0) - (block - (drop - ;; The ref.as_non_null can be moved here because - ;; it is in the same block in the same arm of the - ;; if statement. - (local.get $x) - ) - (drop - (ref.as_non_null + (then + (block + (drop + ;; The ref.as_non_null can be moved here because + ;; it is in the same block in the same arm of the + ;; if statement. (local.get $x) ) + (drop + (ref.as_non_null + (local.get $x) + ) + ) ) ) ) diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast index 29c09eb0ffb..f83ddb09127 100644 --- a/test/lit/passes/optimize-instructions-call_ref.wast +++ b/test/lit/passes/optimize-instructions-call_ref.wast @@ -256,13 +256,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (call $foo - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $foo + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $bar - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $bar + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -311,13 +315,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $get-i32) - ;; CHECK-NEXT: (return_call $foo - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return_call $foo + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call $bar - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return_call $bar + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/optimize-instructions-exceptions.wast b/test/lit/passes/optimize-instructions-exceptions.wast index 9d22224fbb8..dcb6491290f 100644 --- a/test/lit/passes/optimize-instructions-exceptions.wast +++ b/test/lit/passes/optimize-instructions-exceptions.wast @@ -13,7 +13,9 @@ ;; CHECK-NEXT: (i32.const 456) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $test @@ -34,7 +36,9 @@ ) ) ) - (nop) + (then + (nop) + ) ) ) ) diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast index 98372bed247..3cf7a72d2f9 100644 --- a/test/lit/passes/optimize-instructions-gc-tnh.wast +++ b/test/lit/passes/optimize-instructions-gc-tnh.wast @@ -243,16 +243,24 @@ ;; NO_TNH-NEXT: (struct.set $struct 0 ;; NO_TNH-NEXT: (if (result (ref null $struct)) ;; NO_TNH-NEXT: (local.get $x) - ;; NO_TNH-NEXT: (local.get $ref) - ;; NO_TNH-NEXT: (ref.null none) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (ref.null none) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (i32.const 1) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (struct.set $struct 0 ;; NO_TNH-NEXT: (if (result (ref null $struct)) ;; NO_TNH-NEXT: (local.get $x) - ;; NO_TNH-NEXT: (ref.null none) - ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (ref.null none) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (local.get $ref) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (i32.const 2) ;; NO_TNH-NEXT: ) @@ -263,16 +271,24 @@ (struct.set $struct 0 (if (result (ref null $struct)) (local.get $x) - (local.get $ref) - (ref.null none) + (then + (local.get $ref) + ) + (else + (ref.null none) + ) ) (i32.const 1) ) (struct.set $struct 0 (if (result (ref null $struct)) (local.get $x) - (ref.null none) - (local.get $ref) + (then + (ref.null none) + ) + (else + (local.get $ref) + ) ) (i32.const 2) ) @@ -655,8 +671,12 @@ ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (if (result (ref none)) ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: (unreachable) - ;; NO_TNH-NEXT: (local.get $x) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (local.get $x) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (unreachable) @@ -668,8 +688,12 @@ (ref.cast (ref $struct) (if (result (ref none)) (i32.const 1) - (unreachable) - (local.get $x) + (then + (unreachable) + ) + (else + (local.get $x) + ) ) ) ) @@ -689,8 +713,12 @@ ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (if (result (ref none)) ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: (local.get $x) - ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (local.get $x) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (unreachable) @@ -700,8 +728,12 @@ (ref.cast (ref $struct) (if (result (ref none)) (i32.const 1) - (local.get $x) - (unreachable) + (then + (local.get $x) + ) + (else + (unreachable) + ) ) ) ) @@ -936,8 +968,12 @@ ;; TNH-NEXT: (drop ;; TNH-NEXT: (if (result (ref nofunc)) ;; TNH-NEXT: (i32.const 1) - ;; TNH-NEXT: (return) - ;; TNH-NEXT: (unreachable) + ;; TNH-NEXT: (then + ;; TNH-NEXT: (return) + ;; TNH-NEXT: ) + ;; TNH-NEXT: (else + ;; TNH-NEXT: (unreachable) + ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; TNH-NEXT: (unreachable) @@ -950,8 +986,12 @@ ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (if (result (ref nofunc)) ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: (return) - ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (return) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (unreachable) @@ -968,10 +1008,14 @@ (ref.cast (ref func) (if (result (ref nofunc)) (i32.const 1) - (block (result (ref nofunc)) - (return) + (then + (block (result (ref nofunc)) + (return) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index cb732d68b31..c7c7f601fbf 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -52,23 +52,35 @@ (func $if-arms-subtype-fold (result anyref) (if (result anyref) (i32.const 0) - (ref.null eq) - (ref.null eq) + (then + (ref.null eq) + ) + (else + (ref.null eq) + ) ) ) ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold) ;; CHECK: (func $if-arms-subtype-nofold (type $27) (param $i31ref i31ref) (result anyref) ;; CHECK-NEXT: (if (result anyref) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (local.get $i31ref) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $i31ref) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-arms-subtype-nofold (param $i31ref i31ref) (result anyref) (if (result anyref) (i32.const 0) - (ref.null none) - (local.get $i31ref) + (then + (ref.null none) + ) + (else + (local.get $i31ref) + ) ) ) @@ -669,8 +681,12 @@ ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (if (result (ref null $struct)) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -679,8 +695,12 @@ (drop (if (result i32) (local.get $x) - (ref.is_null (local.get $y)) - (ref.is_null (local.get $z)) + (then + (ref.is_null (local.get $y)) + ) + (else + (ref.is_null (local.get $z)) + ) ) ) ) @@ -741,8 +761,12 @@ ;; CHECK-NEXT: (struct.get_u $struct $i8 ;; CHECK-NEXT: (if (result (ref null $struct)) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -753,11 +777,15 @@ (local.get $z) ;; the arms are equal and have side effects, but that is ok with an if ;; which only executes one side anyhow - (struct.get_u $struct 0 - (local.get $x) + (then + (struct.get_u $struct 0 + (local.get $x) + ) ) - (struct.get_u $struct 0 - (local.get $y) + (else + (struct.get_u $struct 0 + (local.get $y) + ) ) ) ) @@ -1058,11 +1086,15 @@ ;; CHECK: (func $hoist-LUB-danger (type $33) (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (struct.get $B 1 - ;; CHECK-NEXT: (local.get $b) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (struct.get $B 1 + ;; CHECK-NEXT: (local.get $b) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (struct.get $C 1 - ;; CHECK-NEXT: (local.get $c) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (struct.get $C 1 + ;; CHECK-NEXT: (local.get $c) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1077,11 +1109,15 @@ ;; nominal typing. (if (result i32) (local.get $x) - (struct.get $B 1 - (local.get $b) + (then + (struct.get $B 1 + (local.get $b) + ) ) - (struct.get $C 1 - (local.get $c) + (else + (struct.get $C 1 + (local.get $c) + ) ) ) ) @@ -3097,8 +3133,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (br $block) - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (i32.const 42) @@ -3117,8 +3157,12 @@ ) (if (result i32) (i32.const 1) - (br $block) - (i32.const 10) + (then + (br $block) + ) + (else + (i32.const 10) + ) ) ;; There are no tricky effects after this, so this cast can be removed. (ref.as_non_null diff --git a/test/lit/passes/optimize-instructions-ignore-traps.wast b/test/lit/passes/optimize-instructions-ignore-traps.wast index 0d31794e50e..e594b791c2a 100644 --- a/test/lit/passes/optimize-instructions-ignore-traps.wast +++ b/test/lit/passes/optimize-instructions-ignore-traps.wast @@ -51,20 +51,28 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.rem_u - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 11) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $while-in6 @@ -149,8 +157,12 @@ ) ) ) - (local.get $7) - (local.get $6) + (then + (local.get $7) + ) + (else + (local.get $6) + ) ) ) (br_if $while-in6 @@ -232,8 +244,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $while-in6 @@ -318,8 +334,12 @@ ) ) ) - (local.get $7) - (local.get $6) + (then + (local.get $7) + ) + (else + (local.get $6) + ) ) ) (br_if $while-in6 @@ -384,22 +404,30 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.rem_s - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.mul - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: (i32.const 5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 5) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br_if $while-in6 @@ -484,8 +512,12 @@ ) ) ) - (local.get $7) - (local.get $6) + (then + (local.get $7) + ) + (else + (local.get $6) + ) ) ) (br_if $while-in6 @@ -540,8 +572,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return @@ -576,7 +610,9 @@ ) ) ) - (return (local.get $0)) + (then + (return (local.get $0)) + ) ) (return (local.get $1)) ) @@ -587,23 +623,29 @@ ;; CHECK-NEXT: (local.tee $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.lt_u - ;; CHECK-NEXT: (i32.and - ;; CHECK-NEXT: (i32.extend8_s - ;; CHECK-NEXT: (i32.sub - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.extend8_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return @@ -638,7 +680,9 @@ ) ) ) - (return (local.get $0)) + (then + (return (local.get $0)) + ) ) (return (local.get $1)) ) diff --git a/test/lit/passes/optimize-instructions-multivalue.wast b/test/lit/passes/optimize-instructions-multivalue.wast index 10b64e35476..e2a35336589 100644 --- a/test/lit/passes/optimize-instructions-multivalue.wast +++ b/test/lit/passes/optimize-instructions-multivalue.wast @@ -8,8 +8,12 @@ ;; CHECK-NEXT: (tuple.extract 2 0 ;; CHECK-NEXT: (if (type $2) (result i32 i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $tuple) - ;; CHECK-NEXT: (local.get $tuple2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $tuple) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $tuple2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -19,11 +23,15 @@ (if (result i32) (local.get $x) ;; The tuple.extract can be hoisted out. - (tuple.extract 2 0 - (local.get $tuple) + (then + (tuple.extract 2 0 + (local.get $tuple) + ) ) - (tuple.extract 2 0 - (local.get $tuple2) + (else + (tuple.extract 2 0 + (local.get $tuple2) + ) ) ) ) diff --git a/test/lit/passes/optimize-instructions-mvp.wast b/test/lit/passes/optimize-instructions-mvp.wast index 550db4094ed..9ac34145cee 100644 --- a/test/lit/passes/optimize-instructions-mvp.wast +++ b/test/lit/passes/optimize-instructions-mvp.wast @@ -92,8 +92,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $i1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -102,8 +104,10 @@ (i32.eqz (local.get $i1) ) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) ) ) @@ -111,8 +115,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $i1) - ;; CHECK-NEXT: (i32.const 12) - ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -121,11 +129,15 @@ (i32.eqz (local.get $i1) ) - (drop - (i32.const 11) + (then + (drop + (i32.const 11) + ) ) - (drop - (i32.const 12) + (else + (drop + (i32.const 12) + ) ) ) ) @@ -135,8 +147,12 @@ ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $i2) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 11) - ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -145,11 +161,15 @@ (i64.eqz (local.get $i2) ) - (drop - (i32.const 11) + (then + (drop + (i32.const 11) + ) ) - (drop - (i32.const 12) + (else + (drop + (i32.const 12) + ) ) ) ) @@ -510,7 +530,9 @@ ;; CHECK: (func $if-eqz-eqz ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 123) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-eqz-eqz @@ -520,7 +542,9 @@ (i32.const 123) ) ) - (nop) + (then + (nop) + ) ) ) ;; CHECK: (func $select-eqz (param $i1 i32) (result i32) @@ -2118,18 +2142,24 @@ ;; CHECK: (func $ne0 (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $ne0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $ne0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.or ;; CHECK-NEXT: (call $ne0) ;; CHECK-NEXT: (call $ne0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.and @@ -2142,16 +2172,22 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $ne0 (result i32) (if (i32.ne (call $ne0) (i32.const 0)) - (nop) + (then + (nop) + ) ) (if (i32.ne (i32.const 0) (call $ne0)) - (nop) + (then + (nop) + ) ) ;; through an or (if @@ -2159,7 +2195,9 @@ (i32.ne (i32.const 0) (call $ne0)) (i32.ne (i32.const 0) (call $ne0)) ) - (nop) + (then + (nop) + ) ) ;; but not an and (if @@ -2167,7 +2205,9 @@ (i32.ne (i32.const 0) (call $ne0)) (i32.ne (i32.const 0) (call $ne0)) ) - (nop) + (then + (nop) + ) ) (i32.const 1) ) @@ -2175,34 +2215,50 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $ne0) - ;; CHECK-NEXT: (call $ne1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $ne1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (call $ne0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $recurse-bool (if (if (result i32) (i32.const 1) - (i32.ne (call $ne0) (i32.const 0)) - (i32.ne (call $ne1) (i32.const 0)) + (then + (i32.ne (call $ne0) (i32.const 0)) + ) + (else + (i32.ne (call $ne1) (i32.const 0)) + ) + ) + (then + (nop) ) - (nop) ) (if (block (result i32) (nop) (i32.ne (call $ne0) (i32.const 0)) ) - (nop) + (then + (nop) + ) ) ) ;; CHECK: (func $ne1 (result i32) @@ -2671,8 +2727,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 111) - ;; CHECK-NEXT: (i32.const 222) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 222) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-sext-unreachable (param $0 i32) (result i32) @@ -2684,8 +2744,12 @@ ) (i32.const 16) ) - (i32.const 111) - (i32.const 222) + (then + (i32.const 111) + ) + (else + (i32.const 222) + ) ) ) ;; CHECK: (func $sext-24-100 (result i32) @@ -4074,8 +4138,12 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 255) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4089,8 +4157,12 @@ ) (i32.const 24) ) - (i32.const 100) - (i32.const 200) + (then + (i32.const 100) + ) + (else + (i32.const 200) + ) ) ) ) @@ -5703,13 +5775,17 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -5718,36 +5794,56 @@ (drop (if (result i32) (local.get $0) - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) + (then + (i32.add (local.get $1) (i32.const 1)) + ) + (else + (i32.add (local.get $1) (i32.const 1)) + ) ) ) (drop (if (result i32) (local.tee $0 (local.get $1)) ;; side effects! - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) + (then + (i32.add (local.get $1) (i32.const 1)) + ) + (else + (i32.add (local.get $1) (i32.const 1)) + ) ) ) (drop (if (result i32) (local.get $0) - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) + (then + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + ) + (else + (i32.add (local.get $1) (unreachable)) + ) ) ) (drop (if (result i32) (local.tee $0 (local.get $1)) ;; side effects! - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) + (then + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + ) + (else + (i32.add (local.get $1) (unreachable)) + ) ) ) (drop (if (result i32) (unreachable) ;; !!! - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) + (then + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + ) + (else + (i32.add (local.get $1) (unreachable)) + ) ) ) ) @@ -6830,8 +6926,12 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 40) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $return-proper-value-from-shift-left-by-zero (result i32) @@ -6855,8 +6955,12 @@ ) (i32.const -2) ) - (i32.const 1) - (i32.const 0) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) ) ) ;; CHECK: (func $de-morgan-2 (param $x i32) (param $y i32) @@ -9950,8 +10054,12 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -9960,8 +10068,12 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (i32.const 2147483647) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -10146,8 +10258,12 @@ (local.get $x) (i32.const 4) ) - (i32.const 1) - (i32.const 0) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) )) ;; (signed)x % min_s ? 1 : 0 (drop (if (result i32) @@ -10155,8 +10271,12 @@ (local.get $x) (i32.const 0x80000000) ) - (i32.const 1) - (i32.const 0) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) )) ) ;; CHECK: (func $fold-eqz-eqz (param $x i32) (param $y i64) @@ -10244,8 +10364,12 @@ ;; CHECK-NEXT: (local.set $x4 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -10257,8 +10381,12 @@ ;; CHECK-NEXT: (local.set $x5 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -10267,8 +10395,12 @@ ;; CHECK-NEXT: (local.set $x6 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -10308,13 +10440,13 @@ (local.set $x3 (loop (result i32) (i32.const 1))) (drop (i32.and (local.get $x3) (i32.const 7))) ;; if - two sides, can't - (local.set $x4 (if (result i32) (i32.const 1) (i32.const 2) (i32.const 3))) + (local.set $x4 (if (result i32) (i32.const 1) (then (i32.const 2) )(else (i32.const 3)))) (drop (i32.and (local.get $x4) (i32.const 7))) ;; if - one side, can - (local.set $x5 (if (result i32) (i32.const 1) (unreachable) (i32.const 3))) + (local.set $x5 (if (result i32) (i32.const 1) (then (unreachable) )(else (i32.const 3)))) (drop (i32.and (local.get $x5) (i32.const 7))) ;; if - one side, can - (local.set $x6 (if (result i32) (i32.const 1) (i32.const 3) (unreachable))) + (local.set $x6 (if (result i32) (i32.const 1) (then (i32.const 3) )(else (unreachable)))) (drop (i32.and (local.get $x6) (i32.const 7))) ;; br_if with value (drop @@ -12136,7 +12268,9 @@ ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $select-into-arms (param $x i32) (param $y i32) @@ -12146,7 +12280,9 @@ (i32.eqz (i32.eqz (local.get $y))) (local.get $y) ) - (unreachable) + (then + (unreachable) + ) ) ) ;; CHECK: (func $select-with-same-arm-and-cond-32 (param $x i32) @@ -12443,7 +12579,9 @@ ;; CHECK: (func $optimize-boolean-context (param $x i32) (param $y i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select @@ -12460,7 +12598,9 @@ (i32.const 0) (local.get $x) ) - (unreachable) + (then + (unreachable) + ) ) (drop (select (local.get $x) @@ -14646,8 +14786,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14693,10 +14837,14 @@ (drop (if (result i32) (local.get $x) - (i32.eqz - (local.get $y) + (then + (i32.eqz + (local.get $y) + ) + ) + (else + (i32.const 1) ) - (i32.const 1) ) ) ) @@ -14705,8 +14853,12 @@ ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (if (result i64) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (i64.const 1) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14715,9 +14867,13 @@ (drop (if (result i32) (local.get $x) - (i32.const 0) - (i64.eqz - (local.get $y) + (then + (i32.const 0) + ) + (else + (i64.eqz + (local.get $y) + ) ) ) ) @@ -14727,8 +14883,12 @@ ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (if (result i64) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) - ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14737,10 +14897,14 @@ (drop (if (result i32) (local.get $x) - (i64.eqz - (local.get $y) + (then + (i64.eqz + (local.get $y) + ) + ) + (else + (i32.const 1) ) - (i32.const 1) ) ) ) @@ -14769,10 +14933,14 @@ ;; CHECK: (func $ternary-no-unreachable-1 (param $x i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ternary-no-unreachable-1 (param $x i32) (result i32) @@ -14781,18 +14949,26 @@ ;; one arm is an eqz, the other is 0 or 1, so we can put an eqz on the ;; outside in theory, but we'd need to be careful with the unreachable ;; type here. ignore this case, as DCE is the proper optimization anyhow. - (i32.eqz - (unreachable) + (then + (i32.eqz + (unreachable) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) ;; CHECK: (func $ternary-no-unreachable-2 (param $x i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14800,9 +14976,13 @@ (if (result i32) (local.get $x) ;; as before, but flipped - (i32.const 0) - (i32.eqz - (unreachable) + (then + (i32.const 0) + ) + (else + (i32.eqz + (unreachable) + ) ) ) ) @@ -14831,8 +15011,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14841,8 +15025,12 @@ (drop (if (result i32) (local.get $z) - (i32.eqz (local.get $x)) - (i32.eqz (local.get $y)) + (then + (i32.eqz (local.get $x)) + ) + (else + (i32.eqz (local.get $y)) + ) ) ) ) @@ -14852,8 +15040,12 @@ ;; CHECK-NEXT: (f64.floor ;; CHECK-NEXT: (if (result f64) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14865,8 +15057,12 @@ ;; f64 (if (result f32) (local.get $z) - (f32.demote_f64 (f64.floor (local.get $x))) - (f32.demote_f64 (f64.floor (local.get $y))) + (then + (f32.demote_f64 (f64.floor (local.get $x))) + ) + (else + (f32.demote_f64 (f64.floor (local.get $y))) + ) ) ) ) @@ -14921,8 +15117,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14930,18 +15130,26 @@ (func $ternary-identical-arms-and-type-is-none (param $x i32) (param $y i32) (param $z i32) (if (local.get $z) - (drop (i32.eqz (local.get $x))) - (drop (i32.eqz (local.get $y))) + (then + (drop (i32.eqz (local.get $x))) + ) + (else + (drop (i32.eqz (local.get $y))) + ) ) ) ;; CHECK: (func $ternary-identical-arms-and-type-is-none-child-types-mismatch (param $x i32) (param $y i32) (param $z i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (f64.const 2.34) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.const 2.34) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -14950,8 +15158,12 @@ (local.get $z) ;; the drop cannot be hoisted out, since the children's type mismatch ;; would not allow us to give a proper type to the if. - (drop (i32.const 1)) - (drop (f64.const 2.34)) + (then + (drop (i32.const 1)) + ) + (else + (drop (f64.const 2.34)) + ) ) ) ;; CHECK: (func $ternary-identical-arms-but-block (param $x i32) (param $y i32) (param $z i32) @@ -15021,8 +15233,12 @@ ;; CHECK-NEXT: (br_if $block ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15032,11 +15248,15 @@ (if (local.get $z) ;; two br_ifs with the same target are shallowly identical - (br_if $block - (local.get $x) + (then + (br_if $block + (local.get $x) + ) ) - (br_if $block - (local.get $y) + (else + (br_if $block + (local.get $y) + ) ) ) ) @@ -15046,11 +15266,15 @@ ;; CHECK-NEXT: (block $block2 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (br_if $block1 - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br_if $block1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $block2 - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br_if $block2 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15062,11 +15286,15 @@ (if (local.get $z) ;; two br_ifs with different targets are not shallowly identical - (br_if $block1 - (local.get $x) + (then + (br_if $block1 + (local.get $x) + ) ) - (br_if $block2 - (local.get $y) + (else + (br_if $block2 + (local.get $y) + ) ) ) ) @@ -15077,8 +15305,12 @@ ;; CHECK-NEXT: (return ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15087,11 +15319,15 @@ (block $block (if (local.get $z) - (return - (local.get $x) + (then + (return + (local.get $x) + ) ) - (return - (local.get $y) + (else + (return + (local.get $y) + ) ) ) ) @@ -15131,30 +15367,42 @@ ;; CHECK-NEXT: (call $send-i32 ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $z) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $ternary-identical-arms-call (param $x i32) (param $y i32) (param $z i32) (if (local.get $z) - (call $send-i32 - (local.get $x) + (then + (call $send-i32 + (local.get $x) + ) ) - (call $send-i32 - (local.get $y) + (else + (call $send-i32 + (local.get $y) + ) ) ) ) ;; CHECK: (func $if-dont-change-to-unreachable (param $x i32) (param $y i32) (param $z i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -15162,11 +15410,15 @@ ;; if we move the returns outside, we'd become unreachable; avoid that. (if (result i32) (local.get $x) - (return - (local.get $y) + (then + (return + (local.get $y) + ) ) - (return - (local.get $z) + (else + (return + (local.get $z) + ) ) ) ) diff --git a/test/lit/passes/optimize-stack-ir.wast b/test/lit/passes/optimize-stack-ir.wast index adb78787941..bb1e0f9f031 100644 --- a/test/lit/passes/optimize-stack-ir.wast +++ b/test/lit/passes/optimize-stack-ir.wast @@ -159,8 +159,10 @@ ) (i32.const 0) ) - (br $topmost - (f64.const -3.4) + (then + (br $topmost + (f64.const -3.4) + ) ) ) (if @@ -170,8 +172,10 @@ ) (f64.const 0) ) - (br $topmost - (f64.const 5.6) + (then + (br $topmost + (f64.const 5.6) + ) ) ) (f64.const 1.2) @@ -224,8 +228,10 @@ (local.get $x) (f64.const 0) ) - (br $topmost - (f64.const 1.2) + (then + (br $topmost + (f64.const 1.2) + ) ) ) (if @@ -233,8 +239,10 @@ (local.get $Int) (f64.const 0) ) - (br $topmost - (f64.const -3.4) + (then + (br $topmost + (f64.const -3.4) + ) ) ) (if @@ -242,8 +250,10 @@ (local.get $Double) (i32.const 0) ) - (br $topmost - (f64.const 5.6) + (then + (br $topmost + (f64.const 5.6) + ) ) ) (if @@ -251,8 +261,10 @@ (local.get $x) (local.get $y) ) - (br $topmost - (local.get $x) + (then + (br $topmost + (local.get $x) + ) ) ) (local.get $y) @@ -899,8 +911,12 @@ (f64.abs (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 1)) + ) ) ) ) @@ -919,8 +935,12 @@ (func $unreachable-if-toplevel (result i32) (if ;; note no type - valid in binaryen IR, in wasm must be i32 (i32.const 3) - (return (i32.const 2)) - (return (i32.const 1)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 1)) + ) ) ) @@ -986,16 +1006,16 @@ ;; CHECK-NEXT: unreachable ;; CHECK-NEXT: ) (func $unreachable-ifs - (if (unreachable) (nop)) - (if (unreachable) (unreachable)) - (if (unreachable) (nop) (nop)) - (if (unreachable) (unreachable) (nop)) - (if (unreachable) (nop) (unreachable)) - (if (unreachable) (unreachable) (unreachable)) + (if (unreachable) (then (nop))) + (if (unreachable) (then (unreachable))) + (if (unreachable) (then (nop) )(else (nop))) + (if (unreachable) (then (unreachable) )(else (nop))) + (if (unreachable) (then (nop) )(else (unreachable))) + (if (unreachable) (then (unreachable) )(else (unreachable))) ;; - (if (i32.const 1) (unreachable) (nop)) - (if (i32.const 1) (nop) (unreachable)) - (if (i32.const 1) (unreachable) (unreachable)) + (if (i32.const 1) (then (unreachable) )(else (nop))) + (if (i32.const 1) (then (nop) )(else (unreachable))) + (if (i32.const 1) (then (unreachable) )(else (unreachable))) ) ;; CHECK: (func $unreachable-if-arm (type $FUNCSIG$v) @@ -1008,13 +1028,17 @@ (func $unreachable-if-arm (if (i32.const 1) - (block - (nop) + (then + (block + (nop) + ) ) - (block - (unreachable) - (drop - (i32.const 1) + (else + (block + (unreachable) + (drop + (i32.const 1) + ) ) ) ) @@ -1137,8 +1161,12 @@ (func $local-to-stack-3-no (param $x i32) (result i32) (local $temp i32) (if (i32.const 1) - (local.set $temp (call $local-to-stack (i32.const 1))) - (local.set $temp (call $local-to-stack (i32.const 2))) ;; two sets for that get + (then + (local.set $temp (call $local-to-stack (i32.const 1))) + ) + (else + (local.set $temp (call $local-to-stack (i32.const 2))) ;; two sets for that get + ) ) (drop (call $local-to-stack (i32.const 3))) (local.get $temp) @@ -1338,7 +1366,7 @@ (local $temp2 i32) (local.set $temp2 (call $local-to-stack-multi-4 (i32.const 0))) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) - (if (i32.const 0) (nop)) + (if (i32.const 0) (then (nop))) (drop (local.get $temp1)) (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 2))) (block $block (br $block)) @@ -1362,13 +1390,17 @@ (func $local-to-stack-in-control-flow (local $temp1 i32) (if (i32.const 0) - (block - (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 0))) - (drop (local.get $temp1)) + (then + (block + (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 0))) + (drop (local.get $temp1)) + ) ) - (block - (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) - (drop (local.get $temp1)) + (else + (block + (local.set $temp1 (call $local-to-stack-multi-4 (i32.const 1))) + (drop (local.get $temp1)) + ) ) ) ) diff --git a/test/lit/passes/outlining.wast b/test/lit/passes/outlining.wast index 349513dde3f..ee6dd5d90bf 100644 --- a/test/lit/passes/outlining.wast +++ b/test/lit/passes/outlining.wast @@ -255,8 +255,10 @@ ;; CHECK: (func $a (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $outline$) - ;; CHECK-NEXT: (global.set $global$1 - ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -265,16 +267,20 @@ (i32.eqz (global.get $global$1) ) - (global.set $global$1 - (i32.const 15) + (then + (global.set $global$1 + (i32.const 15) + ) ) ) ) ;; CHECK: (func $b (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $outline$) - ;; CHECK-NEXT: (global.set $global$1 - ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -283,8 +289,10 @@ (i32.eqz (global.get $global$1) ) - (global.set $global$1 - (i32.const 20) + (then + (global.set $global$1 + (i32.const 20) + ) ) ) ) @@ -307,7 +315,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a (param i32) @@ -315,8 +325,10 @@ (i32.eqz (local.get 0) ) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) ) ) @@ -325,7 +337,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $outline$) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $b (param i32) @@ -333,8 +347,10 @@ (i32.eqz (local.get 0) ) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) ) ) @@ -357,10 +373,14 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $global$1 - ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a @@ -368,12 +388,16 @@ (i32.eqz (global.get $global$1) ) - (global.set $global$1 - (i32.const 15) - ) - (block + (then (global.set $global$1 - (i32.const 100) + (i32.const 15) + ) + ) + (else + (block + (global.set $global$1 + (i32.const 100) + ) ) ) ) @@ -383,10 +407,14 @@ ;; CHECK-NEXT: (i32.ctz ;; CHECK-NEXT: (global.get $global$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $global$1 - ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global$1 + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $outline$) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $b @@ -394,12 +422,16 @@ (i32.ctz (global.get $global$1) ) - (global.set $global$1 - (i32.const 30) - ) - (block + (then (global.set $global$1 - (i32.const 100) + (i32.const 30) + ) + ) + (else + (block + (global.set $global$1 + (i32.const 100) + ) ) ) ) @@ -421,8 +453,12 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $global$1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $outline$_3) - ;; CHECK-NEXT: (call $outline$_4) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $outline$_3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $outline$_4) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -446,11 +482,15 @@ (i32.eqz (global.get $global$1) ) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) - (global.set $global$1 - (i32.const 20) + (else + (global.set $global$1 + (i32.const 20) + ) ) ) ) @@ -462,11 +502,15 @@ (i32.eqz (global.get $global$1) ) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) - (global.set $global$1 - (i32.const 20) + (else + (global.set $global$1 + (i32.const 20) + ) ) ) ) diff --git a/test/lit/passes/poppify.wast b/test/lit/passes/poppify.wast index 38bc920aa30..93a0353e364 100644 --- a/test/lit/passes/poppify.wast +++ b/test/lit/passes/poppify.wast @@ -184,13 +184,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (pop i32) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if (if (i32.const 0) - (nop) + (then + (nop) + ) ) ) @@ -198,15 +202,23 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (pop i32) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else (result i32) (if i32 (i32.const 0) - (i32.const 1) - (i32.const 2) + (then + (i32.const 1) + ) + (else + (i32.const 2) + ) ) ) diff --git a/test/lit/passes/precompute-gc-immutable.wast b/test/lit/passes/precompute-gc-immutable.wast index 0ae99b26a1e..c2a96bd2371 100644 --- a/test/lit/passes/precompute-gc-immutable.wast +++ b/test/lit/passes/precompute-gc-immutable.wast @@ -160,14 +160,18 @@ ;; CHECK-NEXT: (local $ref-imm (ref null $struct-imm)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $ref-imm - ;; CHECK-NEXT: (struct.new $struct-imm - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $ref-imm + ;; CHECK-NEXT: (struct.new $struct-imm + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $ref-imm - ;; CHECK-NEXT: (struct.new $struct-imm - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $ref-imm + ;; CHECK-NEXT: (struct.new $struct-imm + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -183,14 +187,18 @@ ;; different values. (if (local.get $x) - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 1) + (then + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 1) + ) ) ) - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 2) + (else + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 2) + ) ) ) ) @@ -205,14 +213,18 @@ ;; CHECK-NEXT: (local $ref-imm (ref null $struct-imm)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.set $ref-imm - ;; CHECK-NEXT: (struct.new $struct-imm - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $ref-imm + ;; CHECK-NEXT: (struct.new $struct-imm + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $ref-imm - ;; CHECK-NEXT: (struct.new $struct-imm - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $ref-imm + ;; CHECK-NEXT: (struct.new $struct-imm + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -230,14 +242,18 @@ ;; possible values). (if (local.get $x) - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 1) + (then + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 1) + ) ) ) - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 1) + (else + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 1) + ) ) ) ) @@ -252,7 +268,7 @@ ;; CHECK-NEXT: (local $ref-imm (ref null $struct-imm)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $ref-imm ;; CHECK-NEXT: (struct.new $struct-imm ;; CHECK-NEXT: (i32.const 1) @@ -262,7 +278,7 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (local.set $ref-imm ;; CHECK-NEXT: (struct.new $struct-imm ;; CHECK-NEXT: (i32.const 2) @@ -280,27 +296,31 @@ ;; reused. (if (local.get $x) - (block - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 1) + (then + (block + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 1) + ) ) - ) - (call $helper - (struct.get $struct-imm 0 - (local.get $ref-imm) + (call $helper + (struct.get $struct-imm 0 + (local.get $ref-imm) + ) ) ) ) - (block - (local.set $ref-imm - (struct.new $struct-imm - (i32.const 2) + (else + (block + (local.set $ref-imm + (struct.new $struct-imm + (i32.const 2) + ) ) - ) - (call $helper - (struct.get $struct-imm 0 - (local.get $ref-imm) + (call $helper + (struct.get $struct-imm 0 + (local.get $ref-imm) + ) ) ) ) diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 1c99d6e98db..29f64ba0771 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -125,14 +125,18 @@ ;; CHECK-NEXT: (local $x (ref null $struct)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $i) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (struct.new $struct - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (struct.new $struct - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -147,14 +151,18 @@ ;; a merge of two different $x values cannot be precomputed (if (local.get $i) - (local.set $x - (struct.new $struct - (i32.const 1) + (then + (local.set $x + (struct.new $struct + (i32.const 1) + ) ) ) - (local.set $x - (struct.new $struct - (i32.const 2) + (else + (local.set $x + (struct.new $struct + (i32.const 2) + ) ) ) ) @@ -466,8 +474,10 @@ ;; CHECK-NEXT: (call $helper ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $tempref - ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $tempref + ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $tempresult @@ -494,8 +504,10 @@ (call $helper (i32.const 0) ) - (local.set $tempref - (struct.new $empty) + (then + (local.set $tempref + (struct.new $empty) + ) ) ) (local.set $tempresult @@ -669,8 +681,10 @@ ;; CHECK-NEXT: (call $helper ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $tempref - ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $tempref + ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $stashedref @@ -702,8 +716,10 @@ (call $helper (i32.const 0) ) - (local.set $tempref - (struct.new $empty) + (then + (local.set $tempref + (struct.new $empty) + ) ) ) (local.set $stashedref @@ -898,8 +914,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (local.set $ref - ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $ref + ;; CHECK-NEXT: (struct.new_default $empty) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -938,8 +956,10 @@ ) (if (local.get $param) - (local.set $ref - (struct.new $empty) + (then + (local.set $ref + (struct.new $empty) + ) ) ) (drop @@ -1041,7 +1061,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -1062,7 +1084,9 @@ ;; later block. (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) (local.get $x) ) @@ -1105,7 +1129,9 @@ ;; CHECK-NEXT: (local $0 (ref any)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (local.set $0 @@ -1126,7 +1152,9 @@ ;; Otherwise this is the same as before. (if (local.get $x) - (nop) + (then + (nop) + ) ) (unreachable) (local.set $0 @@ -1149,7 +1177,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -1162,7 +1192,9 @@ ) (if (i32.const 1) - (unreachable) + (then + (unreachable) + ) ) (local.get $x) ) diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast index 7a620193e01..84c16cab27a 100644 --- a/test/lit/passes/remove-unused-brs-gc.wast +++ b/test/lit/passes/remove-unused-brs-gc.wast @@ -36,8 +36,12 @@ ;; (that is not specifically intended to be tested here). (if (result (ref struct)) (i32.const 0) - (local.get $0) - (local.get $0) + (then + (local.get $0) + ) + (else + (local.get $0) + ) ) ) ) @@ -639,36 +643,48 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (ref.test (ref none) - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (ref.test (ref none) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result nullref) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (ref.cast nullref + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (ref.cast nullref + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref null $struct)) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block $something (result (ref null $struct)) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (br_on_non_null $something - ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $something (result (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (br_on_non_null $something + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -699,19 +715,27 @@ (drop (if (result i32) (local.get $x) - (ref.test (ref $struct) - (ref.null any) + (then + (ref.test (ref $struct) + (ref.null any) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) (drop (if (result anyref) (local.get $x) - (ref.null any) - (ref.cast (ref null $struct) + (then (ref.null any) ) + (else + (ref.cast (ref null $struct) + (ref.null any) + ) + ) ) ) ;; We do not selectify here because the amount of work in the if is @@ -719,34 +743,42 @@ (drop (if (result anyref) (local.get $x) - (block (result anyref) - (block $something (result anyref) - (drop - (br_on_cast $something anyref (ref $struct) - (local.get $struct) + (then + (block (result anyref) + (block $something (result anyref) + (drop + (br_on_cast $something anyref (ref $struct) + (local.get $struct) + ) ) + (ref.null any) ) - (ref.null any) ) ) - (ref.null any) + (else + (ref.null any) + ) ) ) ;; However, null checks are fairly fast, and we will emit a select here. (drop (if (result anyref) (local.get $x) - (block (result anyref) - (block $nothing - (drop - (br_on_null $nothing - (ref.null $struct) + (then + (block (result anyref) + (block $nothing + (drop + (br_on_null $nothing + (ref.null $struct) + ) ) ) + (ref.null any) ) + ) + (else (ref.null any) ) - (ref.null any) ) ) ) diff --git a/test/lit/passes/remove-unused-brs.wast b/test/lit/passes/remove-unused-brs.wast index 6907547c3aa..6fcc5b066a3 100644 --- a/test/lit/passes/remove-unused-brs.wast +++ b/test/lit/passes/remove-unused-brs.wast @@ -17,11 +17,15 @@ (func $selectify-fresh-lub (param $x i32) (result anyref) (if (local.get $x) - (return - (ref.null none) + (then + (return + (ref.null none) + ) ) - (return - (ref.i31 (i32.const 0)) + (else + (return + (ref.i31 (i32.const 0)) + ) ) ) ) @@ -54,13 +58,17 @@ ) (i32.const 10) ) - (i32.const 1) - (i32.lt_u - (i32.sub - (local.get $0) - (i32.const 97) + (then + (i32.const 1) + ) + (else + (i32.lt_u + (i32.sub + (local.get $0) + (i32.const 97) + ) + (i32.const 6) ) - (i32.const 6) ) ) ) @@ -68,13 +76,17 @@ ;; CHECK: (func $restructure-br_if (type $0) (param $x i32) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: (block $x (result i32) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $x (result i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 300) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 300) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -104,13 +116,17 @@ ;; CHECK-NEXT: (call $nothing) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 100) - ;; CHECK-NEXT: (block $x (result i32) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $x (result i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 300) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 300) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -382,7 +398,9 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $if-of-if) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if-of-if) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-of-if @@ -393,9 +411,13 @@ (local.tee $x (i32.const 1) ) - (if - (local.get $x) - (call $if-of-if) + (then + (if + (local.get $x) + (then + (call $if-of-if) + ) + ) ) ) ) @@ -406,11 +428,15 @@ ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.tee $x - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if-of-if-but-side-effects) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $if-of-if-but-side-effects) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -422,11 +448,15 @@ (local.tee $x (i32.const 1) ) - (if - (local.tee $x - (i32.const 2) + (then + (if + (local.tee $x + (i32.const 2) + ) + (then + (call $if-of-if-but-side-effects) + ) ) - (call $if-of-if-but-side-effects) ) ) ) @@ -437,8 +467,8 @@ ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.eqz @@ -447,7 +477,9 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -456,8 +488,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if-of-if-but-too-costly) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $if-of-if-but-too-costly) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -469,11 +503,15 @@ (local.tee $x (i32.const 1) ) - (if - (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz - (local.get $x) - ))))))))) - (call $if-of-if-but-too-costly) + (then + (if + (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz (i32.eqz + (local.get $x) + ))))))))) + (then + (call $if-of-if-but-too-costly) + ) + ) ) ) ) @@ -484,10 +522,16 @@ ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $if-of-if-but-inner-else) - ;; CHECK-NEXT: (call $if-of-if) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if-of-if-but-inner-else) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $if-of-if) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -498,10 +542,16 @@ (local.tee $x (i32.const 1) ) - (if - (local.get $x) - (call $if-of-if-but-inner-else) - (call $if-of-if) + (then + (if + (local.get $x) + (then + (call $if-of-if-but-inner-else) + ) + (else + (call $if-of-if) + ) + ) ) ) ) @@ -512,11 +562,17 @@ ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $if-of-if-but-outer-else) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if-of-if-but-outer-else) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $if-of-if) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $if-of-if) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-of-if-but-outer-else @@ -526,11 +582,17 @@ (local.tee $x (i32.const 1) ) - (if - (local.get $x) - (call $if-of-if-but-outer-else) + (then + (if + (local.get $x) + (then + (call $if-of-if-but-outer-else) + ) + ) + ) + (else + (call $if-of-if) ) - (call $if-of-if) ) ) ) diff --git a/test/lit/passes/remove-unused-brs_all-features.wast b/test/lit/passes/remove-unused-brs_all-features.wast index 344fbe12f3e..98f0202745c 100644 --- a/test/lit/passes/remove-unused-brs_all-features.wast +++ b/test/lit/passes/remove-unused-brs_all-features.wast @@ -33,25 +33,33 @@ ;; CHECK: (func $foo (type $3) (result (ref null $struct)) ;; CHECK-NEXT: (if (result (ref null $struct)) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (struct.new $struct - ;; CHECK-NEXT: (array.new_default $vector - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (array.new_default $vector + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $foo (result (ref null $struct)) (if (result (ref null $struct)) (i32.const 1) - (struct.new $struct - ;; regression test for computing the cost of an array.new_default, which - ;; lacks the optional field "init" - (array.new_default $vector - (i32.const 1) + (then + (struct.new $struct + ;; regression test for computing the cost of an array.new_default, which + ;; lacks the optional field "init" + (array.new_default $vector + (i32.const 1) + ) ) ) - (ref.null $struct) + (else + (ref.null $struct) + ) ) ) @@ -59,15 +67,19 @@ ;; CHECK-NEXT: (loop $loop (result f64) ;; CHECK-NEXT: (if (result f64) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (f64.const 0) - ;; CHECK-NEXT: (block $block (result f64) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (br_if $loop - ;; CHECK-NEXT: (i32.eqz - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $block (result f64) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (br_if $loop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -83,7 +95,9 @@ ) (if (i32.const 0) - (unreachable) + (then + (unreachable) + ) ) ;; this will be moved from $block into the if right before it. we must be ;; careful to properly finalize() things, as if we finalize the block too @@ -117,8 +131,12 @@ ;; LUB (if (result funcref) (local.get $x) - (ref.func $none_=>_i32) - (ref.func $i32_=>_none) + (then + (ref.func $none_=>_i32) + ) + (else + (ref.func $i32_=>_none) + ) ) ) diff --git a/test/lit/passes/remove-unused-brs_levels.wast b/test/lit/passes/remove-unused-brs_levels.wast index f4737627e65..927cce86781 100644 --- a/test/lit/passes/remove-unused-brs_levels.wast +++ b/test/lit/passes/remove-unused-brs_levels.wast @@ -11,11 +11,15 @@ ;; SHRINK_0-NEXT: (local.get $x) ;; SHRINK_0-NEXT: (i32.const 53498923) ;; SHRINK_0-NEXT: ) - ;; SHRINK_0-NEXT: (i32.div_s + ;; SHRINK_0-NEXT: (then + ;; SHRINK_0-NEXT: (i32.div_s + ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: (i32.const 13) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: (else ;; SHRINK_0-NEXT: (local.get $x) - ;; SHRINK_0-NEXT: (i32.const 13) ;; SHRINK_0-NEXT: ) - ;; SHRINK_0-NEXT: (local.get $x) ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) ;; SHRINK_1: (func $selectify-division (type $0) (param $x i32) (result i32) @@ -52,11 +56,15 @@ (local.get $x) (i32.const 53498923) ) - (i32.div_s + (then + (i32.div_s + (local.get $x) + (i32.const 13) + ) + ) + (else (local.get $x) - (i32.const 13) ) - (local.get $x) ) ) @@ -66,14 +74,18 @@ ;; SHRINK_0-NEXT: (local.get $x) ;; SHRINK_0-NEXT: (i32.const 53498923) ;; SHRINK_0-NEXT: ) - ;; SHRINK_0-NEXT: (i32.div_s + ;; SHRINK_0-NEXT: (then ;; SHRINK_0-NEXT: (i32.div_s - ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: (i32.div_s + ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: (i32.const 13) + ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: (i32.const 13) ;; SHRINK_0-NEXT: ) - ;; SHRINK_0-NEXT: (i32.const 13) ;; SHRINK_0-NEXT: ) - ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: (else + ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) ;; SHRINK_1: (func $selectify-division2 (type $0) (param $x i32) (result i32) @@ -82,14 +94,18 @@ ;; SHRINK_1-NEXT: (local.get $x) ;; SHRINK_1-NEXT: (i32.const 53498923) ;; SHRINK_1-NEXT: ) - ;; SHRINK_1-NEXT: (i32.div_s + ;; SHRINK_1-NEXT: (then ;; SHRINK_1-NEXT: (i32.div_s - ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: (i32.div_s + ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: (i32.const 13) + ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: (i32.const 13) ;; SHRINK_1-NEXT: ) - ;; SHRINK_1-NEXT: (i32.const 13) ;; SHRINK_1-NEXT: ) - ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: (else + ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) ;; SHRINK_2: (func $selectify-division2 (type $0) (param $x i32) (result i32) @@ -116,14 +132,18 @@ (local.get $x) (i32.const 53498923) ) - (i32.div_s + (then (i32.div_s - (local.get $x) + (i32.div_s + (local.get $x) + (i32.const 13) + ) (i32.const 13) ) - (i32.const 13) ) - (local.get $x) + (else + (local.get $x) + ) ) ) ) diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index f287df88f0a..c964d8c28a9 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -576,8 +576,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) @@ -590,8 +594,12 @@ (f64.const 1) (f64.const 1) ) - (call_indirect (type $0) (f64.const 1) (i32.const 0)) - (f64.const 0) + (then + (call_indirect (type $0) (f64.const 1) (i32.const 0)) + ) + (else + (f64.const 0) + ) ) ) ) @@ -634,8 +642,12 @@ ;; CHECK-NEXT: (f64.const 1) ;; CHECK-NEXT: (f64.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (f64.const 1) - ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $0 (; 0 ;) (type $0) (param $var$0 f64) (result f64) @@ -649,8 +661,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) diff --git a/test/lit/passes/rse-gc.wast b/test/lit/passes/rse-gc.wast index 367f3ce1862..4bef953b932 100644 --- a/test/lit/passes/rse-gc.wast +++ b/test/lit/passes/rse-gc.wast @@ -64,11 +64,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -95,11 +99,15 @@ ) (if (local.get $x) - (drop - (local.get $A) + (then + (drop + (local.get $A) + ) ) - (drop - (local.get $B) + (else + (drop + (local.get $B) + ) ) ) (drop diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index 3b0cf119813..103cbe7f95f 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -569,17 +569,25 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref $struct)) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call $func-can-refine) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $func-can-refine) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref $struct)) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (call_ref $sig-can-refine - ;; CHECK-NEXT: (ref.func $func-can-refine) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call_ref $sig-can-refine + ;; CHECK-NEXT: (ref.func $func-can-refine) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -590,18 +598,26 @@ (drop (if (result anyref) (i32.const 1) - (call $func-can-refine) - (unreachable) + (then + (call $func-can-refine) + ) + (else + (unreachable) + ) ) ) ;; The same with a call_ref. (drop (if (result anyref) (i32.const 1) - (call_ref $sig-can-refine - (ref.func $func-can-refine) + (then + (call_ref $sig-can-refine + (ref.func $func-can-refine) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) ) @@ -641,8 +657,10 @@ ;; CHECK: (func $func-4 (type $sig) (result (ref null $struct)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (return - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) @@ -650,8 +668,10 @@ (func $func-4 (type $sig) (result anyref) (if (i32.const 1) - (return - (ref.null any) + (then + (return + (ref.null any) + ) ) ) (unreachable) diff --git a/test/lit/passes/simplify-globals-dominance.wast b/test/lit/passes/simplify-globals-dominance.wast index 3756a4a7eec..dddcaa98306 100644 --- a/test/lit/passes/simplify-globals-dominance.wast +++ b/test/lit/passes/simplify-globals-dominance.wast @@ -14,7 +14,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 10) ;; CHECK-NEXT: ) @@ -23,8 +23,10 @@ ;; CHECK-NEXT: (global.get $global) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (global.get $global) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -34,22 +36,26 @@ ) (if (i32.const 0) - (block - ;; This is dominated by the set, so we can apply 10 here. - (drop - (global.get $global) + (then + (block + ;; This is dominated by the set, so we can apply 10 here. + (drop + (global.get $global) + ) + (call $test) + ;; This is after a call, so we do nothing (we are still dominated by the + ;; global.set, but the call might set the global to another value). + (drop + (global.get $global) + ) ) - (call $test) - ;; This is after a call, so we do nothing (we are still dominated by the - ;; global.set, but the call might set the global to another value). + ) + ;; This is dominated by the set, but we do not optimize it yet. TODO + (else (drop (global.get $global) ) ) - ;; This is dominated by the set, but we do not optimize it yet. TODO - (drop - (global.get $global) - ) ) ) ) diff --git a/test/lit/passes/simplify-globals-read_only_to_write.wast b/test/lit/passes/simplify-globals-read_only_to_write.wast index cf783ee4b51..e1f27327cdb 100644 --- a/test/lit/passes/simplify-globals-read_only_to_write.wast +++ b/test/lit/passes/simplify-globals-read_only_to_write.wast @@ -12,15 +12,19 @@ ;; CHECK: (func $simple ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $simple (if (global.get $global) - (global.set $global (i32.const 1)) + (then + (global.set $global (i32.const 1)) + ) ) ) ;; CHECK: (func $more-with-no-side-effects @@ -28,7 +32,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 1) @@ -43,9 +47,11 @@ (global.get $global) ) ;; Also test for other operations in the body, with no effects. - (block - (nop) - (global.set $global (i32.const 1)) + (then + (block + (nop) + (global.set $global (i32.const 1)) + ) ) ) ) @@ -69,8 +75,10 @@ ;; CHECK: (func $additional-read ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global) - ;; CHECK-NEXT: (global.set $global - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -80,7 +88,9 @@ (func $additional-read (if (global.get $global) - (global.set $global (i32.const 1)) + (then + (global.set $global (i32.const 1)) + ) ) (drop (global.get $global) @@ -96,17 +106,25 @@ ;; CHECK: (func $if-else ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global) - ;; CHECK-NEXT: (global.set $global - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else (if (global.get $global) - (global.set $global (i32.const 1)) - (nop) + (then + (global.set $global (i32.const 1)) + ) + (else + (nop) + ) ) ) ) @@ -121,7 +139,7 @@ ;; CHECK: (func $side-effects-in-body ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $global) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $global ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -137,10 +155,12 @@ (func $side-effects-in-body (if (global.get $global) - (block - (global.set $global (i32.const 1)) - (global.set $other (i32.const 2)) - (drop (global.get $other)) + (then + (block + (global.set $global (i32.const 1)) + (global.set $other (i32.const 2)) + (drop (global.get $other)) + ) ) ) ) @@ -159,17 +179,19 @@ ;; CHECK: (func $nested ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -183,18 +205,24 @@ (func $nested (if (global.get $a) - (block - (global.set $a (i32.const 1)) - (if - (global.get $b) - (block - (if - (global.get $c) + (then + (block + (global.set $a (i32.const 1)) + (if + (global.get $b) + (then (block - (global.set $c (i32.const 2)) + (if + (global.get $c) + (then + (block + (global.set $c (i32.const 2)) + ) + ) + ) + (global.set $b (i32.const 3)) ) ) - (global.set $b (i32.const 3)) ) ) ) @@ -211,7 +239,9 @@ ;; CHECK: (func $clinit ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 1) @@ -223,7 +253,9 @@ ;; in the if body in this case. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1) @@ -240,7 +272,9 @@ ;; CHECK: (func $clinit ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -252,7 +286,9 @@ ;; many elements - a nop is added at the end. (if (global.get $once) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1) @@ -270,8 +306,12 @@ ;; CHECK: (func $clinit ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -281,8 +321,12 @@ ;; As above, but the optimization fails because the if has an else. (if (global.get $once) - (return) - (nop) + (then + (return) + ) + (else + (nop) + ) ) (global.set $once (i32.const 1) @@ -299,7 +343,9 @@ ;; CHECK: (func $clinit ;; CHECK-NEXT: (if ;; CHECK-NEXT: (global.get $once) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -310,7 +356,9 @@ ;; return. (if (global.get $once) - (nop) + (then + (nop) + ) ) (global.set $once (i32.const 1) @@ -331,7 +379,9 @@ ;; CHECK-NEXT: (call $foo ;; CHECK-NEXT: (global.get $once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $once ;; CHECK-NEXT: (i32.const 1) @@ -344,7 +394,9 @@ ;; value, which is dangerous. (global.get $once) ) - (return) + (then + (return) + ) ) (global.set $once (i32.const 1) @@ -374,11 +426,17 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (global.get $global) - ;; CHECK-NEXT: (call $foo) - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $global - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -386,10 +444,16 @@ (if (if (result i32) (global.get $global) ;; the global's value may cause foo() to be called - (call $foo) - (i32.const 1) + (then + (call $foo) + ) + (else + (i32.const 1) + ) + ) + (then + (global.set $global (i32.const 1)) ) - (global.set $global (i32.const 1)) ) ) @@ -416,11 +480,17 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (call $foo) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -429,11 +499,17 @@ (if (result i32) (call $foo) ;; these side effects are not a problem, as the global's ;; value cannot reach them. - (i32.const 1) - (global.get $global) ;; the global's value flows out through the if, + (then + (i32.const 1) + ) + (else + (global.get $global) ;; the global's value flows out through the if, + ) ;; safely ) - (global.set $global (i32.const 1)) + (then + (global.set $global (i32.const 1)) + ) ) ) @@ -459,8 +535,10 @@ ;; CHECK-NEXT: (local.tee $temp ;; CHECK-NEXT: (global.get $global) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $global - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $global + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -470,7 +548,9 @@ (local.tee $temp (global.get $global) ;; the global's value flows into a place that has ) ;; side effects, so it may be noticed. - (global.set $global (i32.const 1)) + (then + (global.set $global (i32.const 1)) + ) ) ) ) @@ -505,8 +585,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -528,8 +610,10 @@ ) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) ) @@ -554,8 +638,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.eq @@ -563,8 +649,10 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -579,8 +667,10 @@ (i32.eqz (global.get $once) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) (i32.eq @@ -588,8 +678,10 @@ (i32.const 0) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) ) @@ -614,18 +706,24 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $once - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $once + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.eq ;; CHECK-NEXT: (global.get $once) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $once - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $once + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -640,18 +738,24 @@ (i32.eqz (global.get $once) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) + ) + (else + (nop) ;; This breaks the pattern we are looking for. ) - (nop) ;; This breaks the pattern we are looking for. ) (i32.eq (global.get $once) (i32.const 0) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) ) @@ -677,15 +781,19 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.eq @@ -693,8 +801,10 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -709,15 +819,19 @@ ;; A third nested appearance. (if (global.get $once) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) (global.get $once) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) (i32.eq @@ -725,8 +839,10 @@ (i32.const 0) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) ) @@ -754,8 +870,10 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $once) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $once - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $once + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.eq @@ -763,8 +881,10 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.set $once - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (global.set $once + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -788,8 +908,10 @@ (i32.eqz (global.get $once) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) (i32.eq @@ -797,8 +919,10 @@ (i32.const 0) ) ) - (global.set $once - (i32.const 1) + (then + (global.set $once + (i32.const 1) + ) ) ) ) diff --git a/test/lit/passes/simplify-locals-eh.wast b/test/lit/passes/simplify-locals-eh.wast index 36bd110834f..5e4a395d3f9 100644 --- a/test/lit/passes/simplify-locals-eh.wast +++ b/test/lit/passes/simplify-locals-eh.wast @@ -196,7 +196,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -204,7 +204,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -228,18 +228,22 @@ (drop (local.get $1)) (if (local.get $p) - (block - ;; We also optimize in this block, which is adjacent to the code before - ;; us. It is valid to optimize the 1 to a 0 here, as it is dominated by - ;; the code earlier. - (drop (local.get $0)) - (drop (local.get $1)) + (then + (block + ;; We also optimize in this block, which is adjacent to the code before + ;; us. It is valid to optimize the 1 to a 0 here, as it is dominated by + ;; the code earlier. + (drop (local.get $0)) + (drop (local.get $1)) + ) ) - (block - ;; We could also optimize here, but atm just look at code adjacent to - ;; its dominator. TODO - (drop (local.get $0)) - (drop (local.get $1)) + (else + (block + ;; We could also optimize here, but atm just look at code adjacent to + ;; its dominator. TODO + (drop (local.get $0)) + (drop (local.get $1)) + ) ) ) ;; As in the else, this could be optimized. TODO diff --git a/test/lit/passes/simplify-locals-gc-nn.wast b/test/lit/passes/simplify-locals-gc-nn.wast index df5148d126a..32c881de81f 100644 --- a/test/lit/passes/simplify-locals-gc-nn.wast +++ b/test/lit/passes/simplify-locals-gc-nn.wast @@ -154,7 +154,9 @@ ;; CHECK-NEXT: (local $temp ((ref func) nullref)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-return-tuple-nn @@ -165,10 +167,12 @@ ;; Instead, we can remove the local.set entirely, as it has no gets. (if (i32.const 0) - (local.set $temp - (tuple.make 2 - (ref.func $if-return-tuple-nn) - (ref.null none) + (then + (local.set $temp + (tuple.make 2 + (ref.func $if-return-tuple-nn) + (ref.null none) + ) ) ) ) diff --git a/test/lit/passes/simplify-locals-gc.wast b/test/lit/passes/simplify-locals-gc.wast index 2c5f56952e0..98d1f5925c0 100644 --- a/test/lit/passes/simplify-locals-gc.wast +++ b/test/lit/passes/simplify-locals-gc.wast @@ -166,8 +166,10 @@ ;; CHECK-NEXT: (local $x (ref func)) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (ref.func $if-nnl) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (ref.func $if-nnl) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $helper @@ -195,8 +197,10 @@ ;; do not optimize here. (if (i32.const 1) - (local.set $x - (ref.func $if-nnl) + (then + (local.set $x + (ref.func $if-nnl) + ) ) ) ;; An exta set + gets, just to avoid other optimizations kicking in @@ -219,8 +223,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (ref.func $if-nnl) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (ref.func $if-nnl) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $helper @@ -241,8 +247,10 @@ ) (if (i32.const 1) - (local.set $x - (ref.func $if-nnl) + (then + (local.set $x + (ref.func $if-nnl) + ) ) ) (call $helper diff --git a/test/lit/passes/simplify-locals-tnh.wast b/test/lit/passes/simplify-locals-tnh.wast index fa10c318d46..21f4863c849 100644 --- a/test/lit/passes/simplify-locals-tnh.wast +++ b/test/lit/passes/simplify-locals-tnh.wast @@ -57,8 +57,10 @@ ;; TNH-NEXT: ) ;; TNH-NEXT: (if ;; TNH-NEXT: (i32.const 0) - ;; TNH-NEXT: (return - ;; TNH-NEXT: (i32.const 1) + ;; TNH-NEXT: (then + ;; TNH-NEXT: (return + ;; TNH-NEXT: (i32.const 1) + ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; TNH-NEXT: (local.get $temp) @@ -72,8 +74,10 @@ ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (i32.const 0) - ;; NO_TNH-NEXT: (return - ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (return + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (local.get $temp) @@ -91,8 +95,10 @@ ) (if (i32.const 0) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (local.get $temp) diff --git a/test/lit/passes/stack-check-memory64.wast b/test/lit/passes/stack-check-memory64.wast index 201910f36b0..137b156de2f 100644 --- a/test/lit/passes/stack-check-memory64.wast +++ b/test/lit/passes/stack-check-memory64.wast @@ -39,7 +39,9 @@ ;; CHECK-NEXT: (global.get $__stack_limit) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $sp ;; CHECK-NEXT: (local.get $0) @@ -63,30 +65,40 @@ (module ;; if the global names are taken we should not crash (memory i64 (data)) - ;; CHECK: (type $0 (func (param i64 i64))) + ;; CHECK: (type $0 (func (result i64))) + + ;; CHECK: (type $1 (func (param i64 i64))) ;; CHECK: (global $sp (mut i64) (i64.const 0)) - (global $sp (mut i64) (i64.const 0))) + (global $sp (mut i64) (i64.const 0)) ;; CHECK: (global $__stack_base (mut i64) (i64.const 0)) (global $__stack_base (mut i64) (i64.const 0)) ;; CHECK: (global $__stack_limit (mut i64) (i64.const 0)) (global $__stack_limit (mut i64) (i64.const 0)) + ;; CHECK: (global $__stack_base_3 (mut i64) (i64.const 0)) + + ;; CHECK: (global $__stack_limit_3 (mut i64) (i64.const 0)) + + ;; CHECK: (memory $0 i64 0 65536) + + ;; CHECK: (data $0 (i64.const 0) "") + + ;; CHECK: (export "use_stack" (func $0)) (export "use_stack" (func $0)) + ;; CHECK: (export "__set_stack_limits" (func $__set_stack_limits)) + + ;; CHECK: (func $0 (result i64) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) (func $0 (result i64) (unreachable) ) ) -;; CHECK: (memory $0 i64 0 65536) - -;; CHECK: (data $0 (i64.const 0) "") - -;; CHECK: (export "__set_stack_limits" (func $__set_stack_limits)) - ;; CHECK: (func $__set_stack_limits (param $0 i64) (param $1 i64) -;; CHECK-NEXT: (global.set $__stack_base +;; CHECK-NEXT: (global.set $__stack_base_3 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (global.set $__stack_limit +;; CHECK-NEXT: (global.set $__stack_limit_3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/stack-ir-non-nullable.wast b/test/lit/passes/stack-ir-non-nullable.wast index e2bd63271db..62d75d61f04 100644 --- a/test/lit/passes/stack-ir-non-nullable.wast +++ b/test/lit/passes/stack-ir-non-nullable.wast @@ -41,14 +41,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -86,14 +90,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -131,14 +139,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -183,14 +195,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -233,14 +249,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -280,14 +300,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -325,14 +349,18 @@ (i32.const 0) ) ) - (local.set $temp - (i31.new - (i32.const 1) + (then + (local.set $temp + (i31.new + (i32.const 1) + ) ) ) - (local.set $temp - (i31.new - (i32.const 2) + (else + (local.set $temp + (i31.new + (i32.const 2) + ) ) ) ) @@ -386,19 +414,23 @@ (i32.const 1) ) ) - (local.set $temp - (tuple.make 2 - (i32.const 2) - (i31.new - (i32.const 3) + (then + (local.set $temp + (tuple.make 2 + (i32.const 2) + (i31.new + (i32.const 3) + ) ) ) ) - (local.set $temp - (tuple.make 2 - (i32.const 4) - (i31.new - (i32.const 5) + (else + (local.set $temp + (tuple.make 2 + (i32.const 4) + (i31.new + (i32.const 5) + ) ) ) ) @@ -454,19 +486,23 @@ (i32.const 1) ) ) - (local.set $temp - (tuple.make 2 - (i32.const 2) - (i31.new - (i32.const 3) + (then + (local.set $temp + (tuple.make 2 + (i32.const 2) + (i31.new + (i32.const 3) + ) ) ) ) - (local.set $temp - (tuple.make 2 - (i32.const 4) - (i31.new - (i32.const 5) + (else + (local.set $temp + (tuple.make 2 + (i32.const 4) + (i31.new + (i32.const 5) + ) ) ) ) @@ -501,11 +537,15 @@ (local.get $temp) (i32.const 0) ) - (local.set $temp - (i32.const 1) + (then + (local.set $temp + (i32.const 1) + ) ) - (local.set $temp - (i32.const 2) + (else + (local.set $temp + (i32.const 2) + ) ) ) (local.get $temp) @@ -544,26 +584,30 @@ ) (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + (drop + (local.get $temp) + ) ) ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + (drop + (local.get $temp) + ) ) ) ) @@ -597,24 +641,28 @@ ) (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + ;; A get was removed here. ) - ;; A get was removed here. ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + (drop + (local.get $temp) + ) ) ) ) @@ -645,25 +693,29 @@ ) (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + (drop + (local.get $temp) + ) ) ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + ;; A get was removed here. ) - ;; A get was removed here. ) ) ) @@ -689,23 +741,27 @@ ) (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + ;; A get was removed here. ) - ;; A get was removed here. ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) + ;; A get was removed here. ) - ;; A get was removed here. ) ) ) @@ -727,20 +783,24 @@ ;; optimize both arms. (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) ) ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) ) ) ) @@ -766,20 +826,24 @@ ;; them as well. (if (i32.const 0) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (then + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) ) ) - (block - (local.set $temp - (local.get $param) - ) - (drop - (local.get $temp) + (else + (block + (local.set $temp + (local.get $param) + ) + (drop + (local.get $temp) + ) ) ) ) @@ -959,13 +1023,17 @@ ;; In this if arm we write to $temp twice. That shouldn't confuse us; there's ;; still a use after the if, and we should not remove the set-get pair before ;; the if. - (local.set $temp - (local.tee $temp - (local.get $param) + (then + (local.set $temp + (local.tee $temp + (local.get $param) + ) ) ) - (local.set $temp - (local.get $param) + (else + (local.set $temp + (local.get $param) + ) ) ) (local.get $temp) diff --git a/test/lit/passes/type-generalizing.wast b/test/lit/passes/type-generalizing.wast index c874cc76cd3..502f57235aa 100644 --- a/test/lit/passes/type-generalizing.wast +++ b/test/lit/passes/type-generalizing.wast @@ -93,8 +93,12 @@ ;; CHECK-NEXT: (local $y eqref) ;; CHECK-NEXT: (if (result eqref) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if (result eqref) @@ -103,9 +107,13 @@ (if (result i31ref) (i32.const 0) ;; Require that typeof($x) <: eqref. - (local.get $x) + (then + (local.get $x) + ) ;; Require that typeof($y) <: eqref. - (local.get $y) + (else + (local.get $y) + ) ) ) diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index 34f156a2b08..9327ebdb178 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -1019,10 +1019,6 @@ (global $g2 (ref $C') (struct.new_default $D2')) ) - (global $g1 (ref $B) (struct.new_default $D1)) - (global $g2 (ref $C) (struct.new_default $D2)) -) - ;; Check that a ref.test inhibits merging (ref.cast is already checked above). (module ;; CHECK: (rec diff --git a/test/lit/passes/type-refining.wast b/test/lit/passes/type-refining.wast index 0a133d7a09c..8ce95c46d0e 100644 --- a/test/lit/passes/type-refining.wast +++ b/test/lit/passes/type-refining.wast @@ -1026,20 +1026,28 @@ ;; CHECK-NEXT: (local.get $A) ;; CHECK-NEXT: (if (result (ref $A)) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (struct.get $A 0 - ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (if (result (ref $A)) ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (struct.get $A 0 - ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1056,20 +1064,28 @@ (local.get $A) (if (result (ref null $A)) (i32.const 1) - (struct.get $A 0 - (local.get $A) + (then + (struct.get $A 0 + (local.get $A) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) (drop (struct.new $A (if (result (ref null $A)) (i32.const 1) - (struct.get $A 0 - (local.get $A) + (then + (struct.get $A 0 + (local.get $A) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) ) diff --git a/test/lit/passes/type-ssa_and_merging.wast b/test/lit/passes/type-ssa_and_merging.wast index 3fbff170d20..670de31ac45 100644 --- a/test/lit/passes/type-ssa_and_merging.wast +++ b/test/lit/passes/type-ssa_and_merging.wast @@ -80,9 +80,11 @@ ;; NOP: (func $get-a-1 (type $0) (; has Stack IR ;) (param $0 (ref $A)) (result i32) ;; NOP-NEXT: (if ;; NOP-NEXT: (call $import) - ;; NOP-NEXT: (return - ;; NOP-NEXT: (call $get-a-1 - ;; NOP-NEXT: (local.get $0) + ;; NOP-NEXT: (then + ;; NOP-NEXT: (return + ;; NOP-NEXT: (call $get-a-1 + ;; NOP-NEXT: (local.get $0) + ;; NOP-NEXT: ) ;; NOP-NEXT: ) ;; NOP-NEXT: ) ;; NOP-NEXT: ) @@ -93,8 +95,10 @@ ;; YES: (func $get-a-1 (type $1) (param $0 (ref $A)) ;; YES-NEXT: (if ;; YES-NEXT: (call $import) - ;; YES-NEXT: (call $get-a-1 - ;; YES-NEXT: (local.get $0) + ;; YES-NEXT: (then + ;; YES-NEXT: (call $get-a-1 + ;; YES-NEXT: (local.get $0) + ;; YES-NEXT: ) ;; YES-NEXT: ) ;; YES-NEXT: ) ;; YES-NEXT: ) @@ -104,9 +108,11 @@ ;; is necessary to avoid inlining making this testcase trivial even in NOP). (if (call $import) - (return - (call $get-a-1 - (local.get $ref) + (then + (return + (call $get-a-1 + (local.get $ref) + ) ) ) ) @@ -116,9 +122,11 @@ ;; NOP: (func $get-a-2 (type $0) (; has Stack IR ;) (param $0 (ref $A)) (result i32) ;; NOP-NEXT: (if ;; NOP-NEXT: (call $import) - ;; NOP-NEXT: (return - ;; NOP-NEXT: (call $get-a-2 - ;; NOP-NEXT: (local.get $0) + ;; NOP-NEXT: (then + ;; NOP-NEXT: (return + ;; NOP-NEXT: (call $get-a-2 + ;; NOP-NEXT: (local.get $0) + ;; NOP-NEXT: ) ;; NOP-NEXT: ) ;; NOP-NEXT: ) ;; NOP-NEXT: ) @@ -129,8 +137,10 @@ ;; YES: (func $get-a-2 (type $1) (param $0 (ref $A)) ;; YES-NEXT: (if ;; YES-NEXT: (call $import) - ;; YES-NEXT: (call $get-a-2 - ;; YES-NEXT: (local.get $0) + ;; YES-NEXT: (then + ;; YES-NEXT: (call $get-a-2 + ;; YES-NEXT: (local.get $0) + ;; YES-NEXT: ) ;; YES-NEXT: ) ;; YES-NEXT: ) ;; YES-NEXT: ) @@ -138,9 +148,11 @@ ;; Parallel to the above. (if (call $import) - (return - (call $get-a-2 - (local.get $ref) + (then + (return + (call $get-a-2 + (local.get $ref) + ) ) ) ) diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index df7e6c033fe..38549504e8e 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -275,8 +275,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref $sub)) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (struct.new_default $sub) - ;; CHECK-NEXT: (struct.new_default $sub) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (struct.new_default $sub) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (struct.new_default $sub) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -285,8 +289,12 @@ (if (result (ref $super)) (i32.const 0) ;; This requires $sub <: $super. - (struct.new $sub) - (struct.new $sub) + (then + (struct.new $sub) + ) + (else + (struct.new $sub) + ) ) ) ) diff --git a/test/lit/passes/vacuum-eh.wast b/test/lit/passes/vacuum-eh.wast index b6b4629cd0a..68b5f7b1e43 100644 --- a/test/lit/passes/vacuum-eh.wast +++ b/test/lit/passes/vacuum-eh.wast @@ -185,10 +185,14 @@ ;; CHECK-NEXT: (do ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (catch_all @@ -210,8 +214,12 @@ (do (if (local.get $0) - (throw $e (i32.const 0)) - (unreachable) + (then + (throw $e (i32.const 0)) + ) + (else + (unreachable) + ) ) ) (catch_all) diff --git a/test/lit/passes/vacuum-func.wast b/test/lit/passes/vacuum-func.wast index 6f93e400287..6181a662def 100644 --- a/test/lit/passes/vacuum-func.wast +++ b/test/lit/passes/vacuum-func.wast @@ -59,7 +59,9 @@ ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (i32.const 1) @@ -78,7 +80,9 @@ ;; test at least.) (if (local.get $x) - (unreachable) + (then + (unreachable) + ) ) (local.set $x diff --git a/test/lit/passes/vacuum-gc.wast b/test/lit/passes/vacuum-gc.wast index be49bf1cf33..27cd6f52d73 100644 --- a/test/lit/passes/vacuum-gc.wast +++ b/test/lit/passes/vacuum-gc.wast @@ -51,10 +51,14 @@ ;; synthesize and allocate a new struct value. Vacuum should not error ;; on this case, though. Instead, the end result of this function should ;; simply be empty, as everything here can be vacuumed away. - (block (result (ref ${})) - (struct.new ${}) + (then + (block (result (ref ${})) + (struct.new ${}) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) ) diff --git a/test/lit/passes/vacuum-intrinsics.wast b/test/lit/passes/vacuum-intrinsics.wast index 6b0654fb78e..8ae5c0a3317 100644 --- a/test/lit/passes/vacuum-intrinsics.wast +++ b/test/lit/passes/vacuum-intrinsics.wast @@ -97,16 +97,20 @@ ;; CHECK-NEXT: (ref.func $i) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $ifTrue (result i32) - ;; CHECK-NEXT: (call $nop) - ;; CHECK-NEXT: (call $call.without.effects - ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $ifTrue (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $ifFalse (result i32) - ;; CHECK-NEXT: (call $nop) - ;; CHECK-NEXT: (call $call.without.effects - ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $ifFalse (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -124,13 +128,17 @@ ) ;; The arms fall through their blocks and also through the if, and end ;; up used by the set. - (block $ifTrue (result i32) - (call $nop) - (call $call.without.effects (ref.func $i)) + (then + (block $ifTrue (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) ) - (block $ifFalse (result i32) - (call $nop) - (call $call.without.effects (ref.func $i)) + (else + (block $ifFalse (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) ) ) ) @@ -145,13 +153,17 @@ ;; CHECK-NEXT: (ref.func $i) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $ifTrue (result i32) - ;; CHECK-NEXT: (call $nop) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (block $ifTrue (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $ifFalse (result i32) - ;; CHECK-NEXT: (call $nop) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (block $ifFalse (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -165,13 +177,17 @@ ) ;; As above, but now there is a drop outside the if, so the arms are ;; unused and we can optimize them. - (block $ifTrue (result i32) - (call $nop) - (call $call.without.effects (ref.func $i)) + (then + (block $ifTrue (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) ) - (block $ifFalse (result i32) - (call $nop) - (call $call.without.effects (ref.func $i)) + (else + (block $ifFalse (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) ) ) ) @@ -181,11 +197,15 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result (ref any)) ;; CHECK-NEXT: (call $i) - ;; CHECK-NEXT: (call $call.without.effects-ref - ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $call.without.effects-ref + ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $call.without.effects-ref - ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $call.without.effects-ref + ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -196,8 +216,12 @@ (call $i) ;; As above, but the type of these unused values prevents us from ;; optimizing as we cannot create a "zero" for them. - (call $call.without.effects-ref (ref.func $ref)) - (call $call.without.effects-ref (ref.func $ref)) + (then + (call $call.without.effects-ref (ref.func $ref)) + ) + (else + (call $call.without.effects-ref (ref.func $ref)) + ) ) ) ) diff --git a/test/lit/passes/vacuum-tnh.wast b/test/lit/passes/vacuum-tnh.wast index f6d30a2c5d6..f74dc3c8761 100644 --- a/test/lit/passes/vacuum-tnh.wast +++ b/test/lit/passes/vacuum-tnh.wast @@ -286,47 +286,71 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) - ;; YESTNH-NEXT: (unreachable) - ;; YESTNH-NEXT: (unreachable) + ;; YESTNH-NEXT: (then + ;; YESTNH-NEXT: (unreachable) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: (else + ;; YESTNH-NEXT: (unreachable) + ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; NO_TNH: (func $if-unreachable (type $0) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (call $if-unreachable - ;; NO_TNH-NEXT: (i32.const 0) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (call $if-unreachable + ;; NO_TNH-NEXT: (i32.const 0) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) - ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (unreachable) - ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) (func $if-unreachable (param $p i32) ;; The if arm can be nopped, as in tnh we assume we never reach it. (if (local.get $p) - (unreachable) + (then + (unreachable) + ) ) ;; This else arm can be removed. (if (local.get $p) - (call $if-unreachable - (i32.const 0) + (then + (call $if-unreachable + (i32.const 0) + ) + ) + (else + (unreachable) ) - (unreachable) ) ;; Both of these can be removed, but we leave this for DCE to handle. (if (local.get $p) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) @@ -339,8 +363,12 @@ ;; NO_TNH: (func $if-unreachable-value (type $3) (param $p i32) (result i32) ;; NO_TNH-NEXT: (if (result i32) ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (unreachable) - ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) (func $if-unreachable-value (param $p i32) (result i32) @@ -348,8 +376,12 @@ ;; cannot have a nop there. (if (result i32) (local.get $p) - (unreachable) - (i32.const 1) + (then + (unreachable) + ) + (else + (i32.const 1) + ) ) ) @@ -362,30 +394,40 @@ ;; NO_TNH: (func $if-unreachable-value-2 (type $3) (param $p i32) (result i32) ;; NO_TNH-NEXT: (if (result i32) ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (else + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) (func $if-unreachable-value-2 (param $p i32) (result i32) ;; As above but in the other arm. (if (result i32) (local.get $p) - (i32.const 1) - (unreachable) + (then + (i32.const 1) + ) + (else + (unreachable) + ) ) ) ;; YESTNH: (func $block-unreachable (type $0) (param $p i32) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) - ;; YESTNH-NEXT: (block + ;; YESTNH-NEXT: (then ;; YESTNH-NEXT: (i32.store ;; YESTNH-NEXT: (i32.const 0) ;; YESTNH-NEXT: (i32.const 1) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) - ;; YESTNH-NEXT: (return) + ;; YESTNH-NEXT: (then + ;; YESTNH-NEXT: (return) + ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) @@ -394,14 +436,16 @@ ;; NO_TNH: (func $block-unreachable (type $0) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (block + ;; NO_TNH-NEXT: (then ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 0) ;; NO_TNH-NEXT: (i32.const 1) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (return) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (return) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 2) @@ -414,22 +458,26 @@ (func $block-unreachable (param $p i32) (if (local.get $p) - (block - (i32.store - (i32.const 0) - (i32.const 1) - ) - (if - (local.get $p) - (return) - ) - ;; This store can be removed as it leads up to an unreachable which we - ;; assume is never reached. - (i32.store - (i32.const 2) - (i32.const 3) + (then + (block + (i32.store + (i32.const 0) + (i32.const 1) + ) + (if + (local.get $p) + (then + (return) + ) + ) + ;; This store can be removed as it leads up to an unreachable which we + ;; assume is never reached. + (i32.store + (i32.const 2) + (i32.const 3) + ) + (unreachable) ) - (unreachable) ) ) ) @@ -437,55 +485,61 @@ ;; YESTNH: (func $block-unreachable-named (type $0) (param $p i32) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) - ;; YESTNH-NEXT: (block $named - ;; YESTNH-NEXT: (i32.store - ;; YESTNH-NEXT: (i32.const 0) - ;; YESTNH-NEXT: (i32.const 1) - ;; YESTNH-NEXT: ) - ;; YESTNH-NEXT: (br_if $named - ;; YESTNH-NEXT: (local.get $p) + ;; YESTNH-NEXT: (then + ;; YESTNH-NEXT: (block $named + ;; YESTNH-NEXT: (i32.store + ;; YESTNH-NEXT: (i32.const 0) + ;; YESTNH-NEXT: (i32.const 1) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: (br_if $named + ;; YESTNH-NEXT: (local.get $p) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) - ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; NO_TNH: (func $block-unreachable-named (type $0) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (block $named - ;; NO_TNH-NEXT: (i32.store - ;; NO_TNH-NEXT: (i32.const 0) - ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: ) - ;; NO_TNH-NEXT: (br_if $named - ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: ) - ;; NO_TNH-NEXT: (i32.store - ;; NO_TNH-NEXT: (i32.const 2) - ;; NO_TNH-NEXT: (i32.const 3) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (block $named + ;; NO_TNH-NEXT: (i32.store + ;; NO_TNH-NEXT: (i32.const 0) + ;; NO_TNH-NEXT: (i32.const 1) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (br_if $named + ;; NO_TNH-NEXT: (local.get $p) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (i32.store + ;; NO_TNH-NEXT: (i32.const 2) + ;; NO_TNH-NEXT: (i32.const 3) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) - ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) (func $block-unreachable-named (param $p i32) (if (local.get $p) - (block $named - (i32.store - (i32.const 0) - (i32.const 1) - ) - ;; As above, but now the block is named and we use a br_if. We should - ;; again only remove the last store. - (br_if $named - (local.get $p) - ) - (i32.store - (i32.const 2) - (i32.const 3) + (then + (block $named + (i32.store + (i32.const 0) + (i32.const 1) + ) + ;; As above, but now the block is named and we use a br_if. We should + ;; again only remove the last store. + (br_if $named + (local.get $p) + ) + (i32.store + (i32.const 2) + (i32.const 3) + ) + (unreachable) ) - (unreachable) ) ) ) @@ -496,7 +550,7 @@ ;; NO_TNH: (func $block-unreachable-all (type $0) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (block + ;; NO_TNH-NEXT: (then ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 0) ;; NO_TNH-NEXT: (i32.const 1) @@ -512,18 +566,20 @@ (func $block-unreachable-all (param $p i32) (if (local.get $p) - (block - ;; Both stores can be removed, and even the entire if arm and then the - ;; entire if. - (i32.store - (i32.const 0) - (i32.const 1) - ) - (i32.store - (i32.const 2) - (i32.const 3) + (then + (block + ;; Both stores can be removed, and even the entire if arm and then the + ;; entire if. + (i32.store + (i32.const 0) + (i32.const 1) + ) + (i32.store + (i32.const 2) + (i32.const 3) + ) + (unreachable) ) - (unreachable) ) ) ) @@ -625,7 +681,9 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) - ;; YESTNH-NEXT: (br $loop) + ;; YESTNH-NEXT: (then + ;; YESTNH-NEXT: (br $loop) + ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) @@ -638,7 +696,9 @@ ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) - ;; NO_TNH-NEXT: (br $loop) + ;; NO_TNH-NEXT: (then + ;; NO_TNH-NEXT: (br $loop) + ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 2) @@ -655,7 +715,9 @@ ) (if (local.get $p) - (br $loop) + (then + (br $loop) + ) ) ;; This store can be removed as it leads up to an unreachable which we ;; assume is never reached. diff --git a/test/lit/passes/vacuum_all-features.wast b/test/lit/passes/vacuum_all-features.wast index b228d13eeb4..e4b183663eb 100644 --- a/test/lit/passes/vacuum_all-features.wast +++ b/test/lit/passes/vacuum_all-features.wast @@ -69,22 +69,34 @@ ) (if (i32.const 100) - (nop) - (drop - (i32.const 101) + (then + (nop) + ) + (else + (drop + (i32.const 101) + ) ) ) (if (i32.const 102) - (drop - (i32.const 103) + (then + (drop + (i32.const 103) + ) + ) + (else + (nop) ) - (nop) ) (if (i32.const 104) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) ) ;; CHECK: (func $l (type $3) (result i32) @@ -350,63 +362,83 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $d) - ;; CHECK-NEXT: (f64.ne - ;; CHECK-NEXT: (f64.promote_f32 - ;; CHECK-NEXT: (f32.load - ;; CHECK-NEXT: (local.tee $l - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (local.get $b) - ;; CHECK-NEXT: (i32.const 60) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (f64.promote_f32 + ;; CHECK-NEXT: (f32.load + ;; CHECK-NEXT: (local.tee $l + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $b) + ;; CHECK-NEXT: (i32.const 60) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $e) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $e) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $Gu (type $4) (param $b i32) (param $e f64) (param $l i32) (param $d i32) (if (if (result i32) (local.get $d) - (block $block1 (result i32) - (nop) - (f64.ne - (f64.promote_f32 - (f32.load - (local.tee $l - (i32.add - (local.get $b) - (i32.const 60) + (then + (block $block1 (result i32) + (nop) + (f64.ne + (f64.promote_f32 + (f32.load + (local.tee $l + (i32.add + (local.get $b) + (i32.const 60) + ) ) ) ) + (local.get $e) ) - (local.get $e) ) ) - (i32.const 0) + (else + (i32.const 0) + ) + ) + (then + (unreachable) ) - (unreachable) ) ) ;; CHECK: (func $if-drop (type $3) (result i32) ;; CHECK-NEXT: (block $out ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $if-drop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $int) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $int) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $out) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $out) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $if-drop) - ;; CHECK-NEXT: (br $out) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $int) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $out) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $int) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -417,15 +449,23 @@ (drop (if (result i32) (call $if-drop) - (call $int) - (br $out) + (then + (call $int) + ) + (else + (br $out) + ) ) ) (drop (if (result i32) (call $if-drop) - (br $out) - (call $int) + (then + (br $out) + ) + (else + (call $int) + ) ) ) ) @@ -565,8 +605,12 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (call $if2drops) - ;; CHECK-NEXT: (call $if2drops) - ;; CHECK-NEXT: (call $if2drops) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (call $if2drops) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (call $if2drops) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) @@ -574,11 +618,15 @@ (func $if2drops (result i32) (if (call $if2drops) - (drop - (call $if2drops) + (then + (drop + (call $if2drops) + ) ) - (drop - (call $if2drops) + (else + (drop + (call $if2drops) + ) ) ) (i32.const 2) @@ -586,11 +634,15 @@ ;; CHECK: (func $if2drops-different (type $3) (result i32) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (call $if2drops) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $if2drops) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $if2drops) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call $unary) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $unary) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 2) @@ -598,11 +650,15 @@ (func $if2drops-different (result i32) (if (call $if2drops) - (drop - (call $if2drops) ;; i32 + (then + (drop + (call $if2drops) ;; i32 + ) ) - (drop - (call $unary) ;; f32! + (else + (drop + (call $unary) ;; f32! + ) ) ) (i32.const 2) @@ -619,26 +675,34 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-const (param $x i32) - (if (i32.const 0) (call $if-const (i32.const 1))) - (if (i32.const 2) (call $if-const (i32.const 3))) - (if (i32.const 0) (call $if-const (i32.const 4)) (call $if-const (i32.const 5))) - (if (i32.const 6) (call $if-const (i32.const 7)) (call $if-const (i32.const 8))) + (if (i32.const 0) (then (call $if-const (i32.const 1)))) + (if (i32.const 2) (then (call $if-const (i32.const 3)))) + (if (i32.const 0) (then (call $if-const (i32.const 4)) )(else (call $if-const (i32.const 5)))) + (if (i32.const 6) (then (call $if-const (i32.const 7)) )(else (call $if-const (i32.const 8)))) ) ;; CHECK: (func $drop-if-both-unreachable (type $1) (param $0 i32) ;; CHECK-NEXT: (block $out ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (br $out) - ;; CHECK-NEXT: (br $out) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $out) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $out) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -647,16 +711,24 @@ (drop (if (result i32) (local.get $0) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) (drop (if (result i32) (local.get $0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) @@ -664,7 +736,7 @@ ;; CHECK-NEXT: (block $out ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -678,14 +750,18 @@ (block $out (if (local.get $x) - (block - (if - (i32.const 1) - (block - (local.set $x - (local.get $x) + (then + (block + (if + (i32.const 1) + (then + (block + (local.set $x + (local.get $x) + ) + (br $out) + ) ) - (br $out) ) ) ) @@ -804,8 +880,12 @@ (block $label$0 (if (i32.const 170996275) - (unreachable) - (br $label$0) + (then + (unreachable) + ) + (else + (br $label$0) + ) ) ) (unreachable) @@ -817,8 +897,12 @@ (block $label$0 (if (i32.const 170996275) - (nop) - (br $label$0) + (then + (nop) + ) + (else + (br $label$0) + ) ) ) (unreachable) @@ -833,8 +917,12 @@ (block $label$0 (if (i32.const 170996275) - (br $label$0) - (nop) + (then + (br $label$0) + ) + (else + (nop) + ) ) ) (unreachable) @@ -911,8 +999,12 @@ (br $label$9) ) ) - (unreachable) - (i32.const 1920103026) + (then + (unreachable) + ) + (else + (i32.const 1920103026) + ) ) ) ) @@ -932,7 +1024,9 @@ (br $label$0 (i32.const 1) ) - (br $label$1) + (then + (br $label$1) + ) ) ) (i32.const 1579493952) @@ -952,7 +1046,9 @@ (br $label$0 (i32.const 1) ) - (br $label$1) + (then + (br $label$1) + ) ) ) (i32.const 1579493952) @@ -969,16 +1065,20 @@ (i32.eqz (local.get $0) ) - (block $label$1 - (block - (if ;; we nop this if, which has a type change for block $label$1, no more brs to it - (i32.const 0) - (br_if $label$1 - (i32.const 1717966400) + (then + (block $label$1 + (block + (if ;; we nop this if, which has a type change for block $label$1, no more brs to it + (i32.const 0) + (then + (br_if $label$1 + (i32.const 1717966400) + ) + ) + ) + (drop + (br $label$0) ) - ) - (drop - (br $label$0) ) ) ) @@ -1111,7 +1211,7 @@ ;; CHECK-NEXT: (call $_deflateInit2_ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $global$1 ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) @@ -1128,7 +1228,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (i32.load offset=20 @@ -1145,7 +1245,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $_deflateEnd ;; CHECK-NEXT: (local.get $3) @@ -1204,11 +1304,13 @@ (call $_deflateInit2_ (local.get $3) ) - (block - (global.set $global$1 - (local.get $3) + (then + (block + (global.set $global$1 + (local.get $3) + ) + (return) ) - (return) ) ) (drop @@ -1221,36 +1323,40 @@ ) (i32.const 1) ) - (block (result i32) - (i32.store - (local.get $1) - (i32.load offset=20 - (local.get $3) + (then + (block (result i32) + (i32.store + (local.get $1) + (i32.load offset=20 + (local.get $3) + ) ) - ) - (local.set $0 - (call $_deflateEnd + (local.set $0 + (call $_deflateEnd + (local.get $3) + ) + ) + (global.set $global$1 (local.get $3) ) + (local.get $0) ) - (global.set $global$1 - (local.get $3) - ) - (local.get $0) ) - (block (result i32) - (drop - (call $_deflateEnd + (else + (block (result i32) + (drop + (call $_deflateEnd + (local.get $3) + ) + ) + (global.set $global$1 (local.get $3) ) - ) - (global.set $global$1 - (local.get $3) - ) - (select - (local.get $0) - (i32.const -5) - (local.get $0) + (select + (local.get $0) + (i32.const -5) + (local.get $0) + ) ) ) ) diff --git a/test/lit/source-map.wast b/test/lit/source-map.wast index fcb5e1dd3d2..8d22360adf0 100644 --- a/test/lit/source-map.wast +++ b/test/lit/source-map.wast @@ -13,7 +13,9 @@ (local.get $y) ) ;;@ src.cpp:50:1 - (return) + (then + (return) + ) ) ;;@ src.cpp:60:1 (call $foo @@ -35,8 +37,10 @@ ;; CHECK-NEXT: ;;@ src.cpp:40:1 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) -;; CHECK-NEXT: ;;@ src.cpp:50:1 -;; CHECK-NEXT: (return) +;; CHECK-NEXT: (then +;; CHECK-NEXT: ;;@ src.cpp:50:1 +;; CHECK-NEXT: (return) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ;;@ src.cpp:60:1 ;; CHECK-NEXT: (call $foo diff --git a/test/lit/validation/bad-non-nullable-locals.wast b/test/lit/validation/bad-non-nullable-locals.wast index e34970fde03..558759aeb6a 100644 --- a/test/lit/validation/bad-non-nullable-locals.wast +++ b/test/lit/validation/bad-non-nullable-locals.wast @@ -49,10 +49,14 @@ (if (i32.const 1) ;; Superficially the order is right, but not really. - (local.set $x - (ref.func $helper) + (then + (local.set $x + (ref.func $helper) + ) + ) + (else + (local.get $x) ) - (local.get $x) ) ) diff --git a/test/lit/wasm-split/instrument-funcs.wast b/test/lit/wasm-split/instrument-funcs.wast index cf3ca4af7bd..2dbd578f30b 100644 --- a/test/lit/wasm-split/instrument-funcs.wast +++ b/test/lit/wasm-split/instrument-funcs.wast @@ -36,7 +36,7 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (global.get $baz_timestamp) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (block +;; CHECK-NEXT: (then ;; CHECK-NEXT: (global.set $monotonic_counter ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (global.get $monotonic_counter) @@ -59,7 +59,7 @@ ;; CHECK-NEXT: (local.get $size) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (block +;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store align=1 ;; CHECK-NEXT: (local.get $addr) ;; CHECK-NEXT: (i64.const {{.*}}) diff --git a/test/lit/wasm-split/instrument-in-memory.wast b/test/lit/wasm-split/instrument-in-memory.wast index 3208b0b5de8..91433d424f3 100644 --- a/test/lit/wasm-split/instrument-in-memory.wast +++ b/test/lit/wasm-split/instrument-in-memory.wast @@ -49,7 +49,7 @@ ;; CHECK-NEXT: (local.get $size) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (block +;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store align=1 ;; CHECK-NEXT: (local.get $addr) ;; CHECK-NEXT: (i64.const {{.*}}) diff --git a/test/lit/wasm-split/instrument-in-secondary-memory.wast b/test/lit/wasm-split/instrument-in-secondary-memory.wast index 26ac0ad18d9..18a8b0a4fdf 100644 --- a/test/lit/wasm-split/instrument-in-secondary-memory.wast +++ b/test/lit/wasm-split/instrument-in-secondary-memory.wast @@ -52,7 +52,7 @@ ;; CHECK-NEXT: (local.get $size) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (block +;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store $0 align=1 ;; CHECK-NEXT: (local.get $addr) ;; CHECK-NEXT: (i64.const {{.*}}) diff --git a/test/lit/wasm-split/instrument-memory64.wast b/test/lit/wasm-split/instrument-memory64.wast index ff2a56cadcd..65560d29e76 100644 --- a/test/lit/wasm-split/instrument-memory64.wast +++ b/test/lit/wasm-split/instrument-memory64.wast @@ -30,7 +30,7 @@ ;; CHECK-NEXT: (local.get $size) ;; CHECK-NEXT: (i32.const 16) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (block +;; CHECK-NEXT: (then ;; CHECK-NEXT: (i64.store align=1 ;; CHECK-NEXT: (local.get $addr) ;; CHECK-NEXT: (i64.const {{.*}}) diff --git a/test/lit/wasm-split/jspi-secondary-export.wast b/test/lit/wasm-split/jspi-secondary-export.wast index 57fe849a9af..3729ec00e5e 100644 --- a/test/lit/wasm-split/jspi-secondary-export.wast +++ b/test/lit/wasm-split/jspi-secondary-export.wast @@ -62,7 +62,9 @@ ;; PRIMARY-NEXT: (i32.eqz ;; PRIMARY-NEXT: (global.get $global$1) ;; PRIMARY-NEXT: ) -;; PRIMARY-NEXT: (call $__load_secondary_module) +;; PRIMARY-NEXT: (then +;; PRIMARY-NEXT: (call $__load_secondary_module) +;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: (call_indirect (type $0) ;; PRIMARY-NEXT: (local.get $0) diff --git a/test/lit/wasm-split/jspi.wast b/test/lit/wasm-split/jspi.wast index 340b2acec79..6866f02ffdd 100644 --- a/test/lit/wasm-split/jspi.wast +++ b/test/lit/wasm-split/jspi.wast @@ -43,7 +43,9 @@ ;; PRIMARY-NEXT: (i32.eqz ;; PRIMARY-NEXT: (global.get $global$1) ;; PRIMARY-NEXT: ) - ;; PRIMARY-NEXT: (call $__load_secondary_module) + ;; PRIMARY-NEXT: (then + ;; PRIMARY-NEXT: (call $__load_secondary_module) + ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: (call_indirect (type $0) ;; PRIMARY-NEXT: (i32.const 0) diff --git a/test/lit/wasm-split/multi-memory-lowering-export.wast b/test/lit/wasm-split/multi-memory-lowering-export.wast index 0721ba2a462..152aaf72310 100644 --- a/test/lit/wasm-split/multi-memory-lowering-export.wast +++ b/test/lit/wasm-split/multi-memory-lowering-export.wast @@ -55,8 +55,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.copy @@ -100,8 +102,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $return_size) diff --git a/test/lit/wasm-split/multi-memory-lowering-import.wast b/test/lit/wasm-split/multi-memory-lowering-import.wast index d62609108c2..37ccfa16cb1 100644 --- a/test/lit/wasm-split/multi-memory-lowering-import.wast +++ b/test/lit/wasm-split/multi-memory-lowering-import.wast @@ -52,8 +52,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (memory.copy @@ -97,8 +99,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const -1) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (return -;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return +;; CHECK-NEXT: (i32.const -1) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $return_size) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 05aedd51985..19915b13040 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -1024,8 +1024,12 @@ ;; CHECK: (func $if-else (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else @@ -1040,8 +1044,12 @@ ;; CHECK: (func $if-else-empty (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-empty @@ -1054,11 +1062,11 @@ ;; CHECK: (func $if-else-many (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1078,11 +1086,15 @@ ;; CHECK: (func $if-else-single-nested (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1100,11 +1112,15 @@ ;; CHECK: (func $if-else-folded-body (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1125,8 +1141,12 @@ ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1142,7 +1162,9 @@ ;; CHECK: (func $if-no-else (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-no-else @@ -1155,8 +1177,12 @@ ;; CHECK: (func $if-else-result (type $1) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-result (result i32) @@ -1172,8 +1198,12 @@ ;; CHECK-NEXT: (block $l (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1189,8 +1219,12 @@ ;; CHECK: (func $if-else-folded (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-folded @@ -1208,8 +1242,12 @@ ;; CHECK: (func $if-else-folded-empty (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-folded-empty @@ -1223,11 +1261,11 @@ ;; CHECK: (func $if-else-folded-many (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (else ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1252,11 +1290,15 @@ ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1282,8 +1324,12 @@ ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1302,7 +1348,9 @@ ;; CHECK: (func $if-no-else-folded (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-no-else-folded @@ -1317,8 +1365,12 @@ ;; CHECK: (func $if-else-folded-result (type $1) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-folded-result (result i32) @@ -1337,8 +1389,12 @@ ;; CHECK-NEXT: (block $l (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1357,15 +1413,23 @@ ;; CHECK: (func $if-else-atypical-condition (type $void) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) -;; CHECK-NEXT: (nop) -;; CHECK-NEXT: (nop) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) -;; CHECK-NEXT: (nop) -;; CHECK-NEXT: (nop) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (else +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else-atypical-condition @@ -1378,19 +1442,33 @@ ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (if (result i32) - ;; CHECK-NEXT: (i32.const 3) - ;; CHECK-NEXT: (i32.const 4) - ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 6) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1429,8 +1507,12 @@ ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $label) - ;; CHECK-NEXT: (br $label) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $label) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $label) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1447,11 +1529,15 @@ ;; CHECK-NEXT: (block $label (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $label - ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $label + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br $label - ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (br $label + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2264,7 +2350,9 @@ ;; CHECK-NEXT: (block $l_1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $l_1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $l_1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2289,7 +2377,9 @@ ;; CHECK-NEXT: (block $l_1 ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (br $l_1) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $l_1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $l_0) diff --git a/test/lld/basic_safe_stack.wat.out b/test/lld/basic_safe_stack.wat.out index 617463a6664..7d554cc8839 100644 --- a/test/lld/basic_safe_stack.wat.out +++ b/test/lld/basic_safe_stack.wat.out @@ -32,8 +32,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $1) + (then + (call $__handle_stack_overflow + (local.get $1) + ) ) ) (global.set $__stack_pointer @@ -66,8 +68,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $3) + (then + (call $__handle_stack_overflow + (local.get $3) + ) ) ) (global.set $__stack_pointer diff --git a/test/lld/em_asm_pthread.wasm.out b/test/lld/em_asm_pthread.wasm.out index 40f61e3a71a..3b51b896ab7 100644 --- a/test/lld/em_asm_pthread.wasm.out +++ b/test/lld/em_asm_pthread.wasm.out @@ -134,14 +134,16 @@ (i32.const 0) (i32.const 1) ) - (drop - (memory.atomic.wait32 - (i32.const 4032) - (i32.const 1) - (i64.const -1) + (then + (drop + (memory.atomic.wait32 + (i32.const 4032) + (i32.const 1) + (i64.const -1) + ) ) ) - (block + (else (memory.init $0 (i32.const 1024) (i32.const 0) diff --git a/test/lld/recursive_safe_stack.wat.out b/test/lld/recursive_safe_stack.wat.out index 32c79c31026..ad30dc776aa 100644 --- a/test/lld/recursive_safe_stack.wat.out +++ b/test/lld/recursive_safe_stack.wat.out @@ -46,8 +46,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $3) + (then + (call $__handle_stack_overflow + (local.get $3) + ) ) ) (global.set $global$0 @@ -85,8 +87,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $4) + (then + (call $__handle_stack_overflow + (local.get $4) + ) ) ) (global.set $global$0 @@ -121,8 +125,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $1) + (then + (call $__handle_stack_overflow + (local.get $1) + ) ) ) (global.set $global$0 @@ -159,8 +165,10 @@ (global.get $__stack_limit) ) ) - (call $__handle_stack_overflow - (local.get $2) + (then + (call $__handle_stack_overflow + (local.get $2) + ) ) ) (global.set $global$0 diff --git a/test/lld/safe_stack_standalone-wasm.wat.out b/test/lld/safe_stack_standalone-wasm.wat.out index 353e44b3acc..63d6c09d492 100644 --- a/test/lld/safe_stack_standalone-wasm.wat.out +++ b/test/lld/safe_stack_standalone-wasm.wat.out @@ -44,7 +44,9 @@ (global.get $__stack_limit) ) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$0 (local.get $3) @@ -81,7 +83,9 @@ (global.get $__stack_limit) ) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$0 (local.get $4) @@ -115,7 +119,9 @@ (global.get $__stack_limit) ) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$0 (local.get $1) @@ -151,7 +157,9 @@ (global.get $__stack_limit) ) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $global$0 (local.get $2) diff --git a/test/passes/O.bin.txt b/test/passes/O.bin.txt index 51610d92ff1..d35a4d11c64 100644 --- a/test/passes/O.bin.txt +++ b/test/passes/O.bin.txt @@ -10,15 +10,19 @@ (i64.eqz (local.get $0) ) - (i64.const 1) - (i64.mul - (call $0 - (i64.sub - (local.get $0) - (i64.const 1) + (then + (i64.const 1) + ) + (else + (i64.mul + (call $0 + (i64.sub + (local.get $0) + (i64.const 1) + ) ) + (local.get $0) ) - (local.get $0) ) ) ) @@ -27,15 +31,19 @@ (i64.eqz (local.get $0) ) - (i64.const 1) - (i64.mul - (call $1 - (i64.sub - (local.get $0) - (i64.const 1) + (then + (i64.const 1) + ) + (else + (i64.mul + (call $1 + (i64.sub + (local.get $0) + (i64.const 1) + ) ) + (local.get $0) ) - (local.get $0) ) ) ) @@ -54,7 +62,7 @@ (local.get $0) ) ) - (block + (then (local.set $1 (i64.mul (local.get $0) @@ -83,22 +91,24 @@ (local.get $0) (i64.const 2) ) - (loop $label$3 - (local.set $1 - (i64.mul - (local.get $0) - (local.get $1) + (then + (loop $label$3 + (local.set $1 + (i64.mul + (local.get $0) + (local.get $1) + ) ) - ) - (br_if $label$3 - (i64.gt_s - (local.tee $0 - (i64.sub - (local.get $0) - (i64.const 1) + (br_if $label$3 + (i64.gt_s + (local.tee $0 + (i64.sub + (local.get $0) + (i64.const 1) + ) ) + (i64.const 1) ) - (i64.const 1) ) ) ) diff --git a/test/passes/O3_low-memory-unused_metrics.txt b/test/passes/O3_low-memory-unused_metrics.txt index 3bdce292109..547eb1673ed 100644 --- a/test/passes/O3_low-memory-unused_metrics.txt +++ b/test/passes/O3_low-memory-unused_metrics.txt @@ -93,9 +93,11 @@ total (local.get $0) ) ) - (br_if $label$3 - (i32.load offset=4 - (local.get $0) + (then + (br_if $label$3 + (i32.load offset=4 + (local.get $0) + ) ) ) ) @@ -133,7 +135,9 @@ total (local.get $0) ) ) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (i32.store (local.get $2) @@ -164,7 +168,7 @@ total (local.get $3) (i32.const 42) ) - (block + (then (if (i32.eq (i32.load offset=24 @@ -172,7 +176,7 @@ total ) (i32.const 2) ) - (block + (then (i32.store offset=48 (local.get $0) (call $fimport$14 @@ -249,7 +253,7 @@ total ) ) ) - (block + (then (i32.store offset=20 (local.get $2) (i32.add @@ -362,21 +366,23 @@ total ) (i32.const 9) ) - (local.set $3 - (select - (i32.const 4) - (i32.shl - (i32.gt_s - (i32.load offset=136 - (local.get $2) + (then + (local.set $3 + (select + (i32.const 4) + (i32.shl + (i32.gt_s + (i32.load offset=136 + (local.get $2) + ) + (i32.const 1) ) - (i32.const 1) + (i32.const 2) + ) + (i32.lt_s + (local.get $4) + (i32.const 2) ) - (i32.const 2) - ) - (i32.lt_s - (local.get $4) - (i32.const 2) ) ) ) @@ -635,21 +641,23 @@ total ) (i32.const 9) ) - (local.set $3 - (select - (i32.const 4) - (i32.shl - (i32.gt_s - (i32.load offset=136 - (local.get $2) + (then + (local.set $3 + (select + (i32.const 4) + (i32.shl + (i32.gt_s + (i32.load offset=136 + (local.get $2) + ) + (i32.const 1) ) - (i32.const 1) + (i32.const 2) + ) + (i32.lt_s + (local.get $4) + (i32.const 2) ) - (i32.const 2) - ) - (i32.lt_s - (local.get $4) - (i32.const 2) ) ) ) @@ -711,7 +719,7 @@ total ) ) ) - (block (result i32) + (then (local.set $3 (i32.load offset=20 (local.get $3) @@ -771,20 +779,24 @@ total (local.get $2) ) ) - (local.get $3) + (else + (local.get $3) + ) ) ) - (i32.store offset=48 - (local.get $0) - (call $fimport$14 - (i32.load offset=48 - (local.get $0) - ) - (i32.load offset=8 - (local.get $2) - ) - (i32.load offset=20 - (local.get $2) + (then + (i32.store offset=48 + (local.get $0) + (call $fimport$14 + (i32.load offset=48 + (local.get $0) + ) + (i32.load offset=8 + (local.get $2) + ) + (i32.load offset=20 + (local.get $2) + ) ) ) ) @@ -929,7 +941,7 @@ total (i32.load offset=108 (local.get $2) ) - (block + (then (local.set $3 (i32.load offset=48 (local.get $0) @@ -1062,7 +1074,7 @@ total ) ) ) - (block + (then (local.set $3 (i32.load offset=20 (local.get $2) @@ -1091,7 +1103,7 @@ total ) (local.get $3) ) - (block + (then (block $label$30 (br_if $label$30 (i32.le_u @@ -1299,13 +1311,13 @@ total ) (local.get $6) ) - (block + (then (local.set $3 (local.get $4) ) (br $label$26) ) - (block + (else (local.set $3 (i32.load offset=20 (local.get $2) @@ -1374,7 +1386,7 @@ total (local.get $5) ) ) - (block + (then (i32.store offset=4 (local.get $2) (i32.const 73) @@ -1429,7 +1441,7 @@ total ) (local.get $3) ) - (block + (then (block $label$39 (br_if $label$39 (i32.le_u @@ -1625,7 +1637,7 @@ total ) (if (local.get $5) - (block + (then (local.set $3 (i32.load offset=20 (local.get $2) @@ -1633,7 +1645,7 @@ total ) (br $label$37) ) - (block + (else (local.set $3 (local.get $4) ) @@ -1742,7 +1754,7 @@ total ) (local.get $3) ) - (block + (then (block $label$47 (br_if $label$47 (i32.le_u @@ -1938,7 +1950,7 @@ total ) (if (local.get $5) - (block + (then (local.set $3 (i32.load offset=20 (local.get $2) @@ -1946,7 +1958,7 @@ total ) (br $label$45) ) - (block + (else (local.set $3 (local.get $4) ) @@ -2029,7 +2041,7 @@ total (local.get $2) ) ) - (block + (then (block $label$52 (br_if $label$52 (i32.ge_u @@ -2231,7 +2243,7 @@ total (i32.load offset=20 (local.get $2) ) - (block + (then (block $label$55 (br_if $label$55 (i32.eqz @@ -2375,7 +2387,7 @@ total ) (i32.const 666) ) - (block + (then (br_if $label$58 (i32.eqz (local.get $3) @@ -2424,7 +2436,7 @@ total ) (i32.const 3) ) - (block + (then (br_if $label$61 (i32.ne (local.get $3) @@ -2467,9 +2479,11 @@ total ) (i32.const 3) ) - (i32.store offset=4 - (local.get $2) - (i32.const 666) + (then + (i32.store offset=4 + (local.get $2) + (i32.const 666) + ) ) ) (if @@ -2479,7 +2493,7 @@ total (i32.const -3) ) ) - (block + (then (local.set $3 (i32.const 0) ) @@ -2509,7 +2523,7 @@ total (local.get $1) (i32.const 1) ) - (block + (then (call $fimport$30 (local.get $2) ) @@ -2710,7 +2724,7 @@ total (local.get $4) (i32.const 2) ) - (block + (then (i32.store offset=20 (local.get $2) (i32.add @@ -3115,11 +3129,13 @@ total ) (i32.const 0) ) - (i32.store offset=24 - (local.get $2) - (i32.sub - (i32.const 0) - (local.get $0) + (then + (i32.store offset=24 + (local.get $2) + (i32.sub + (i32.const 0) + (local.get $0) + ) ) ) ) diff --git a/test/passes/converge_O3_metrics.bin.txt b/test/passes/converge_O3_metrics.bin.txt index 54cc551be56..bd977b342de 100644 --- a/test/passes/converge_O3_metrics.bin.txt +++ b/test/passes/converge_O3_metrics.bin.txt @@ -92,19 +92,21 @@ total (i32.const 10888) ) ) - (block $label$2 - (br_if $label$2 - (call_indirect (type $0) - (local.get $1) - (i32.const 10888) - (local.get $0) - (i32.add - (i32.load offset=48 - (i32.load - (local.get $1) + (then + (block $label$2 + (br_if $label$2 + (call_indirect (type $0) + (local.get $1) + (i32.const 10888) + (local.get $0) + (i32.add + (i32.load offset=48 + (i32.load + (local.get $1) + ) ) + (i32.const 8) ) - (i32.const 8) ) ) ) @@ -133,17 +135,21 @@ total (i32.const 24) ) ) - (i32.const 0) - (call_indirect (type $1) - (local.get $0) - (i32.const 10) - (i32.add - (i32.load offset=52 - (i32.load - (local.get $0) + (then + (i32.const 0) + ) + (else + (call_indirect (type $1) + (local.get $0) + (i32.const 10) + (i32.add + (i32.load offset=52 + (i32.load + (local.get $0) + ) ) + (i32.const 422) ) - (i32.const 422) ) ) ) @@ -317,19 +323,21 @@ total (i32.const 10888) ) ) - (block $label$2 - (br_if $label$2 - (call_indirect (type $0) - (local.get $1) - (i32.const 10888) - (local.get $0) - (i32.add - (i32.load offset=48 - (i32.load - (local.get $1) + (then + (block $label$2 + (br_if $label$2 + (call_indirect (type $0) + (local.get $1) + (i32.const 10888) + (local.get $0) + (i32.add + (i32.load offset=48 + (i32.load + (local.get $1) + ) ) + (i32.const 8) ) - (i32.const 8) ) ) ) @@ -358,17 +366,21 @@ total (i32.const 24) ) ) - (i32.const 0) - (call_indirect (type $1) - (local.get $0) - (i32.const 10) - (i32.add - (i32.load offset=52 - (i32.load - (local.get $0) + (then + (i32.const 0) + ) + (else + (call_indirect (type $1) + (local.get $0) + (i32.const 10) + (i32.add + (i32.load offset=52 + (i32.load + (local.get $0) + ) ) + (i32.const 422) ) - (i32.const 422) ) ) ) @@ -537,19 +549,21 @@ total (i32.const 10888) ) ) - (block $label$2 - (br_if $label$2 - (call_indirect (type $0) - (local.get $1) - (i32.const 10888) - (local.get $0) - (i32.add - (i32.load offset=48 - (i32.load - (local.get $1) + (then + (block $label$2 + (br_if $label$2 + (call_indirect (type $0) + (local.get $1) + (i32.const 10888) + (local.get $0) + (i32.add + (i32.load offset=48 + (i32.load + (local.get $1) + ) ) + (i32.const 8) ) - (i32.const 8) ) ) ) @@ -578,17 +592,21 @@ total (i32.const 24) ) ) - (i32.const 0) - (call_indirect (type $1) - (local.get $0) - (i32.const 10) - (i32.add - (i32.load offset=52 - (i32.load - (local.get $0) + (then + (i32.const 0) + ) + (else + (call_indirect (type $1) + (local.get $0) + (i32.const 10) + (i32.add + (i32.load offset=52 + (i32.load + (local.get $0) + ) ) + (i32.const 422) ) - (i32.const 422) ) ) ) diff --git a/test/passes/fannkuch3_manyopts_dwarf.bin.txt b/test/passes/fannkuch3_manyopts_dwarf.bin.txt index 1df0db5063d..caaced4ef9b 100644 --- a/test/passes/fannkuch3_manyopts_dwarf.bin.txt +++ b/test/passes/fannkuch3_manyopts_dwarf.bin.txt @@ -4788,7 +4788,7 @@ file_names[ 4]: ;; code offset: 0x4a (i32.const 0) ) - (block + (then ;; code offset: 0x4f (loop $label$4 ;; code offset: 0x5b @@ -4899,52 +4899,54 @@ file_names[ 4]: ;; code offset: 0x9c (i32.const 1) ) - ;; code offset: 0xa1 - (loop $label$7 - ;; code offset: 0xb2 - (i32.store - ;; code offset: 0xaf - (i32.add - ;; code offset: 0xa3 - (local.get $9) - ;; code offset: 0xae - (i32.shl - ;; code offset: 0xaa - (local.tee $1 - ;; code offset: 0xa9 - (i32.sub - ;; code offset: 0xa5 - (local.get $2) - ;; code offset: 0xa7 - (i32.const 1) + (then + ;; code offset: 0xa1 + (loop $label$7 + ;; code offset: 0xb2 + (i32.store + ;; code offset: 0xaf + (i32.add + ;; code offset: 0xa3 + (local.get $9) + ;; code offset: 0xae + (i32.shl + ;; code offset: 0xaa + (local.tee $1 + ;; code offset: 0xa9 + (i32.sub + ;; code offset: 0xa5 + (local.get $2) + ;; code offset: 0xa7 + (i32.const 1) + ) ) + ;; code offset: 0xac + (i32.const 2) ) - ;; code offset: 0xac + ) + ;; code offset: 0xb0 + (local.get $2) + ) + ;; code offset: 0xba + (local.set $0 + ;; code offset: 0xb9 + (i32.gt_s + ;; code offset: 0xb5 + (local.get $2) + ;; code offset: 0xb7 (i32.const 2) ) ) - ;; code offset: 0xb0 - (local.get $2) - ) - ;; code offset: 0xba - (local.set $0 - ;; code offset: 0xb9 - (i32.gt_s - ;; code offset: 0xb5 - (local.get $2) - ;; code offset: 0xb7 - (i32.const 2) + ;; code offset: 0xbe + (local.set $2 + ;; code offset: 0xbc + (local.get $1) + ) + ;; code offset: 0xc2 + (br_if $label$7 + ;; code offset: 0xc0 + (local.get $0) ) - ) - ;; code offset: 0xbe - (local.set $2 - ;; code offset: 0xbc - (local.get $1) - ) - ;; code offset: 0xc2 - (br_if $label$7 - ;; code offset: 0xc0 - (local.get $0) ) ) ) @@ -5016,7 +5018,7 @@ file_names[ 4]: ;; code offset: 0xf7 (i32.const 3) ) - (block + (then ;; code offset: 0x101 (local.set $1 ;; code offset: 0x100 @@ -5207,7 +5209,7 @@ file_names[ 4]: ;; code offset: 0x186 (i32.const 0) ) - (block + (then ;; code offset: 0x18b (loop $label$14 ;; code offset: 0x1a5 @@ -5419,52 +5421,54 @@ file_names[ 4]: ;; code offset: 0x225 (i32.const 2) ) - ;; code offset: 0x22a - (loop $label$17 - ;; code offset: 0x23b - (i32.store - ;; code offset: 0x238 - (i32.add - ;; code offset: 0x22c - (local.get $9) - ;; code offset: 0x237 - (i32.shl - ;; code offset: 0x233 - (local.tee $1 - ;; code offset: 0x232 - (i32.sub - ;; code offset: 0x22e - (local.get $2) - ;; code offset: 0x230 - (i32.const 1) + (then + ;; code offset: 0x22a + (loop $label$17 + ;; code offset: 0x23b + (i32.store + ;; code offset: 0x238 + (i32.add + ;; code offset: 0x22c + (local.get $9) + ;; code offset: 0x237 + (i32.shl + ;; code offset: 0x233 + (local.tee $1 + ;; code offset: 0x232 + (i32.sub + ;; code offset: 0x22e + (local.get $2) + ;; code offset: 0x230 + (i32.const 1) + ) ) + ;; code offset: 0x235 + (i32.const 2) ) - ;; code offset: 0x235 + ) + ;; code offset: 0x239 + (local.get $2) + ) + ;; code offset: 0x243 + (local.set $0 + ;; code offset: 0x242 + (i32.gt_s + ;; code offset: 0x23e + (local.get $2) + ;; code offset: 0x240 (i32.const 2) ) ) - ;; code offset: 0x239 - (local.get $2) - ) - ;; code offset: 0x243 - (local.set $0 - ;; code offset: 0x242 - (i32.gt_s - ;; code offset: 0x23e - (local.get $2) - ;; code offset: 0x240 - (i32.const 2) + ;; code offset: 0x247 + (local.set $2 + ;; code offset: 0x245 + (local.get $1) + ) + ;; code offset: 0x24b + (br_if $label$17 + ;; code offset: 0x249 + (local.get $0) ) - ) - ;; code offset: 0x247 - (local.set $2 - ;; code offset: 0x245 - (local.get $1) - ) - ;; code offset: 0x24b - (br_if $label$17 - ;; code offset: 0x249 - (local.get $0) ) ) ) @@ -5526,7 +5530,7 @@ file_names[ 4]: ;; code offset: 0x278 (i32.const 3) ) - (block + (then ;; code offset: 0x282 (local.set $1 ;; code offset: 0x281 @@ -5717,7 +5721,7 @@ file_names[ 4]: ;; code offset: 0x307 (i32.const 0) ) - (block + (then ;; code offset: 0x30c (loop $label$24 ;; code offset: 0x326 @@ -5916,23 +5920,25 @@ file_names[ 4]: ;; code offset: 0x3aa (i32.const 2) ) - ;; code offset: 0x3bb - (br_if $label$2 - ;; code offset: 0x3ba - (i32.gt_s - ;; code offset: 0x3b6 - (local.tee $3 - ;; code offset: 0x3b4 - (call $atoi - ;; code offset: 0x3b1 - (i32.load offset=4 - ;; code offset: 0x3af - (local.get $1) + (then + ;; code offset: 0x3bb + (br_if $label$2 + ;; code offset: 0x3ba + (i32.gt_s + ;; code offset: 0x3b6 + (local.tee $3 + ;; code offset: 0x3b4 + (call $atoi + ;; code offset: 0x3b1 + (i32.load offset=4 + ;; code offset: 0x3af + (local.get $1) + ) ) ) + ;; code offset: 0x3b8 + (i32.const 0) ) - ;; code offset: 0x3b8 - (i32.const 0) ) ) ) @@ -5961,7 +5967,7 @@ file_names[ 4]: ;; code offset: 0x3cd (i32.const 1) ) - (block + (then ;; code offset: 0x3d7 (local.set $2 ;; code offset: 0x3d6 @@ -6079,7 +6085,7 @@ file_names[ 4]: ;; code offset: 0x42b (i32.const 0) ) - (block + (then ;; code offset: 0x430 (loop $label$10 ;; code offset: 0x43c @@ -6230,52 +6236,54 @@ file_names[ 4]: ;; code offset: 0x49c (i32.const 1) ) - ;; code offset: 0x4a1 - (loop $label$14 - ;; code offset: 0x4b2 - (i32.store - ;; code offset: 0x4af - (i32.add - ;; code offset: 0x4a3 - (local.get $5) - ;; code offset: 0x4ae - (i32.shl - ;; code offset: 0x4aa - (local.tee $0 - ;; code offset: 0x4a9 - (i32.sub - ;; code offset: 0x4a5 - (local.get $2) - ;; code offset: 0x4a7 - (i32.const 1) + (then + ;; code offset: 0x4a1 + (loop $label$14 + ;; code offset: 0x4b2 + (i32.store + ;; code offset: 0x4af + (i32.add + ;; code offset: 0x4a3 + (local.get $5) + ;; code offset: 0x4ae + (i32.shl + ;; code offset: 0x4aa + (local.tee $0 + ;; code offset: 0x4a9 + (i32.sub + ;; code offset: 0x4a5 + (local.get $2) + ;; code offset: 0x4a7 + (i32.const 1) + ) ) + ;; code offset: 0x4ac + (i32.const 2) ) - ;; code offset: 0x4ac + ) + ;; code offset: 0x4b0 + (local.get $2) + ) + ;; code offset: 0x4ba + (local.set $7 + ;; code offset: 0x4b9 + (i32.gt_s + ;; code offset: 0x4b5 + (local.get $2) + ;; code offset: 0x4b7 (i32.const 2) ) ) - ;; code offset: 0x4b0 - (local.get $2) - ) - ;; code offset: 0x4ba - (local.set $7 - ;; code offset: 0x4b9 - (i32.gt_s - ;; code offset: 0x4b5 - (local.get $2) - ;; code offset: 0x4b7 - (i32.const 2) + ;; code offset: 0x4be + (local.set $2 + ;; code offset: 0x4bc + (local.get $0) + ) + ;; code offset: 0x4c2 + (br_if $label$14 + ;; code offset: 0x4c0 + (local.get $7) ) - ) - ;; code offset: 0x4be - (local.set $2 - ;; code offset: 0x4bc - (local.get $0) - ) - ;; code offset: 0x4c2 - (br_if $label$14 - ;; code offset: 0x4c0 - (local.get $7) ) ) ) @@ -6323,7 +6331,7 @@ file_names[ 4]: ;; code offset: 0x4e3 (i32.const 0) ) - (block + (then ;; code offset: 0x4e8 (loop $label$17 ;; code offset: 0x502 @@ -6439,7 +6447,7 @@ file_names[ 4]: ;; code offset: 0x538 (i32.const 1) ) - (block + (then ;; code offset: 0x547 (br_if $label$15 ;; code offset: 0x546 @@ -6491,52 +6499,54 @@ file_names[ 4]: ;; code offset: 0x55e (i32.const 1) ) - ;; code offset: 0x563 - (loop $label$21 - ;; code offset: 0x574 - (i32.store - ;; code offset: 0x571 - (i32.add - ;; code offset: 0x565 - (local.get $5) - ;; code offset: 0x570 - (i32.shl - ;; code offset: 0x56c - (local.tee $0 - ;; code offset: 0x56b - (i32.sub - ;; code offset: 0x567 - (local.get $2) - ;; code offset: 0x569 - (i32.const 1) + (then + ;; code offset: 0x563 + (loop $label$21 + ;; code offset: 0x574 + (i32.store + ;; code offset: 0x571 + (i32.add + ;; code offset: 0x565 + (local.get $5) + ;; code offset: 0x570 + (i32.shl + ;; code offset: 0x56c + (local.tee $0 + ;; code offset: 0x56b + (i32.sub + ;; code offset: 0x567 + (local.get $2) + ;; code offset: 0x569 + (i32.const 1) + ) ) + ;; code offset: 0x56e + (i32.const 2) ) - ;; code offset: 0x56e + ) + ;; code offset: 0x572 + (local.get $2) + ) + ;; code offset: 0x57c + (local.set $7 + ;; code offset: 0x57b + (i32.gt_s + ;; code offset: 0x577 + (local.get $2) + ;; code offset: 0x579 (i32.const 2) ) ) - ;; code offset: 0x572 - (local.get $2) - ) - ;; code offset: 0x57c - (local.set $7 - ;; code offset: 0x57b - (i32.gt_s - ;; code offset: 0x577 - (local.get $2) - ;; code offset: 0x579 - (i32.const 2) + ;; code offset: 0x580 + (local.set $2 + ;; code offset: 0x57e + (local.get $0) + ) + ;; code offset: 0x584 + (br_if $label$21 + ;; code offset: 0x582 + (local.get $7) ) - ) - ;; code offset: 0x580 - (local.set $2 - ;; code offset: 0x57e - (local.get $0) - ) - ;; code offset: 0x584 - (br_if $label$21 - ;; code offset: 0x582 - (local.get $7) ) ) ) @@ -6584,7 +6594,7 @@ file_names[ 4]: ;; code offset: 0x5a5 (i32.const 0) ) - (block + (then ;; code offset: 0x5aa (loop $label$24 ;; code offset: 0x5c4 @@ -6700,7 +6710,7 @@ file_names[ 4]: ;; code offset: 0x5fa (i32.const 1) ) - (block + (then ;; code offset: 0x609 (br_if $label$22 ;; code offset: 0x608 @@ -6755,55 +6765,57 @@ file_names[ 4]: (if ;; code offset: 0x625 (local.get $4) - ;; code offset: 0x629 - (loop $label$27 - ;; code offset: 0x62f - (local.set $1 - ;; code offset: 0x62d - (call $fannkuch_worker\28void*\29 - ;; code offset: 0x62b - (local.get $4) + (then + ;; code offset: 0x629 + (loop $label$27 + ;; code offset: 0x62f + (local.set $1 + ;; code offset: 0x62d + (call $fannkuch_worker\28void*\29 + ;; code offset: 0x62b + (local.get $4) + ) ) - ) - ;; code offset: 0x636 - (local.set $2 - ;; code offset: 0x633 - (i32.load offset=8 - ;; code offset: 0x631 + ;; code offset: 0x636 + (local.set $2 + ;; code offset: 0x633 + (i32.load offset=8 + ;; code offset: 0x631 + (local.get $4) + ) + ) + ;; code offset: 0x63a + (call $free + ;; code offset: 0x638 (local.get $4) ) - ) - ;; code offset: 0x63a - (call $free - ;; code offset: 0x638 - (local.get $4) - ) - ;; code offset: 0x646 - (local.set $0 - ;; code offset: 0x645 - (select - ;; code offset: 0x63c - (local.get $1) - ;; code offset: 0x63e - (local.get $0) - ;; code offset: 0x644 - (i32.lt_s - ;; code offset: 0x640 - (local.get $0) - ;; code offset: 0x642 + ;; code offset: 0x646 + (local.set $0 + ;; code offset: 0x645 + (select + ;; code offset: 0x63c (local.get $1) + ;; code offset: 0x63e + (local.get $0) + ;; code offset: 0x644 + (i32.lt_s + ;; code offset: 0x640 + (local.get $0) + ;; code offset: 0x642 + (local.get $1) + ) ) ) - ) - ;; code offset: 0x64a - (local.set $4 - ;; code offset: 0x648 - (local.get $2) - ) - ;; code offset: 0x64e - (br_if $label$27 - ;; code offset: 0x64c - (local.get $2) + ;; code offset: 0x64a + (local.set $4 + ;; code offset: 0x648 + (local.get $2) + ) + ;; code offset: 0x64e + (br_if $label$27 + ;; code offset: 0x64c + (local.get $2) + ) ) ) ) diff --git a/test/passes/func-metrics.txt b/test/passes/func-metrics.txt index 8c2812bd2cc..69b89557c32 100644 --- a/test/passes/func-metrics.txt +++ b/test/passes/func-metrics.txt @@ -57,34 +57,48 @@ func: ifs (block $block0 (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) - (drop - (i32.const 6) + (else + (drop + (i32.const 6) + ) ) ) (drop (i32.eq (if (result i32) (i32.const 4) - (i32.const 5) - (i32.const 6) + (then + (i32.const 5) + ) + (else + (i32.const 6) + ) ) (i32.const 177) ) diff --git a/test/passes/func-metrics.wast b/test/passes/func-metrics.wast index e95d819d93f..3b7f79b13a8 100644 --- a/test/passes/func-metrics.wast +++ b/test/passes/func-metrics.wast @@ -16,34 +16,48 @@ (block $block0 (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) - (drop - (i32.const 6) + (else + (drop + (i32.const 6) + ) ) ) (drop (i32.eq (if (result i32) (i32.const 4) - (i32.const 5) - (i32.const 6) + (then + (i32.const 5) + ) + (else + (i32.const 6) + ) ) (i32.const 177) ) diff --git a/test/passes/interesting-pass-mix.txt b/test/passes/interesting-pass-mix.txt index 2c13877db84..ae6252b7710 100644 --- a/test/passes/interesting-pass-mix.txt +++ b/test/passes/interesting-pass-mix.txt @@ -34,23 +34,29 @@ (func $loops (param $0 i32) (if (local.get $0) - (loop $shape$2$continue - (call $trivial) - (br $shape$2$continue) + (then + (loop $shape$2$continue + (call $trivial) + (br $shape$2$continue) + ) ) ) (loop $shape$4$continue (call $trivial) (if (local.get $0) - (br $shape$4$continue) + (then + (br $shape$4$continue) + ) ) ) (loop $shape$6$continue (call $trivial) (if (local.get $0) - (br $shape$6$continue) + (then + (br $shape$6$continue) + ) ) ) ) @@ -64,7 +70,7 @@ (i32.eqz (local.get $0) ) - (block + (then (call $unreachable (i32.const 5) ) @@ -73,14 +79,16 @@ ) (if (local.get $0) - (block + (then (call $unreachable (i32.const 1) ) (unreachable) ) - (call $unreachable - (i32.const 3) + (else + (call $unreachable + (i32.const 3) + ) ) ) ) @@ -104,8 +112,10 @@ (i32.eqz (local.get $0) ) - (call $before-and-after - (i32.const 5) + (then + (call $before-and-after + (i32.const 5) + ) ) ) (call $before-and-after @@ -123,7 +133,9 @@ ) (if (local.get $0) - (br $shape$4$continue) + (then + (br $shape$4$continue) + ) ) ) (call $before-and-after @@ -134,8 +146,10 @@ ) (if (local.get $0) - (call $before-and-after - (i32.const 12) + (then + (call $before-and-after + (i32.const 12) + ) ) ) (call $before-and-after @@ -143,17 +157,23 @@ ) (if (local.get $0) - (call $before-and-after - (i32.const 14) + (then + (call $before-and-after + (i32.const 14) + ) ) - (call $before-and-after - (i32.const 15) + (else + (call $before-and-after + (i32.const 15) + ) ) ) (if (local.get $0) - (call $before-and-after - (i32.const 16) + (then + (call $before-and-after + (i32.const 16) + ) ) ) (call $before-and-after @@ -215,12 +235,18 @@ (block $block$2$break (if (local.get $0) - (call $if-br-wat - (i32.const 1) + (then + (call $if-br-wat + (i32.const 1) + ) ) - (if - (local.get $0) - (br $block$2$break) + (else + (if + (local.get $0) + (then + (br $block$2$break) + ) + ) ) ) (call $if-br-wat diff --git a/test/passes/interesting-pass-mix.wast b/test/passes/interesting-pass-mix.wast index fba9e7c9e2e..c1f9bb8f24c 100644 --- a/test/passes/interesting-pass-mix.wast +++ b/test/passes/interesting-pass-mix.wast @@ -15,23 +15,33 @@ (func $ifs (param $x i32) (result i32) (if (local.get $x) - (if - (local.get $x) - (return (i32.const 2)) - (return (i32.const 3)) + (then + (if + (local.get $x) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 3)) + ) + ) ) ) (if (local.get $x) - (return (i32.const 4)) + (then + (return (i32.const 4)) + ) ) (return (i32.const 5)) ) (func $loops (param $x i32) (if (local.get $x) - (loop $top - (call $trivial) - (br $top) + (then + (loop $top + (call $trivial) + (br $top) + ) ) ) (loop $top2 @@ -40,7 +50,7 @@ ) (loop $top3 (call $trivial) - (if (local.get $x) (br $top3)) + (if (local.get $x) (then (br $top3))) ) ) (func $br-out (param $x i32) @@ -51,16 +61,22 @@ ) (func $unreachable (param $x i32) (if (local.get $x) - (if (local.get $x) - (block - (call $unreachable (i32.const 1)) - (unreachable) - (call $unreachable (i32.const 2)) - ) - (block - (call $unreachable (i32.const 3)) - (return) - (call $unreachable (i32.const 4)) + (then + (if (local.get $x) + (then + (block + (call $unreachable (i32.const 1)) + (unreachable) + (call $unreachable (i32.const 2)) + ) + ) + (else + (block + (call $unreachable (i32.const 3)) + (return) + (call $unreachable (i32.const 4)) + ) + ) ) ) ) @@ -97,16 +113,24 @@ ) (call $before-and-after (i32.const 11)) (if (local.get $x) - (call $before-and-after (i32.const 12)) + (then + (call $before-and-after (i32.const 12)) + ) ) (call $before-and-after (i32.const 13)) (if (local.get $x) - (call $before-and-after (i32.const 14)) - (call $before-and-after (i32.const 15)) + (then + (call $before-and-after (i32.const 14)) + ) + (else + (call $before-and-after (i32.const 15)) + ) ) (if (local.get $x) - (block - (call $before-and-after (i32.const 16)) + (then + (block + (call $before-and-after (i32.const 16)) + ) ) ) (call $before-and-after (i32.const 17)) @@ -148,8 +172,12 @@ ) (func $no-return (if (i32.const 1) - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (drop (i32.const 2)) + ) + (else + (drop (i32.const 3)) + ) ) ) (func $if-br-wat (param $x i32) @@ -159,12 +187,18 @@ (block $label$2 (if (local.get $x) - (call $if-br-wat - (i32.const 1) + (then + (call $if-br-wat + (i32.const 1) + ) ) - (if - (local.get $x) - (br $label$2) ;; waka + (else + (if + (local.get $x) + (then + (br $label$2) ;; waka + ) + ) ) ) (call $if-br-wat diff --git a/test/passes/licm.txt b/test/passes/licm.txt index 3c038207ba2..83edd78c3d2 100644 --- a/test/passes/licm.txt +++ b/test/passes/licm.txt @@ -444,8 +444,10 @@ (func $conditional (if (i32.const 0) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) ) (loop $loop @@ -459,8 +461,10 @@ (loop $loop (if (call $conditional1) - (drop - (i32.const 10) + (then + (drop + (i32.const 10) + ) ) ) (br_if $loop diff --git a/test/passes/licm.wast b/test/passes/licm.wast index c4fbfcd99a0..0ec3632beb7 100644 --- a/test/passes/licm.wast +++ b/test/passes/licm.wast @@ -245,7 +245,9 @@ (func $conditional (loop $loop (if (i32.const 0) - (drop (i32.const 10)) ;; cannot be hoisted - might never be reached + (then + (drop (i32.const 10)) ;; cannot be hoisted - might never be reached + ) ) (br_if $loop (i32.const 1)) ) @@ -253,7 +255,9 @@ (func $conditional1 (result i32) (loop $loop (if (call $conditional1) - (drop (i32.const 10)) ;; cannot be hoisted - might never be reached + (then + (drop (i32.const 10)) ;; cannot be hoisted - might never be reached + ) ;; also anyhow the whole if also cannot, due to the call ) (br_if $loop (i32.const 1)) diff --git a/test/passes/log-execution.txt b/test/passes/log-execution.txt index fdc5332804e..35ca7411ef8 100644 --- a/test/passes/log-execution.txt +++ b/test/passes/log-execution.txt @@ -23,7 +23,9 @@ (block (if (i32.const 0) - (nop) + (then + (nop) + ) ) (block (call $log_execution @@ -51,11 +53,13 @@ ) (if (call $intt) - (loop $y - (call $log_execution - (i32.const 5) + (then + (loop $y + (call $log_execution + (i32.const 5) + ) + (call $loops) ) - (call $loops) ) ) (block diff --git a/test/passes/log-execution.wast b/test/passes/log-execution.wast index f7448408aea..b84d7ac1f40 100644 --- a/test/passes/log-execution.wast +++ b/test/passes/log-execution.wast @@ -7,7 +7,7 @@ (i32.const 10) ) (func $workk - (if (i32.const 0) (nop)) + (if (i32.const 0) (then (nop))) (drop (i32.const 1)) ) (func $loops @@ -16,8 +16,10 @@ (br $x) ) (if (call $intt) - (loop $y - (call $loops) + (then + (loop $y + (call $loops) + ) ) ) (loop diff --git a/test/passes/merge-blocks.txt b/test/passes/merge-blocks.txt index b1037478b54..86d97af4b01 100644 --- a/test/passes/merge-blocks.txt +++ b/test/passes/merge-blocks.txt @@ -49,7 +49,7 @@ (block $x (if (i32.const 100) - (block + (then (drop (i32.const 1) ) @@ -121,7 +121,7 @@ (block $label (if (i32.const 1) - (block + (then (drop (i32.const 2) ) @@ -136,7 +136,7 @@ (block $label (if (br $label) - (block + (then (drop (i32.const 2) ) @@ -151,7 +151,9 @@ (block $label (if (i32.const 1) - (br $label) + (then + (br $label) + ) ) ) ) @@ -159,9 +161,13 @@ (block $label (if (i32.const 1) - (br $label) - (drop - (i32.const 3) + (then + (br $label) + ) + (else + (drop + (i32.const 3) + ) ) ) ) @@ -170,10 +176,14 @@ (block $label (if (i32.const 1) - (drop - (i32.const 3) + (then + (drop + (i32.const 3) + ) + ) + (else + (br $label) ) - (br $label) ) ) ) @@ -181,8 +191,12 @@ (block $label (if (i32.const 1) - (br $label) - (br $label) + (then + (br $label) + ) + (else + (br $label) + ) ) ) ) @@ -190,11 +204,15 @@ (block $label (if (i32.const 1) - (drop - (i32.const 2) + (then + (drop + (i32.const 2) + ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) ) @@ -203,8 +221,12 @@ (block $label (result i32) (if (result i32) (i32.const 1) - (i32.const 2) - (i32.const 3) + (then + (i32.const 2) + ) + (else + (i32.const 3) + ) ) ) ) @@ -217,7 +239,9 @@ (block $label$4 (unreachable) ) - (br $label$3) + (then + (br $label$3) + ) ) ) (unreachable) @@ -229,24 +253,34 @@ (block $label$1 (if (unreachable) - (nop) - (unreachable) + (then + (nop) + ) + (else + (unreachable) + ) ) ) ) (func $propagate-type-if-we-optimize (if (i32.const 1) - (nop) - (block + (then + (nop) + ) + (else (drop (loop $label$3 (result i64) (br_if $label$3 (block $label$4 (result i32) (if (i32.const 0) - (unreachable) - (unreachable) + (then + (unreachable) + ) + (else + (unreachable) + ) ) ) ) diff --git a/test/passes/merge-blocks.wast b/test/passes/merge-blocks.wast index 55996420e8d..749797ce67e 100644 --- a/test/passes/merge-blocks.wast +++ b/test/passes/merge-blocks.wast @@ -44,9 +44,11 @@ (drop (block $x (result i32) (if (i32.const 100) - (block - (drop (br_if $x (i32.const 1) (i32.const 2))) - (nop) + (then + (block + (drop (br_if $x (i32.const 1) (i32.const 2))) + (nop) + ) ) ) (i32.const 0) @@ -113,9 +115,11 @@ (block $label (if (i32.const 1) - (block - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (block + (drop (i32.const 2)) + (drop (i32.const 3)) + ) ) ) ) @@ -124,9 +128,11 @@ (block $label (if (br $label) ;; use outside of arm - (block - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (block + (drop (i32.const 2)) + (drop (i32.const 3)) + ) ) ) ) @@ -135,7 +141,9 @@ (block $label (if (i32.const 1) - (br $label) + (then + (br $label) + ) ) ) ) @@ -143,8 +151,12 @@ (block $label (if (i32.const 1) - (br $label) - (drop (i32.const 3)) + (then + (br $label) + ) + (else + (drop (i32.const 3)) + ) ) ) ) @@ -152,8 +164,12 @@ (block $label (if (i32.const 1) - (drop (i32.const 3)) - (br $label) + (then + (drop (i32.const 3)) + ) + (else + (br $label) + ) ) ) ) @@ -161,8 +177,12 @@ (block $label (if (i32.const 1) - (br $label) - (br $label) + (then + (br $label) + ) + (else + (br $label) + ) ) ) ) @@ -170,8 +190,12 @@ (block $label (if (i32.const 1) - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (drop (i32.const 2)) + ) + (else + (drop (i32.const 3)) + ) ) ) ) @@ -179,8 +203,12 @@ (block $label (result i32) (if (result i32) (i32.const 1) - (i32.const 2) - (i32.const 3) + (then + (i32.const 2) + ) + (else + (i32.const 3) + ) ) ) ) @@ -193,7 +221,9 @@ (block $label$4 (unreachable) ) - (br $label$3) + (then + (br $label$3) + ) ) ) (unreachable) @@ -205,31 +235,43 @@ (block $label$1 (if (unreachable) ;; unreachable condition - (nop) - (unreachable) + (then + (nop) + ) + (else + (unreachable) + ) ) ) ) (func $propagate-type-if-we-optimize (if (i32.const 1) - (nop) - (block - (drop - (loop $label$3 (result i64) - (br_if $label$3 - (block $label$4 (result i32) - (if - (i32.const 0) - (unreachable) - (unreachable) + (then + (nop) + ) + (else + (block + (drop + (loop $label$3 (result i64) + (br_if $label$3 + (block $label$4 (result i32) + (if + (i32.const 0) + (then + (unreachable) + ) + (else + (unreachable) + ) + ) ) ) + (i64.const -9) ) - (i64.const -9) ) + (unreachable) ) - (unreachable) ) ) ) diff --git a/test/passes/merge-locals_all-features.txt b/test/passes/merge-locals_all-features.txt index e9fd7acb021..18b552e5d81 100644 --- a/test/passes/merge-locals_all-features.txt +++ b/test/passes/merge-locals_all-features.txt @@ -11,8 +11,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $x) @@ -23,8 +27,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $x) @@ -35,8 +43,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (drop @@ -50,8 +62,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (drop @@ -68,17 +84,25 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (if (i32.const 300) - (local.set $y - (i32.const 400) + (then + (local.set $y + (i32.const 400) + ) ) - (drop - (local.get $x) + (else + (drop + (local.get $x) + ) ) ) (i32.const 500) @@ -89,17 +113,25 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 200) + (then + (i32.const 100) + ) + (else + (i32.const 200) + ) ) ) (if (i32.const 300) - (local.set $y - (i32.const 400) + (then + (local.set $y + (i32.const 400) + ) ) - (drop - (local.get $y) + (else + (drop + (local.get $y) + ) ) ) (local.get $y) @@ -110,8 +142,12 @@ (local.tee $x (local.get $x) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $y) @@ -124,8 +160,12 @@ (local.get $x) ) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $y) @@ -149,8 +189,10 @@ ) (if (local.get $var$1) - (local.set $var$2 - (i32.const 1) + (then + (local.set $var$2 + (i32.const 1) + ) ) ) (drop @@ -163,8 +205,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $y) + (then + (i32.const 100) + ) + (else + (local.get $y) + ) ) ) (drop @@ -172,8 +218,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -186,8 +234,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) ) @@ -197,8 +249,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.set $y @@ -214,8 +270,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $y) + (then + (i32.const 100) + ) + (else + (local.get $y) + ) ) ) (local.set $x @@ -226,8 +286,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -240,8 +302,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (local.set $x @@ -252,8 +318,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -266,14 +334,20 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (if (i32.const 1) - (local.set $x - (i32.const 300) + (then + (local.set $x + (i32.const 300) + ) ) ) (drop @@ -281,8 +355,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -295,14 +371,20 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (if (i32.const 1) - (local.set $x - (i32.const 300) + (then + (local.set $x + (i32.const 300) + ) ) ) (drop @@ -310,8 +392,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -324,20 +408,28 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (if (i32.const 1) - (drop - (local.get $x) + (then + (drop + (local.get $x) + ) ) - (block + (else (if (i32.const 1) - (local.set $x - (i32.const 300) + (then + (local.set $x + (i32.const 300) + ) ) ) (drop @@ -347,8 +439,10 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 200) + (then + (local.set $y + (i32.const 200) + ) ) ) (drop @@ -388,12 +482,14 @@ (local.get $var$0) ) ) - (i32.const 0) - (block (result i32) + (then + (i32.const 0) + ) + (else (local.set $var$3 (if (result i32) (i32.const 0) - (block (result i32) + (then (block $label$7 (block $label$8 (local.set $var$0 @@ -403,13 +499,15 @@ ) (local.get $var$3) ) - (block (result i32) + (else (if (i32.eqz (global.get $global$0) ) - (return - (i64.const 137438953472) + (then + (return + (i64.const 137438953472) + ) ) ) (global.set $global$0 @@ -443,8 +541,10 @@ (loop $label$1 (if (i32.const 1) - (drop - (local.get $result) + (then + (drop + (local.get $result) + ) ) ) (local.set $result diff --git a/test/passes/merge-locals_all-features.wast b/test/passes/merge-locals_all-features.wast index 1b73c9a95a8..b1d3aa9b7cc 100644 --- a/test/passes/merge-locals_all-features.wast +++ b/test/passes/merge-locals_all-features.wast @@ -6,8 +6,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $y) ;; turn this into $x @@ -18,8 +22,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $x) @@ -30,8 +38,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (drop (local.get $y)) ;; turn this into $x @@ -43,8 +55,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (drop (local.get $y)) ;; turn this into $x @@ -57,14 +73,22 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (if (i32.const 300) - (local.set $y (i32.const 400)) - (drop (local.get $y)) ;; turn this into $x + (then + (local.set $y (i32.const 400)) + ) + (else + (drop (local.get $y)) ;; turn this into $x + ) ) (i32.const 500) ) @@ -74,14 +98,22 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 200) + (then + (i32.const 100) + ) + (else + (i32.const 200) + ) ) ) (if (i32.const 300) - (local.set $y (i32.const 400)) - (drop (local.get $y)) ;; can turn this into $x, but another exists we can't, so do nothing + (then + (local.set $y (i32.const 400)) + ) + (else + (drop (local.get $y)) ;; can turn this into $x, but another exists we can't, so do nothing + ) ) (local.get $y) ;; but not this one! ) @@ -91,8 +123,12 @@ (local.tee $x (local.get $x) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $y) ;; turn this into $x @@ -105,8 +141,12 @@ (local.get $x) ) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (local.get $y) ;; turn this into $x @@ -129,8 +169,10 @@ (local.get $var$1) ) (if (local.get $var$1) - (local.set $var$2 ;; conditional overwrite 2 - (i32.const 1) + (then + (local.set $var$2 ;; conditional overwrite 2 + (i32.const 1) + ) ) ) (drop @@ -143,13 +185,19 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (drop (local.get $x)) ;; (read lower down first) but the reverse can work! (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -159,8 +207,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) ;; don't change to $y, as its lifetime ended. leave it ended + (then + (i32.const 100) + ) + (else + (local.get $x) ;; don't change to $y, as its lifetime ended. leave it ended + ) ) ) ) @@ -170,8 +222,12 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) ;; don't change to $y, as its lifetime ended. leave it ended + (then + (i32.const 100) + ) + (else + (local.get $x) ;; don't change to $y, as its lifetime ended. leave it ended + ) ) ) (local.set $y (i32.const 200)) @@ -183,14 +239,20 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) ;; can optimize this ($y lives on) + (then + (i32.const 100) + ) + (else + (local.get $x) ;; can optimize this ($y lives on) + ) ) ) (local.set $x (i32.const 300)) ;; force an undo (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -200,14 +262,20 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (local.set $x (i32.const 300)) ;; force an undo (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -217,16 +285,24 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (if (i32.const 1) - (local.set $x (i32.const 300)) ;; force an undo + (then + (local.set $x (i32.const 300)) ;; force an undo + ) ) (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -236,16 +312,24 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (local.get $x) + (then + (i32.const 100) + ) + (else + (local.get $x) + ) ) ) (if (i32.const 1) - (local.set $x (i32.const 300)) ;; force an undo + (then + (local.set $x (i32.const 300)) ;; force an undo + ) ) (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -255,21 +339,33 @@ (local.tee $x (local.get $y) ) - (i32.const 100) - (i32.const 150) + (then + (i32.const 100) + ) + (else + (i32.const 150) + ) ) ) (if (i32.const 1) - (drop (local.get $x)) - (block - (if (i32.const 1) - (local.set $x (i32.const 300)) ;; force an undo + (then + (drop (local.get $x)) + ) + (else + (block + (if (i32.const 1) + (then + (local.set $x (i32.const 300)) ;; force an undo + ) + ) + (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work ) - (drop (local.get $x)) ;; (read lower down first) but the reverse can almost work ) ) (if (i32.const 1) - (local.set $y (i32.const 200)) + (then + (local.set $y (i32.const 200)) + ) ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) @@ -306,48 +402,58 @@ (local.get $var$0) ) ) - (i32.const 0) - (block (result i32) - (local.set $var$3 - (if (result i32) - (i32.const 0) - (block (result i32) - (block $label$7 - (block $label$8 - (local.set $var$0 - (i32.const 34738786) + (then + (i32.const 0) + ) + (else + (block (result i32) + (local.set $var$3 + (if (result i32) + (i32.const 0) + (then + (block (result i32) + (block $label$7 + (block $label$8 + (local.set $var$0 + (i32.const 34738786) + ) + ) ) - ) - ) - (local.get $var$3) - ) - (block (result i32) - (if - (i32.eqz - (global.get $global$0) - ) - (return - (i64.const 137438953472) - ) - ) - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) - ) - ) - (br_if $label$1 - (i32.eqz (local.get $var$3) ) ) - (return - (i64.const 44125) + (else + (block (result i32) + (if + (i32.eqz + (global.get $global$0) + ) + (then + (return + (i64.const 137438953472) + ) + ) + ) + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) + ) + (br_if $label$1 + (i32.eqz + (local.get $var$3) + ) + ) + (return + (i64.const 44125) + ) + ) ) ) ) + (i32.const -129) ) - (i32.const -129) ) ) ) @@ -361,8 +467,10 @@ (loop $label$1 (if (i32.const 1) - (drop - (local.get $result) + (then + (drop + (local.get $result) + ) ) ) (local.set $result ;; vanishes diff --git a/test/passes/metrics_all-features.txt b/test/passes/metrics_all-features.txt index e40a35441b1..2fcf292573d 100644 --- a/test/passes/metrics_all-features.txt +++ b/test/passes/metrics_all-features.txt @@ -31,34 +31,48 @@ total (block $block0 (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) - (drop - (i32.const 6) + (else + (drop + (i32.const 6) + ) ) ) (drop (i32.eq (if (result i32) (i32.const 4) - (i32.const 5) - (i32.const 6) + (then + (i32.const 5) + ) + (else + (i32.const 6) + ) ) (i32.const 177) ) diff --git a/test/passes/metrics_all-features.wast b/test/passes/metrics_all-features.wast index 68c13b9c22c..fe4a70ce22c 100644 --- a/test/passes/metrics_all-features.wast +++ b/test/passes/metrics_all-features.wast @@ -12,34 +12,48 @@ (block $block0 (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) ) (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 2) + (else + (drop + (i32.const 2) + ) ) ) (if (i32.const 4) - (drop - (i32.const 5) + (then + (drop + (i32.const 5) + ) ) - (drop - (i32.const 6) + (else + (drop + (i32.const 6) + ) ) ) (drop (i32.eq (if (result i32) (i32.const 4) - (i32.const 5) - (i32.const 6) + (then + (i32.const 5) + ) + (else + (i32.const 6) + ) ) (i32.const 177) ) diff --git a/test/passes/optimize-added-constants-propagate_low-memory-unused.txt b/test/passes/optimize-added-constants-propagate_low-memory-unused.txt index 2c8a9f0c772..98169960325 100644 --- a/test/passes/optimize-added-constants-propagate_low-memory-unused.txt +++ b/test/passes/optimize-added-constants-propagate_low-memory-unused.txt @@ -271,8 +271,10 @@ (local $3 i32) (if (local.get $z) - (local.set $y - (i32.const -1) + (then + (local.set $y + (i32.const -1) + ) ) ) (block @@ -323,10 +325,12 @@ ) (if (i32.const 1) - (local.set $x - (i32.add - (i32.const 2) - (local.get $y) + (then + (local.set $x + (i32.add + (i32.const 2) + (local.get $y) + ) ) ) ) diff --git a/test/passes/optimize-added-constants-propagate_low-memory-unused.wast b/test/passes/optimize-added-constants-propagate_low-memory-unused.wast index d62d487d223..dbff37fbc7d 100644 --- a/test/passes/optimize-added-constants-propagate_low-memory-unused.wast +++ b/test/passes/optimize-added-constants-propagate_low-memory-unused.wast @@ -303,7 +303,9 @@ (local $x i32) (local $y i32) (if (local.get $z) - (local.set $y (i32.const -1)) ;; y is not ssa + (then + (local.set $y (i32.const -1)) ;; y is not ssa + ) ) (local.set $x (i32.add @@ -345,10 +347,12 @@ ) ) (if (i32.const 1) - (local.set $x ;; x is not ssa - (i32.add - (i32.const 2) - (local.get $y) + (then + (local.set $x ;; x is not ssa + (i32.add + (i32.const 2) + (local.get $y) + ) ) ) ) diff --git a/test/passes/optimize-added-constants_low-memory-unused.txt b/test/passes/optimize-added-constants_low-memory-unused.txt index c700fa741e9..9baf092af87 100644 --- a/test/passes/optimize-added-constants_low-memory-unused.txt +++ b/test/passes/optimize-added-constants_low-memory-unused.txt @@ -290,8 +290,10 @@ (local $y i32) (if (local.get $z) - (local.set $y - (i32.const -1) + (then + (local.set $y + (i32.const -1) + ) ) ) (local.set $x diff --git a/test/passes/optimize-added-constants_low-memory-unused.wast b/test/passes/optimize-added-constants_low-memory-unused.wast index ac7d77fc42c..4b40a0f85d5 100644 --- a/test/passes/optimize-added-constants_low-memory-unused.wast +++ b/test/passes/optimize-added-constants_low-memory-unused.wast @@ -303,7 +303,9 @@ (local $x i32) (local $y i32) (if (local.get $z) - (local.set $y (i32.const -1)) + (then + (local.set $y (i32.const -1)) + ) ) (local.set $x (i32.add diff --git a/test/passes/precompute-propagate_all-features.txt b/test/passes/precompute-propagate_all-features.txt index 6fb67825a8d..380c7a88929 100644 --- a/test/passes/precompute-propagate_all-features.txt +++ b/test/passes/precompute-propagate_all-features.txt @@ -19,8 +19,10 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 10) + (then + (local.set $x + (i32.const 10) + ) ) ) (call $basic @@ -34,11 +36,15 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 10) + (then + (local.set $x + (i32.const 10) + ) ) - (local.set $x - (i32.const 10) + (else + (local.set $x + (i32.const 10) + ) ) ) (call $basic @@ -49,11 +55,15 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 10) + (then + (local.set $x + (i32.const 10) + ) ) - (local.set $x - (i32.const 20) + (else + (local.set $x + (i32.const 20) + ) ) ) (call $basic @@ -67,11 +77,15 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 10) + (then + (local.set $x + (i32.const 10) + ) ) - (local.set $x - (local.get $p) + (else + (local.set $x + (local.get $p) + ) ) ) (call $basic @@ -85,8 +99,10 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 0) + (then + (local.set $x + (i32.const 0) + ) ) ) (call $basic @@ -129,11 +145,15 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 11) + (then + (local.set $y + (i32.const 11) + ) ) - (local.set $y - (i32.const 11) + (else + (local.set $y + (i32.const 11) + ) ) ) (local.set $y @@ -149,11 +169,15 @@ ) (if (i32.const 1) - (local.set $y - (i32.const 12) + (then + (local.set $y + (i32.const 12) + ) ) - (local.set $y - (i32.const 11) + (else + (local.set $y + (i32.const 11) + ) ) ) (local.set $y @@ -242,8 +266,10 @@ (nop) (if (local.get $3) - (local.set $2 - (i32.const 0) + (then + (local.set $2 + (i32.const 0) + ) ) ) (local.get $2) diff --git a/test/passes/precompute-propagate_all-features.wast b/test/passes/precompute-propagate_all-features.wast index 17a20417d74..0460ad34ab2 100644 --- a/test/passes/precompute-propagate_all-features.wast +++ b/test/passes/precompute-propagate_all-features.wast @@ -8,38 +8,54 @@ (func $split (param $p i32) (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 10)) + (then + (local.set $x (i32.const 10)) + ) ) (call $basic (i32.add (local.get $x) (local.get $x))) ) (func $split-but-join (param $p i32) (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 10)) - (local.set $x (i32.const 10)) + (then + (local.set $x (i32.const 10)) + ) + (else + (local.set $x (i32.const 10)) + ) ) (call $basic (i32.add (local.get $x) (local.get $x))) ) (func $split-but-join-different (param $p i32) (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 10)) - (local.set $x (i32.const 20)) + (then + (local.set $x (i32.const 10)) + ) + (else + (local.set $x (i32.const 20)) + ) ) (call $basic (i32.add (local.get $x) (local.get $x))) ) (func $split-but-join-different-b (param $p i32) (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 10)) - (local.set $x (local.get $p)) + (then + (local.set $x (i32.const 10)) + ) + (else + (local.set $x (local.get $p)) + ) ) (call $basic (i32.add (local.get $x) (local.get $x))) ) (func $split-but-join-init0 (param $p i32) (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 0)) + (then + (local.set $x (i32.const 0)) + ) ) (call $basic (i32.add (local.get $x) (local.get $x))) ) @@ -62,8 +78,12 @@ (local $y i32) (local.set $x (i32.const 10)) (if (i32.const 1) - (local.set $y (i32.const 11)) - (local.set $y (i32.add (local.get $x) (i32.const 1))) + (then + (local.set $y (i32.const 11)) + ) + (else + (local.set $y (i32.add (local.get $x) (i32.const 1))) + ) ) (local.set $y (i32.add (local.get $x) (local.get $y))) (local.get $y) @@ -73,8 +93,12 @@ (local $y i32) (local.set $x (i32.const 10)) (if (i32.const 1) - (local.set $y (i32.const 12)) ;; 12, not 11... - (local.set $y (i32.add (local.get $x) (i32.const 1))) + (then + (local.set $y (i32.const 12)) ;; 12, not 11... + ) + (else + (local.set $y (i32.add (local.get $x) (i32.const 1))) + ) ) (local.set $y (i32.add (local.get $x) (local.get $y))) (local.get $y) @@ -83,8 +107,8 @@ (local $x i32) (local $y i32) (loop $loop ;; we look like we depend on the other, but we don't actually - (local.set $x (if (result i32) (i32.const 1) (i32.const 0) (local.get $y))) - (local.set $y (if (result i32) (i32.const 1) (i32.const 0) (local.get $x))) + (local.set $x (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $y)))) + (local.set $y (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $x)))) (br $loop) ) ) @@ -92,8 +116,8 @@ (local $x i32) (local $y i32) (loop $loop ;; we look like we depend on the other, but we don't actually - (local.set $x (if (result i32) (i32.const 1) (i32.const 0) (local.get $y))) - (local.set $y (if (result i32) (i32.const 1) (i32.const 0) (local.get $x))) + (local.set $x (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $y)))) + (local.set $y (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $x)))) (call $deadloop2 (local.get $x)) (call $deadloop2 (local.get $y)) (br $loop) @@ -103,8 +127,8 @@ (local $x i32) (local $y i32) (loop $loop ;; we look like we depend on the other, but we don't actually - (local.set $x (if (result i32) (i32.const 1) (i32.const 0) (local.get $x))) - (local.set $y (if (result i32) (i32.const 1) (i32.const 0) (local.get $y))) + (local.set $x (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $x)))) + (local.set $y (if (result i32) (i32.const 1) (then (i32.const 0) )(else (local.get $y)))) (call $deadloop2 (local.get $x)) (call $deadloop2 (local.get $y)) (br $loop) @@ -147,14 +171,18 @@ ;; if lower down, but we do not do an additional cycle of ;; this pass automatically as such things are fairly rare, ;; so that opportunity remains unoptimized in this test. - (local.set $3 ;; this set is completely removed, allowing later opts - (i32.const 24) + (then + (local.set $3 ;; this set is completely removed, allowing later opts + (i32.const 24) + ) ) ) (if (local.get $3) - (local.set $2 - (i32.const 0) + (then + (local.set $2 + (i32.const 0) + ) ) ) (local.get $2) diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt index affa325310d..3f5908ef053 100644 --- a/test/passes/precompute_all-features.txt +++ b/test/passes/precompute_all-features.txt @@ -96,14 +96,18 @@ (func $ret (type $1) (result i32) (if (call $ret) - (return - (i32.const 0) + (then + (return + (i32.const 0) + ) ) ) (if (call $ret) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (i32.const 1) @@ -111,7 +115,9 @@ (func $noret (type $0) (if (call $ret) - (return) + (then + (return) + ) ) ) (func $refinalize-br-condition-unreachable (type $0) @@ -144,21 +150,25 @@ (i32.const 1919623207) (if (result i32) (i32.const 1) - (block $label$2 - (drop - (i64.and - (i64.trunc_f32_u - (f32.const 70847791997969805621592064) + (then + (block $label$2 + (drop + (i64.and + (i64.trunc_f32_u + (f32.const 70847791997969805621592064) + ) + (i64.const 729618461987467893) ) - (i64.const 729618461987467893) ) - ) - (br $label$0 - (f64.const 6.134856208230095e-154) + (br $label$0 + (f64.const 6.134856208230095e-154) + ) ) ) - (i32.load offset=3 align=2 - (i32.const 169901344) + (else + (i32.load offset=3 align=2 + (i32.const 169901344) + ) ) ) ) diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast index 45000153353..633787fad48 100644 --- a/test/passes/precompute_all-features.wast +++ b/test/passes/precompute_all-features.wast @@ -192,16 +192,22 @@ ) (func $ret (result i32) (if (call $ret) - (return (i32.const 0)) + (then + (return (i32.const 0)) + ) ) (if (call $ret) - (return (return (i32.const 1))) + (then + (return (return (i32.const 1))) + ) ) (i32.const 1) ) (func $noret (if (call $ret) - (return) + (then + (return) + ) ) ) (func $refinalize-br-condition-unreachable @@ -234,33 +240,37 @@ (i32.const 1919623207) (if (result i32) (i32.const 1) - (block $label$2 (result i32) - (drop - (i64.and - (i64.trunc_f32_u - (f32.const 70847791997969805621592064) + (then + (block $label$2 (result i32) + (drop + (i64.and + (i64.trunc_f32_u + (f32.const 70847791997969805621592064) + ) + (i64.const 729618461987467893) ) - (i64.const 729618461987467893) ) - ) - (br_if $label$2 - (i32.const 2049535349) - (f32.eq - (f32.demote_f64 - (f64.mul - (br_if $label$0 ;; this br is optimized, and br *and* values reused - (f64.const 6.134856208230095e-154) - (i32.const 690910817) + (br_if $label$2 + (i32.const 2049535349) + (f32.eq + (f32.demote_f64 + (f64.mul + (br_if $label$0 ;; this br is optimized, and br *and* values reused + (f64.const 6.134856208230095e-154) + (i32.const 690910817) + ) + (f64.const 1.515470884183969e-152) ) - (f64.const 1.515470884183969e-152) ) + (f32.const 66524025679377434935296) ) - (f32.const 66524025679377434935296) ) ) ) - (i32.load offset=3 align=2 - (i32.const 169901344) + (else + (i32.load offset=3 align=2 + (i32.const 169901344) + ) ) ) ) diff --git a/test/passes/print-call-graph.txt b/test/passes/print-call-graph.txt index 42a640aa38c..b6ec339b79e 100644 --- a/test/passes/print-call-graph.txt +++ b/test/passes/print-call-graph.txt @@ -225,7 +225,7 @@ digraph call { (i32.eqz (global.get $__THREW__) ) - (block + (then (global.set $__THREW__ (local.get $0) ) @@ -404,7 +404,7 @@ digraph call { (i32.load (i32.const 1140) ) - (block (result i32) + (then (call $_pthread_cleanup_push (i32.const 1) (local.get $0) @@ -436,7 +436,7 @@ digraph call { ) (local.get $3) ) - (block (result i32) + (else (i32.store (local.get $8) (i32.load @@ -484,7 +484,7 @@ digraph call { ) ) ) - (block (result i32) + (then (i32.store (local.get $6) (local.tee $3 @@ -519,34 +519,36 @@ digraph call { (local.get $1) ) ) - (if (result i32) - (i32.eq - (local.get $5) - (i32.const 2) - ) - (block (result i32) - (i32.store - (local.get $6) - (i32.add - (i32.load - (local.get $6) + (else + (if (result i32) + (i32.eq + (local.get $5) + (i32.const 2) + ) + (then + (i32.store + (local.get $6) + (i32.add + (i32.load + (local.get $6) + ) + (local.get $4) ) - (local.get $4) ) + (local.set $3 + (local.get $1) + ) + (local.set $5 + (i32.const 2) + ) + (local.get $12) ) - (local.set $3 - (local.get $1) - ) - (local.set $5 - (i32.const 2) - ) - (local.get $12) - ) - (block (result i32) - (local.set $3 - (local.get $1) + (else + (local.set $3 + (local.get $1) + ) + (local.get $12) ) - (local.get $12) ) ) ) @@ -693,15 +695,17 @@ digraph call { ) (i32.const 0) ) - (block (result i32) + (then (i32.store (local.get $0) (i32.const -1) ) (i32.const -1) ) - (i32.load - (local.get $0) + (else + (i32.load + (local.get $0) + ) ) ) ) @@ -716,7 +720,7 @@ digraph call { (local.get $0) (i32.const -4096) ) - (block (result i32) + (then (i32.store (call $___errno_location) (i32.sub @@ -726,7 +730,9 @@ digraph call { ) (i32.const -1) ) - (local.get $0) + (else + (local.get $0) + ) ) ) (func $___errno_location (result i32) @@ -734,10 +740,14 @@ digraph call { (i32.load (i32.const 1140) ) - (i32.load offset=64 - (call $_pthread_self) + (then + (i32.load offset=64 + (call $_pthread_self) + ) + ) + (else + (i32.const 1184) ) - (i32.const 1184) ) ) (func $_cleanup_387 (param $0 i32) @@ -747,8 +757,10 @@ digraph call { (local.get $0) ) ) - (call $_free - (local.get $0) + (then + (call $_free + (local.get $0) + ) ) ) ) @@ -787,7 +799,7 @@ digraph call { (i32.const 64) ) ) - (block + (then (i32.store (local.get $3) (i32.load offset=60 @@ -807,9 +819,11 @@ digraph call { (i32.const 54) (local.get $3) ) - (i32.store8 offset=75 - (local.get $0) - (i32.const -1) + (then + (i32.store8 offset=75 + (local.get $0) + (i32.const -1) + ) ) ) ) @@ -832,7 +846,7 @@ digraph call { (block $do-once (result i32) (if (result i32) (local.get $0) - (block (result i32) + (then (if (i32.le_s (i32.load offset=76 @@ -840,9 +854,11 @@ digraph call { ) (i32.const -1) ) - (br $do-once - (call $___fflush_unlocked - (local.get $0) + (then + (br $do-once + (call $___fflush_unlocked + (local.get $0) + ) ) ) ) @@ -860,8 +876,10 @@ digraph call { ) (if (result i32) (local.get $2) - (local.get $1) - (block (result i32) + (then + (local.get $1) + ) + (else (call $_free (local.get $0) ) @@ -869,18 +887,22 @@ digraph call { ) ) ) - (block (result i32) + (else (local.set $0 (if (result i32) (i32.load (i32.const 1136) ) - (call $_fflush - (i32.load - (i32.const 1136) + (then + (call $_fflush + (i32.load + (i32.const 1136) + ) ) ) - (i32.const 0) + (else + (i32.const 0) + ) ) ) (call $___lock @@ -892,50 +914,62 @@ digraph call { (i32.const 1164) ) ) - (loop $while-in - (local.set $2 - (if (result i32) - (i32.gt_s - (i32.load offset=76 - (local.get $1) + (then + (loop $while-in + (local.set $2 + (if (result i32) + (i32.gt_s + (i32.load offset=76 + (local.get $1) + ) + (i32.const -1) + ) + (then + (call $_malloc + (local.get $1) + ) + ) + (else + (i32.const 0) ) - (i32.const -1) - ) - (call $_malloc - (local.get $1) ) - (i32.const 0) ) - ) - (local.set $0 - (if (result i32) - (i32.gt_u - (i32.load offset=20 - (local.get $1) + (local.set $0 + (if (result i32) + (i32.gt_u + (i32.load offset=20 + (local.get $1) + ) + (i32.load offset=28 + (local.get $1) + ) ) - (i32.load offset=28 - (local.get $1) + (then + (i32.or + (call $___fflush_unlocked + (local.get $1) + ) + (local.get $0) + ) + ) + (else + (local.get $0) ) ) - (i32.or - (call $___fflush_unlocked + ) + (if + (local.get $2) + (then + (call $_free (local.get $1) ) - (local.get $0) ) - (local.get $0) - ) - ) - (if - (local.get $2) - (call $_free - (local.get $1) ) - ) - (br_if $while-in - (local.tee $1 - (i32.load offset=56 - (local.get $1) + (br_if $while-in + (local.tee $1 + (i32.load offset=56 + (local.get $1) + ) ) ) ) @@ -1026,22 +1060,24 @@ digraph call { ) ) ) - (drop - (call_indirect (type $FUNCSIG$iiii) - (local.get $0) - (i32.sub - (local.get $4) - (local.get $6) - ) - (i32.const 1) - (i32.add - (i32.and - (i32.load offset=40 - (local.get $0) + (then + (drop + (call_indirect (type $FUNCSIG$iiii) + (local.get $0) + (i32.sub + (local.get $4) + (local.get $6) + ) + (i32.const 1) + (i32.add + (i32.and + (i32.load offset=40 + (local.get $0) + ) + (i32.const 3) ) - (i32.const 3) + (i32.const 2) ) - (i32.const 2) ) ) ) @@ -1091,7 +1127,7 @@ digraph call { (local.tee $0 (call $__ZSt15get_new_handlerv) ) - (block + (then (call_indirect (type $FUNCSIG$v) (i32.add (i32.and @@ -1103,8 +1139,10 @@ digraph call { ) (br $while-in) ) - (local.set $0 - (i32.const 0) + (else + (local.set $0 + (i32.const 0) + ) ) ) ) @@ -1145,7 +1183,7 @@ digraph call { (local.get $2) (i32.const 20) ) - (block + (then (local.set $5 (i32.or (i32.or @@ -1185,7 +1223,7 @@ digraph call { (i32.const 3) ) ) - (block + (then (local.set $3 (i32.sub (i32.add @@ -1201,7 +1239,7 @@ digraph call { (local.get $0) (local.get $3) ) - (block + (then (i32.store8 (local.get $0) (local.get $1) @@ -1224,7 +1262,7 @@ digraph call { (local.get $0) (local.get $6) ) - (block + (then (i32.store (local.get $0) (local.get $5) @@ -1247,7 +1285,7 @@ digraph call { (local.get $0) (local.get $4) ) - (block + (then (i32.store8 (local.get $0) (local.get $1) @@ -1274,11 +1312,13 @@ digraph call { (local.get $2) (i32.const 4096) ) - (return - (call $_emscripten_memcpy_big - (local.get $0) - (local.get $1) - (local.get $2) + (then + (return + (call $_emscripten_memcpy_big + (local.get $0) + (local.get $1) + (local.get $2) + ) ) ) ) @@ -1296,7 +1336,7 @@ digraph call { (i32.const 3) ) ) - (block + (then (loop $while-in (block $while-out (br_if $while-out @@ -1311,8 +1351,10 @@ digraph call { (i32.eqz (local.get $2) ) - (return - (local.get $3) + (then + (return + (local.get $3) + ) ) ) (i32.store8 @@ -1348,7 +1390,7 @@ digraph call { (local.get $2) (i32.const 4) ) - (block + (then (i32.store (local.get $0) (i32.load @@ -1385,7 +1427,7 @@ digraph call { (local.get $2) (i32.const 0) ) - (block + (then (i32.store8 (local.get $0) (i32.load8_s diff --git a/test/passes/print-call-graph.wast b/test/passes/print-call-graph.wast index b1bb6001143..9d6371b4bf3 100644 --- a/test/passes/print-call-graph.wast +++ b/test/passes/print-call-graph.wast @@ -110,12 +110,14 @@ (i32.eqz (global.get $__THREW__) ) - (block - (global.set $__THREW__ - (local.get $0) - ) - (global.set $threwValue - (local.get $1) + (then + (block + (global.set $__THREW__ + (local.get $0) + ) + (global.set $threwValue + (local.get $1) + ) ) ) ) @@ -289,57 +291,61 @@ (i32.load (i32.const 1140) ) - (block (result i32) - (call $_pthread_cleanup_push - (i32.const 1) - (local.get $0) - ) - (i32.store - (local.get $9) - (i32.load - (local.get $13) + (then + (block (result i32) + (call $_pthread_cleanup_push + (i32.const 1) + (local.get $0) ) - ) - (i32.store offset=4 - (local.get $9) - (local.get $1) - ) - (i32.store offset=8 - (local.get $9) - (local.get $5) - ) - (local.set $3 - (call $___syscall_ret - (call $___syscall146 - (i32.const 146) - (local.get $9) + (i32.store + (local.get $9) + (i32.load + (local.get $13) ) ) + (i32.store offset=4 + (local.get $9) + (local.get $1) + ) + (i32.store offset=8 + (local.get $9) + (local.get $5) + ) + (local.set $3 + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (local.get $9) + ) + ) + ) + (call $_pthread_cleanup_pop + (i32.const 0) + ) + (local.get $3) ) - (call $_pthread_cleanup_pop - (i32.const 0) - ) - (local.get $3) ) - (block (result i32) - (i32.store - (local.get $8) - (i32.load - (local.get $13) + (else + (block (result i32) + (i32.store + (local.get $8) + (i32.load + (local.get $13) + ) ) - ) - (i32.store offset=4 - (local.get $8) - (local.get $1) - ) - (i32.store offset=8 - (local.get $8) - (local.get $5) - ) - (call $___syscall_ret - (call $___syscall146 - (i32.const 146) + (i32.store offset=4 + (local.get $8) + (local.get $1) + ) + (i32.store offset=8 (local.get $8) + (local.get $5) + ) + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (local.get $8) + ) ) ) ) @@ -369,69 +375,77 @@ ) ) ) - (block (result i32) - (i32.store - (local.get $6) - (local.tee $3 - (i32.load - (local.get $14) - ) - ) - ) - (i32.store - (local.get $10) - (local.get $3) - ) - (local.set $4 - (i32.sub - (local.get $4) - (local.get $12) - ) - ) - (local.set $3 - (i32.add - (local.get $1) - (i32.const 8) - ) - ) - (local.set $5 - (i32.add - (local.get $5) - (i32.const -1) - ) - ) - (i32.load offset=12 - (local.get $1) - ) - ) - (if (result i32) - (i32.eq - (local.get $5) - (i32.const 2) - ) + (then (block (result i32) (i32.store (local.get $6) - (i32.add + (local.tee $3 (i32.load - (local.get $6) + (local.get $14) ) + ) + ) + (i32.store + (local.get $10) + (local.get $3) + ) + (local.set $4 + (i32.sub (local.get $4) + (local.get $12) ) ) (local.set $3 - (local.get $1) + (i32.add + (local.get $1) + (i32.const 8) + ) ) (local.set $5 - (i32.const 2) + (i32.add + (local.get $5) + (i32.const -1) + ) ) - (local.get $12) - ) - (block (result i32) - (local.set $3 + (i32.load offset=12 (local.get $1) ) - (local.get $12) + ) + ) + (else + (if (result i32) + (i32.eq + (local.get $5) + (i32.const 2) + ) + (then + (block (result i32) + (i32.store + (local.get $6) + (i32.add + (i32.load + (local.get $6) + ) + (local.get $4) + ) + ) + (local.set $3 + (local.get $1) + ) + (local.set $5 + (i32.const 2) + ) + (local.get $12) + ) + ) + (else + (block (result i32) + (local.set $3 + (local.get $1) + ) + (local.get $12) + ) + ) ) ) ) @@ -578,15 +592,19 @@ ) (i32.const 0) ) - (block (result i32) - (i32.store - (local.get $0) + (then + (block (result i32) + (i32.store + (local.get $0) + (i32.const -1) + ) (i32.const -1) ) - (i32.const -1) ) - (i32.load - (local.get $0) + (else + (i32.load + (local.get $0) + ) ) ) ) @@ -601,17 +619,21 @@ (local.get $0) (i32.const -4096) ) - (block (result i32) - (i32.store - (call $___errno_location) - (i32.sub - (i32.const 0) - (local.get $0) + (then + (block (result i32) + (i32.store + (call $___errno_location) + (i32.sub + (i32.const 0) + (local.get $0) + ) ) + (i32.const -1) ) - (i32.const -1) ) - (local.get $0) + (else + (local.get $0) + ) ) ) (func $___errno_location (result i32) @@ -619,10 +641,14 @@ (i32.load (i32.const 1140) ) - (i32.load offset=64 - (call $_pthread_self) + (then + (i32.load offset=64 + (call $_pthread_self) + ) + ) + (else + (i32.const 1184) ) - (i32.const 1184) ) ) (func $_cleanup_387 (param $0 i32) @@ -632,8 +658,10 @@ (local.get $0) ) ) - (call $_free - (local.get $0) + (then + (call $_free + (local.get $0) + ) ) ) ) @@ -672,29 +700,33 @@ (i32.const 64) ) ) - (block - (i32.store - (local.get $3) - (i32.load offset=60 - (local.get $0) + (then + (block + (i32.store + (local.get $3) + (i32.load offset=60 + (local.get $0) + ) ) - ) - (i32.store offset=4 - (local.get $3) - (i32.const 21505) - ) - (i32.store offset=8 - (local.get $3) - (local.get $5) - ) - (if - (call $___syscall54 - (i32.const 54) + (i32.store offset=4 (local.get $3) + (i32.const 21505) ) - (i32.store8 offset=75 - (local.get $0) - (i32.const -1) + (i32.store offset=8 + (local.get $3) + (local.get $5) + ) + (if + (call $___syscall54 + (i32.const 54) + (local.get $3) + ) + (then + (i32.store8 offset=75 + (local.get $0) + (i32.const -1) + ) + ) ) ) ) @@ -717,119 +749,145 @@ (block $do-once (result i32) (if (result i32) (local.get $0) - (block (result i32) - (if - (i32.le_s - (i32.load offset=76 - (local.get $0) + (then + (block (result i32) + (if + (i32.le_s + (i32.load offset=76 + (local.get $0) + ) + (i32.const -1) ) - (i32.const -1) - ) - (br $do-once - (call $___fflush_unlocked - (local.get $0) + (then + (br $do-once + (call $___fflush_unlocked + (local.get $0) + ) + ) ) ) - ) - (local.set $2 - (i32.eqz - (call $_malloc - (local.get $0) + (local.set $2 + (i32.eqz + (call $_malloc + (local.get $0) + ) ) ) - ) - (local.set $1 - (call $___fflush_unlocked - (local.get $0) - ) - ) - (if (result i32) - (local.get $2) - (local.get $1) - (block (result i32) - (call $_free + (local.set $1 + (call $___fflush_unlocked (local.get $0) ) - (local.get $1) ) - ) - ) - (block (result i32) - (local.set $0 (if (result i32) - (i32.load - (i32.const 1136) + (local.get $2) + (then + (local.get $1) ) - (call $_fflush - (i32.load - (i32.const 1136) + (else + (block (result i32) + (call $_free + (local.get $0) + ) + (local.get $1) ) ) - (i32.const 0) ) ) - (call $___lock - (i32.const 1168) - ) - (if - (local.tee $1 - (i32.load - (i32.const 1164) - ) - ) - (loop $while-in - (local.set $2 - (if (result i32) - (i32.gt_s - (i32.load offset=76 - (local.get $1) + ) + (else + (block (result i32) + (local.set $0 + (if (result i32) + (i32.load + (i32.const 1136) + ) + (then + (call $_fflush + (i32.load + (i32.const 1136) ) - (i32.const -1) - ) - (call $_malloc - (local.get $1) ) + ) + (else (i32.const 0) ) ) - (local.set $0 - (if (result i32) - (i32.gt_u - (i32.load offset=20 - (local.get $1) + ) + (call $___lock + (i32.const 1168) + ) + (if + (local.tee $1 + (i32.load + (i32.const 1164) + ) + ) + (then + (loop $while-in + (local.set $2 + (if (result i32) + (i32.gt_s + (i32.load offset=76 + (local.get $1) + ) + (i32.const -1) + ) + (then + (call $_malloc + (local.get $1) + ) + ) + (else + (i32.const 0) + ) ) - (i32.load offset=28 - (local.get $1) + ) + (local.set $0 + (if (result i32) + (i32.gt_u + (i32.load offset=20 + (local.get $1) + ) + (i32.load offset=28 + (local.get $1) + ) + ) + (then + (i32.or + (call $___fflush_unlocked + (local.get $1) + ) + (local.get $0) + ) + ) + (else + (local.get $0) + ) ) ) - (i32.or - (call $___fflush_unlocked - (local.get $1) + (if + (local.get $2) + (then + (call $_free + (local.get $1) + ) ) - (local.get $0) ) - (local.get $0) - ) - ) - (if - (local.get $2) - (call $_free - (local.get $1) - ) - ) - (br_if $while-in - (local.tee $1 - (i32.load offset=56 - (local.get $1) + (br_if $while-in + (local.tee $1 + (i32.load offset=56 + (local.get $1) + ) + ) ) ) ) ) + (call $___unlock + (i32.const 1168) + ) + (local.get $0) ) - (call $___unlock - (i32.const 1168) - ) - (local.get $0) ) ) ) @@ -911,22 +969,24 @@ ) ) ) - (drop - (call_indirect (type $FUNCSIG$iiii) - (local.get $0) - (i32.sub - (local.get $4) - (local.get $6) - ) - (i32.const 1) - (i32.add - (i32.and - (i32.load offset=40 - (local.get $0) + (then + (drop + (call_indirect (type $FUNCSIG$iiii) + (local.get $0) + (i32.sub + (local.get $4) + (local.get $6) + ) + (i32.const 1) + (i32.add + (i32.and + (i32.load offset=40 + (local.get $0) + ) + (i32.const 3) ) - (i32.const 3) + (i32.const 2) ) - (i32.const 2) ) ) ) @@ -976,20 +1036,24 @@ (local.tee $0 (call $__ZSt15get_new_handlerv) ) - (block - (call_indirect (type $FUNCSIG$v) - (i32.add - (i32.and - (local.get $0) - (i32.const 0) + (then + (block + (call_indirect (type $FUNCSIG$v) + (i32.add + (i32.and + (local.get $0) + (i32.const 0) + ) + (i32.const 8) ) - (i32.const 8) ) + (br $while-in) ) - (br $while-in) ) - (local.set $0 - (i32.const 0) + (else + (local.set $0 + (i32.const 0) + ) ) ) ) @@ -1030,97 +1094,105 @@ (local.get $2) (i32.const 20) ) - (block - (local.set $5 - (i32.or + (then + (block + (local.set $5 (i32.or (i32.or - (local.tee $1 - (i32.and + (i32.or + (local.tee $1 + (i32.and + (local.get $1) + (i32.const 255) + ) + ) + (i32.shl (local.get $1) - (i32.const 255) + (i32.const 8) ) ) (i32.shl (local.get $1) - (i32.const 8) + (i32.const 16) ) ) (i32.shl (local.get $1) - (i32.const 16) + (i32.const 24) ) ) - (i32.shl - (local.get $1) - (i32.const 24) - ) ) - ) - (local.set $6 - (i32.and - (local.get $4) - (i32.const -4) - ) - ) - (if - (local.tee $3 + (local.set $6 (i32.and - (local.get $0) - (i32.const 3) + (local.get $4) + (i32.const -4) ) ) - (block - (local.set $3 - (i32.sub - (i32.add - (local.get $0) - (i32.const 4) - ) - (local.get $3) + (if + (local.tee $3 + (i32.and + (local.get $0) + (i32.const 3) ) ) - (loop $while-in - (if - (i32.lt_s - (local.get $0) - (local.get $3) - ) - (block - (i32.store8 - (local.get $0) - (local.get $1) - ) - (local.set $0 + (then + (block + (local.set $3 + (i32.sub (i32.add (local.get $0) - (i32.const 1) + (i32.const 4) + ) + (local.get $3) + ) + ) + (loop $while-in + (if + (i32.lt_s + (local.get $0) + (local.get $3) + ) + (then + (block + (i32.store8 + (local.get $0) + (local.get $1) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (br $while-in) + ) ) ) - (br $while-in) ) ) ) ) - ) - (loop $while-in1 - (if - (i32.lt_s - (local.get $0) - (local.get $6) - ) - (block - (i32.store + (loop $while-in1 + (if + (i32.lt_s (local.get $0) - (local.get $5) + (local.get $6) ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 4) + (then + (block + (i32.store + (local.get $0) + (local.get $5) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 4) + ) + ) + (br $while-in1) ) ) - (br $while-in1) ) ) ) @@ -1132,18 +1204,20 @@ (local.get $0) (local.get $4) ) - (block - (i32.store8 - (local.get $0) - (local.get $1) - ) - (local.set $0 - (i32.add + (then + (block + (i32.store8 (local.get $0) - (i32.const 1) + (local.get $1) ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (br $while-in3) ) - (br $while-in3) ) ) ) @@ -1159,11 +1233,13 @@ (local.get $2) (i32.const 4096) ) - (return - (call $_emscripten_memcpy_big - (local.get $0) - (local.get $1) - (local.get $2) + (then + (return + (call $_emscripten_memcpy_big + (local.get $0) + (local.get $1) + (local.get $2) + ) ) ) ) @@ -1181,84 +1257,90 @@ (i32.const 3) ) ) - (block - (loop $while-in - (block $while-out - (br_if $while-out - (i32.eqz - (i32.and - (local.get $0) - (i32.const 3) + (then + (block + (loop $while-in + (block $while-out + (br_if $while-out + (i32.eqz + (i32.and + (local.get $0) + (i32.const 3) + ) ) ) - ) - (if - (i32.eqz - (local.get $2) - ) - (return - (local.get $3) - ) - ) - (i32.store8 - (local.get $0) - (i32.load8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 1) + (if + (i32.eqz + (local.get $2) + ) + (then + (return + (local.get $3) + ) + ) ) - ) - (br $while-in) - ) - ) - (loop $while-in1 - (if - (i32.ge_s - (local.get $2) - (i32.const 4) - ) - (block - (i32.store + (i32.store8 (local.get $0) - (i32.load + (i32.load8_s (local.get $1) ) ) (local.set $0 (i32.add (local.get $0) - (i32.const 4) + (i32.const 1) ) ) (local.set $1 (i32.add (local.get $1) - (i32.const 4) + (i32.const 1) ) ) (local.set $2 (i32.sub (local.get $2) - (i32.const 4) + (i32.const 1) + ) + ) + (br $while-in) + ) + ) + (loop $while-in1 + (if + (i32.ge_s + (local.get $2) + (i32.const 4) + ) + (then + (block + (i32.store + (local.get $0) + (i32.load + (local.get $1) + ) + ) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 4) + ) + ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 4) + ) + ) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 4) + ) + ) + (br $while-in1) ) ) - (br $while-in1) ) ) ) @@ -1270,32 +1352,34 @@ (local.get $2) (i32.const 0) ) - (block - (i32.store8 - (local.get $0) - (i32.load8_s - (local.get $1) - ) - ) - (local.set $0 - (i32.add + (then + (block + (i32.store8 (local.get $0) - (i32.const 1) + (i32.load8_s + (local.get $1) + ) ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 1) + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) ) - ) - (local.set $2 - (i32.sub - (local.get $2) - (i32.const 1) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (local.set $2 + (i32.sub + (local.get $2) + (i32.const 1) + ) ) + (br $while-in3) ) - (br $while-in3) ) ) ) diff --git a/test/passes/print.bin.txt b/test/passes/print.bin.txt index ed16d9e2124..25b2cc38720 100644 --- a/test/passes/print.bin.txt +++ b/test/passes/print.bin.txt @@ -26,31 +26,33 @@ ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) @@ -117,31 +119,33 @@ ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) diff --git a/test/passes/print_g.bin.txt b/test/passes/print_g.bin.txt index 21f31a8317f..174230388c9 100644 --- a/test/passes/print_g.bin.txt +++ b/test/passes/print_g.bin.txt @@ -33,49 +33,51 @@ ;; code offset: 0xd (i32.const 55) ) - ;; code offset: 0x12 - (loop $label$2 - ;; code offset: 0x2e - (br_if $label$2 - ;; code offset: 0x2d - (i32.ne - ;; code offset: 0x2a - (i32.rem_s - ;; code offset: 0x25 - (local.tee $0 - ;; code offset: 0x24 - (i32.add - ;; code offset: 0x21 + (then + ;; code offset: 0x12 + (loop $label$2 + ;; code offset: 0x2e + (br_if $label$2 + ;; code offset: 0x2d + (i32.ne + ;; code offset: 0x2a + (i32.rem_s + ;; code offset: 0x25 + (local.tee $0 + ;; code offset: 0x24 (i32.add - ;; code offset: 0x1b - (i32.mul - ;; code offset: 0x18 + ;; code offset: 0x21 + (i32.add + ;; code offset: 0x1b (i32.mul - ;; code offset: 0x14 + ;; code offset: 0x18 + (i32.mul + ;; code offset: 0x14 + (local.get $0) + ;; code offset: 0x16 + (local.get $0) + ) + ;; code offset: 0x19 (local.get $0) - ;; code offset: 0x16 + ) + ;; code offset: 0x20 + (i32.div_s + ;; code offset: 0x1c (local.get $0) + ;; code offset: 0x1e + (i32.const -2) ) - ;; code offset: 0x19 - (local.get $0) - ) - ;; code offset: 0x20 - (i32.div_s - ;; code offset: 0x1c - (local.get $0) - ;; code offset: 0x1e - (i32.const -2) ) + ;; code offset: 0x22 + (i32.const 13) ) - ;; code offset: 0x22 - (i32.const 13) ) + ;; code offset: 0x27 + (i32.const 120) ) - ;; code offset: 0x27 - (i32.const 120) + ;; code offset: 0x2b + (i32.const 55) ) - ;; code offset: 0x2b - (i32.const 55) ) ) ) @@ -163,49 +165,51 @@ ;; code offset: 0xd (i32.const 55) ) - ;; code offset: 0x12 - (loop $label$2 - ;; code offset: 0x2e - (br_if $label$2 - ;; code offset: 0x2d - (i32.ne - ;; code offset: 0x2a - (i32.rem_s - ;; code offset: 0x25 - (local.tee $0 - ;; code offset: 0x24 - (i32.add - ;; code offset: 0x21 + (then + ;; code offset: 0x12 + (loop $label$2 + ;; code offset: 0x2e + (br_if $label$2 + ;; code offset: 0x2d + (i32.ne + ;; code offset: 0x2a + (i32.rem_s + ;; code offset: 0x25 + (local.tee $0 + ;; code offset: 0x24 (i32.add - ;; code offset: 0x1b - (i32.mul - ;; code offset: 0x18 + ;; code offset: 0x21 + (i32.add + ;; code offset: 0x1b (i32.mul - ;; code offset: 0x14 + ;; code offset: 0x18 + (i32.mul + ;; code offset: 0x14 + (local.get $0) + ;; code offset: 0x16 + (local.get $0) + ) + ;; code offset: 0x19 (local.get $0) - ;; code offset: 0x16 + ) + ;; code offset: 0x20 + (i32.div_s + ;; code offset: 0x1c (local.get $0) + ;; code offset: 0x1e + (i32.const -2) ) - ;; code offset: 0x19 - (local.get $0) - ) - ;; code offset: 0x20 - (i32.div_s - ;; code offset: 0x1c - (local.get $0) - ;; code offset: 0x1e - (i32.const -2) ) + ;; code offset: 0x22 + (i32.const 13) ) - ;; code offset: 0x22 - (i32.const 13) ) + ;; code offset: 0x27 + (i32.const 120) ) - ;; code offset: 0x27 - (i32.const 120) + ;; code offset: 0x2b + (i32.const 55) ) - ;; code offset: 0x2b - (i32.const 55) ) ) ) diff --git a/test/passes/print_g_metrics.bin.txt b/test/passes/print_g_metrics.bin.txt index 4fd8a953b1d..e5ac1edae13 100644 --- a/test/passes/print_g_metrics.bin.txt +++ b/test/passes/print_g_metrics.bin.txt @@ -29,31 +29,33 @@ ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) @@ -116,31 +118,33 @@ total ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) diff --git a/test/passes/print_g_strip-dwarf.bin.txt b/test/passes/print_g_strip-dwarf.bin.txt index 6c31defb227..967e03f3d39 100644 --- a/test/passes/print_g_strip-dwarf.bin.txt +++ b/test/passes/print_g_strip-dwarf.bin.txt @@ -26,31 +26,33 @@ ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) @@ -117,31 +119,33 @@ ) (i32.const 55) ) - (loop $label$2 - (br_if $label$2 - (i32.ne - (i32.rem_s - (local.tee $0 - (i32.add + (then + (loop $label$2 + (br_if $label$2 + (i32.ne + (i32.rem_s + (local.tee $0 (i32.add - (i32.mul + (i32.add (i32.mul + (i32.mul + (local.get $0) + (local.get $0) + ) (local.get $0) + ) + (i32.div_s (local.get $0) + (i32.const -2) ) - (local.get $0) - ) - (i32.div_s - (local.get $0) - (i32.const -2) ) + (i32.const 13) ) - (i32.const 13) ) + (i32.const 120) ) - (i32.const 120) + (i32.const 55) ) - (i32.const 55) ) ) ) diff --git a/test/passes/remove-non-js-ops.txt b/test/passes/remove-non-js-ops.txt index 5ce482d30ff..a89c7af9410 100644 --- a/test/passes/remove-non-js-ops.txt +++ b/test/passes/remove-non-js-ops.txt @@ -379,7 +379,7 @@ ) ) ) - (block + (then (br_if $label$11 (i32.eqz (local.tee $var$3 @@ -673,7 +673,7 @@ (block $label$13 (if (local.get $var$2) - (block + (then (local.set $var$8 (i64.add (local.get $var$1) @@ -764,16 +764,18 @@ (func $__wasm_ctz_i32 (param $var$0 i32) (result i32) (if (local.get $var$0) - (return - (i32.sub - (i32.const 31) - (i32.clz - (i32.xor - (i32.add + (then + (return + (i32.sub + (i32.const 31) + (i32.clz + (i32.xor + (i32.add + (local.get $var$0) + (i32.const -1) + ) (local.get $var$0) - (i32.const -1) ) - (local.get $var$0) ) ) ) @@ -833,7 +835,7 @@ (f32.const 0.5) ) ) - (block + (then (local.set $var$0 (f32.ceil (local.get $var$0) @@ -844,8 +846,10 @@ (local.get $var$2) (f32.const 0.5) ) - (return - (local.get $var$0) + (then + (return + (local.get $var$0) + ) ) ) (local.set $var$1 @@ -891,7 +895,7 @@ (f64.const 0.5) ) ) - (block + (then (local.set $var$0 (f64.ceil (local.get $var$0) @@ -902,8 +906,10 @@ (local.get $var$2) (f64.const 0.5) ) - (return - (local.get $var$0) + (then + (return + (local.get $var$0) + ) ) ) (local.set $var$1 diff --git a/test/passes/remove-unused-brs_enable-multivalue.txt b/test/passes/remove-unused-brs_enable-multivalue.txt index e03ca15a745..2fd56cb9cf6 100644 --- a/test/passes/remove-unused-brs_enable-multivalue.txt +++ b/test/passes/remove-unused-brs_enable-multivalue.txt @@ -128,25 +128,29 @@ (func $b12-yes (if (i32.const 1) - (block $topmost - (block $block1 - (drop - (i32.const 12) - ) - (block + (then + (block $topmost + (block $block1 (drop - (i32.const 1) + (i32.const 12) + ) + (block + (drop + (i32.const 1) + ) ) ) ) ) - (block $block3 - (drop - (i32.const 27) - ) - (block + (else + (block $block3 (drop - (i32.const 2) + (i32.const 27) + ) + (block + (drop + (i32.const 2) + ) ) ) ) @@ -156,23 +160,27 @@ (block $topmost (result i32) (if (i32.const 1) - (block $block1 - (drop - (i32.const 12) - ) - (drop - (br_if $topmost - (i32.const 1) - (i32.const 1) + (then + (block $block1 + (drop + (i32.const 12) + ) + (drop + (br_if $topmost + (i32.const 1) + (i32.const 1) + ) ) ) ) - (block $block3 - (drop - (i32.const 27) - ) - (br $topmost - (i32.const 2) + (else + (block $block3 + (drop + (i32.const 27) + ) + (br $topmost + (i32.const 2) + ) ) ) ) @@ -195,18 +203,22 @@ (func $b14-tuple (result i32 i64) (if (type $5) (result i32 i64) (i32.const 1) - (block $topmost (type $5) (result i32 i64) - (block $block1 (type $5) (result i32 i64) - (tuple.make 2 - (i32.const 12) - (i64.const 12) + (then + (block $topmost (type $5) (result i32 i64) + (block $block1 (type $5) (result i32 i64) + (tuple.make 2 + (i32.const 12) + (i64.const 12) + ) ) ) ) - (block $block3 (type $5) (result i32 i64) - (tuple.make 2 - (i32.const 27) - (i64.const 27) + (else + (block $block3 (type $5) (result i32 i64) + (tuple.make 2 + (i32.const 27) + (i64.const 27) + ) ) ) ) @@ -221,10 +233,12 @@ (func $b15b (if (i32.const 18) - (block $topmost - (block - (drop - (i32.const 0) + (then + (block $topmost + (block + (drop + (i32.const 0) + ) ) ) ) @@ -253,42 +267,58 @@ (func $b17 (if (i32.const 0) - (block $a - (block $block1 + (then + (block $a + (block $block1 + ) ) ) - (block $block3 + (else + (block $block3 + ) ) ) (if (i32.const 0) - (block $a7 - (drop - (i32.const 1) + (then + (block $a7 + (drop + (i32.const 1) + ) ) ) - (block $block6 + (else + (block $block6 + ) ) ) (if (i32.const 0) - (block $a9 - (block $block8 + (then + (block $a9 + (block $block8 + ) ) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 1) + ) ) ) (if (i32.const 0) - (block $c - (block $b - (block $block11 + (then + (block $c + (block $b + (block $block11 + ) ) ) ) - (block $block13 + (else + (block $block13 + ) ) ) ) @@ -304,9 +334,13 @@ (func $ret-3 (if (i32.const 0) - (block $block0 + (then + (block $block0 + ) ) - (block $block3 + (else + (block $block3 + ) ) ) ) @@ -321,37 +355,45 @@ (block $a (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (block $block2 - (block + (else + (block $block2 + (block + (drop + (i32.const 2) + ) + (br $a) + ) (drop - (i32.const 2) + (i32.const 3) ) - (br $a) - ) - (drop - (i32.const 3) ) ) ) (if (i32.const 0) - (block $block4 - (block + (then + (block $block4 + (block + (drop + (i32.const 2) + ) + (br $a) + ) (drop - (i32.const 2) + (i32.const 3) ) - (br $a) ) + ) + (else (drop - (i32.const 3) + (i32.const 1) ) ) - (drop - (i32.const 1) - ) ) (if (block $block6 (result i32) @@ -363,28 +405,36 @@ ) (i32.const 3) ) - (drop - (i32.const 0) + (then + (drop + (i32.const 0) + ) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 1) + ) ) ) (if (block $a17 (result i32) (i32.const 0) ) - (block $a18 - (block - (drop - (i32.const 1) + (then + (block $a18 + (block + (drop + (i32.const 1) + ) ) ) ) - (block $a20 - (block - (drop - (i32.const 2) + (else + (block $a20 + (block + (drop + (i32.const 2) + ) ) ) ) @@ -396,7 +446,7 @@ (block $do-once$0 (if (call $b13) - (block + (then (drop (i32.const 0) ) @@ -410,7 +460,7 @@ (block $do-once$022 (if (call $b13) - (block + (then (drop (call $b14) ) @@ -424,7 +474,7 @@ (block $do-once$025 (if (i32.const 0) - (block + (then (drop (call $b14) ) @@ -440,9 +490,11 @@ (local.tee $x (i32.const 1) ) - (br $do-once$028 - (local.tee $x - (i32.const 2) + (then + (br $do-once$028 + (local.tee $x + (i32.const 2) + ) ) ) ) @@ -488,10 +540,12 @@ (i32.eqz (i32.const 0) ) - (block $out40 - (nop) - (br_if $in39 - (i32.const 1) + (then + (block $out40 + (nop) + (br_if $in39 + (i32.const 1) + ) ) ) ) @@ -506,29 +560,39 @@ (loop $in45 (if (i32.const 0) - (block $out46 - (unreachable) + (then + (block $out46 + (unreachable) + ) + ) + (else + (br $in45) ) - (br $in45) ) ) (loop $in48 (if (i32.const 0) - (block $out49 - (block - (call $loops) + (then + (block $out49 + (block + (call $loops) + ) ) ) - (br $in48) + (else + (br $in48) + ) ) ) (loop $in-todo (if (i32.const 0) - (block $out-todo + (then + (block $out-todo + ) ) - (block + (else (call $loops) (br $in-todo) ) @@ -537,9 +601,11 @@ (loop $in52 (if (i32.const 0) - (block $out53 + (then + (block $out53 + ) ) - (block + (else (call $loops) (br $in52) ) @@ -548,34 +614,40 @@ (loop $in55 (if (i32.const 0) - (block + (then (call $loops) (br $in55) ) - (block $out56 + (else + (block $out56 + ) ) ) ) (loop $in58 (if (i32.const 0) - (block + (then (drop (i32.const 1) ) (call $loops) (br $in58) ) - (block $out59 + (else + (block $out59 + ) ) ) ) (loop $in62 (if (i32.const 0) - (block $out63 + (then + (block $out63 + ) ) - (block + (else (call $loops) (drop (i32.const 100) @@ -587,21 +659,23 @@ (loop $in65 (if (i32.const 0) - (block + (then (call $loops) (drop (i32.const 101) ) (br $in65) ) - (block $out66 + (else + (block $out66 + ) ) ) ) (loop $in68 (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -611,7 +685,9 @@ ) (br $in68) ) - (block $out69 + (else + (block $out69 + ) ) ) ) @@ -620,11 +696,13 @@ (i32.eqz (i32.const 0) ) - (block $out73 - (nop) - (call $loops) - (return) - (br $in72) + (then + (block $out73 + (nop) + (call $loops) + (return) + (br $in72) + ) ) ) ) @@ -641,9 +719,11 @@ (loop $in78 (if (i32.const 0) - (block $out79 + (then + (block $out79 + ) ) - (block + (else (call $loops) (drop (block $out2 (result i32) @@ -666,9 +746,11 @@ (loop $in-todo2 (if (i32.const 0) - (block $out-todo2 + (then + (block $out-todo2 + ) ) - (block + (else (call $loops) (br $in-todo2) ) @@ -703,9 +785,11 @@ (loop $in-todo287 (if (i32.const 0) - (block $out-todo288 + (then + (block $out-todo288 + ) ) - (block + (else (call $loops) (drop (i32.const 1) @@ -789,16 +873,20 @@ (block $out (result i32) (if (local.get $x) - (br $out - (block (result i32) - (local.set $x - (i32.const 0) + (then + (br $out + (block (result i32) + (local.set $x + (i32.const 0) + ) + (i32.const 1) ) - (i32.const 1) ) ) - (br_if $leave - (i32.const 1) + (else + (br_if $leave + (i32.const 1) + ) ) ) (unreachable) @@ -816,15 +904,19 @@ (block $out (result i32) (if (local.get $x) - (br_if $leave - (i32.const 1) + (then + (br_if $leave + (i32.const 1) + ) ) - (br $out - (block (result i32) - (local.set $x - (i32.const 0) + (else + (br $out + (block (result i32) + (local.set $x + (i32.const 0) + ) + (i32.const 1) ) - (i32.const 1) ) ) ) @@ -843,16 +935,18 @@ (block $out (result i32) (if (local.get $x) - (br $out - (block (result i32) - (drop - (call $if-to-br_if-value-sideeffect - (i32.const 0) - (i32.const 1) + (then + (br $out + (block (result i32) + (drop + (call $if-to-br_if-value-sideeffect + (i32.const 0) + (i32.const 1) + ) ) + (nop) + (i32.const 1) ) - (nop) - (i32.const 1) ) ) ) @@ -874,16 +968,20 @@ (local.get $j) (i32.const 2147483640) ) - (block $x - (block $y - (block $z - (br_if $x - (local.get $j) + (then + (block $x + (block $y + (block $z + (br_if $x + (local.get $j) + ) ) ) ) ) - (block $switch$26 + (else + (block $switch$26 + ) ) ) (i32.store @@ -900,13 +998,15 @@ (i32.eqz (i32.const 0) ) - (block $yes - (nop) - (drop - (i32.const 1) - ) - (drop - (i32.const 2) + (then + (block $yes + (nop) + (drop + (i32.const 1) + ) + (drop + (i32.const 2) + ) ) ) ) @@ -1078,7 +1178,9 @@ ) (if (i32.const 0) - (nop) + (then + (nop) + ) ) ) ) @@ -1087,8 +1189,12 @@ (drop (if (result f64) (unreachable) - (f64.const 1) - (br $label$3) + (then + (f64.const 1) + ) + (else + (br $label$3) + ) ) ) (i64.const 1) @@ -1099,12 +1205,20 @@ (drop (if (result i32) (unreachable) - (if (result i32) - (i32.const 1) - (br $label$39) + (then + (if (result i32) + (i32.const 1) + (then + (br $label$39) + ) + (else + (i32.const 0) + ) + ) + ) + (else (i32.const 0) ) - (i32.const 0) ) ) ) @@ -1114,31 +1228,39 @@ (local $2 f32) (if (result f32) (local.get $0) - (block $label$0 - (block $label$11 - (return - (f32.const 239) - ) - (if - (i32.const 0) + (then + (block $label$0 + (block $label$11 (return - (local.get $2) + (f32.const 239) + ) + (if + (i32.const 0) + (then + (return + (local.get $2) + ) + ) ) ) ) ) - (f32.const -9223372036854775808) + (else + (f32.const -9223372036854775808) + ) ) ) (func $unreachable-return-loop-value (result i64) (loop $loop (if (i32.const 1) - (block $block - (br_if $block + (then + (block $block + (br_if $block + (br $loop) + ) (br $loop) ) - (br $loop) ) ) (br $loop) @@ -1152,11 +1274,13 @@ (loop $label$5 (if (i32.const 11) - (block $label$8 - (br_if $label$8 - (unreachable) + (then + (block $label$8 + (br_if $label$8 + (unreachable) + ) + (br $label$5) ) - (br $label$5) ) ) (br $label$5) @@ -1770,9 +1894,13 @@ (func $tiny-switch (if (i32.const 0) - (block $y + (then + (block $y + ) ) - (block $x + (else + (block $x + ) ) ) (block $z @@ -1946,8 +2074,12 @@ (local.set $x (if (result i32) (local.get $p) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1957,21 +2089,27 @@ (local $var$6 f64) (if (i32.const 0) - (drop - (loop $label$3 (result i64) - (block $label$4 (result i64) - (block $label$5 - (block $label$6 - (local.set $var$1 - (if (result f64) - (unreachable) - (br $label$5) - (f64.const 1) + (then + (drop + (loop $label$3 (result i64) + (block $label$4 (result i64) + (block $label$5 + (block $label$6 + (local.set $var$1 + (if (result f64) + (unreachable) + (then + (br $label$5) + ) + (else + (f64.const 1) + ) + ) ) ) ) + (i64.const 1) ) - (i64.const 1) ) ) ) @@ -1988,15 +2126,23 @@ (func $if-flow-2 (result i32) (if (result i32) (i32.const 0) - (unreachable) - (i32.const 2) + (then + (unreachable) + ) + (else + (i32.const 2) + ) ) ) (func $if-flow-3 (result i32) (if (result i32) (i32.const 0) - (i32.const 1) - (unreachable) + (then + (i32.const 1) + ) + (else + (unreachable) + ) ) ) (func $if-flow-4 (result i32) @@ -2004,11 +2150,15 @@ (return (i32.const 0) ) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) - (return - (i32.const 2) + (else + (return + (i32.const 2) + ) ) ) ) @@ -2023,9 +2173,13 @@ (unreachable) (if (i32.const 0) - (nop) - (return - (i32.const 0) + (then + (nop) + ) + (else + (return + (i32.const 0) + ) ) ) ) @@ -2036,52 +2190,68 @@ (loop $label$1 (if (local.get $0) - (block $label$2 - (local.tee $0 - (loop $label$5 - (br_if $label$5 - (block - (unreachable) - (drop - (i32.const 0) + (then + (block $label$2 + (local.tee $0 + (loop $label$5 + (br_if $label$5 + (block + (unreachable) + (drop + (i32.const 0) + ) ) ) ) ) ) ) - (br $label$1) + (else + (br $label$1) + ) ) ) ) (func $drop-restructure-if (param $x i32) (param $y i32) (result i32) (if (result i32) (local.get $y) - (local.get $x) - (block $label$2 (result i32) - (nop) - (i32.const 0) + (then + (local.get $x) + ) + (else + (block $label$2 (result i32) + (nop) + (i32.const 0) + ) ) ) ) (func $drop-restructure-if-final (param $x i32) (param $y i32) (result i32) (if (result i32) (local.get $y) - (local.get $x) - (block $label$2 (result i32) - (nop) - (unreachable) + (then + (local.get $x) + ) + (else + (block $label$2 (result i32) + (nop) + (unreachable) + ) ) ) ) (func $drop-restructure-if-middle (param $x i32) (param $y i32) (result i32) (if (result i32) (local.get $y) - (local.get $x) - (block $label$2 (result i32) - (nop) - (nop) - (i32.const 0) + (then + (local.get $x) + ) + (else + (block $label$2 (result i32) + (nop) + (nop) + (i32.const 0) + ) ) ) ) @@ -2113,13 +2283,15 @@ (func $if-block (if (i32.const 1) - (block $label - (block - (drop - (i32.const 2) - ) - (drop - (i32.const 3) + (then + (block $label + (block + (drop + (i32.const 2) + ) + (drop + (i32.const 3) + ) ) ) ) @@ -2129,7 +2301,7 @@ (block $label (if (br $label) - (block + (then (drop (i32.const 2) ) @@ -2150,42 +2322,58 @@ (func $if-block-br-1 (if (i32.const 1) - (block $label + (then + (block $label + ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) ) (func $if-block-br-2 (if (i32.const 1) - (block $label - (drop - (i32.const 3) + (then + (block $label + (drop + (i32.const 3) + ) ) ) - (nop) + (else + (nop) + ) ) ) (func $if-block-br-3 (if (i32.const 1) - (block $label + (then + (block $label + ) + ) + (else + (nop) ) - (nop) ) ) (func $if-block-br-4-eithre (if (i32.const 1) - (block $label - (drop - (i32.const 2) + (then + (block $label + (drop + (i32.const 2) + ) ) ) - (drop - (i32.const 3) + (else + (drop + (i32.const 3) + ) ) ) ) @@ -2206,8 +2394,10 @@ (block $label$4 (unreachable) ) - (block $label$3 - (br $label$3) + (then + (block $label$3 + (br $label$3) + ) ) ) (unreachable) @@ -2218,26 +2408,36 @@ (func $if-arm-unreachable (if (unreachable) - (block $label$1 - (nop) + (then + (block $label$1 + (nop) + ) + ) + (else + (unreachable) ) - (unreachable) ) ) (func $propagate-type-if-we-optimize (if (i32.const 1) - (nop) - (block + (then + (nop) + ) + (else (drop (loop $label$3 (result i64) (br_if $label$3 (if (i32.const 0) - (block $label$4 + (then + (block $label$4 + (unreachable) + ) + ) + (else (unreachable) ) - (unreachable) ) ) (i64.const -9) @@ -2311,14 +2511,20 @@ (loop $label$1 (if (i32.const 0) - (if - (i32.const 0) - (block $label$3 - (block + (then + (if + (i32.const 0) + (then + (block $label$3 + (block + ) + ) + ) + (else + (return + (i32.const -8192) + ) ) - ) - (return - (i32.const -8192) ) ) ) @@ -2400,10 +2606,14 @@ (local.get $0) (i32.const 2) ) - (local.tee $0 - (i32.const 1) + (then + (local.tee $0 + (i32.const 1) + ) + ) + (else + (i32.const 0) ) - (i32.const 0) ) ) (drop @@ -2412,9 +2622,13 @@ (local.get $0) (i32.const 2) ) - (i32.const 0) - (local.tee $0 - (i32.const 1) + (then + (i32.const 0) + ) + (else + (local.tee $0 + (i32.const 1) + ) ) ) ) @@ -2429,8 +2643,12 @@ ) (i32.const 2) ) - (local.get $0) - (i32.const 0) + (then + (local.get $0) + ) + (else + (i32.const 0) + ) ) ) (drop @@ -2441,8 +2659,12 @@ ) (i32.const 2) ) - (i32.const 0) - (local.get $0) + (then + (i32.const 0) + ) + (else + (local.get $0) + ) ) ) (drop @@ -2504,15 +2726,17 @@ (func $ifs-copies-recursive (param $20 i32) (result i32) (if (i32.const 1) - (local.set $20 - (select + (then + (local.set $20 (select - (i32.const 4) + (select + (i32.const 4) + (local.get $20) + (i32.const 3) + ) (local.get $20) - (i32.const 3) + (i32.const 2) ) - (local.get $20) - (i32.const 2) ) ) ) @@ -2538,8 +2762,10 @@ (loop $top (if (i32.const 1) - (local.tee $x - (unreachable) + (then + (local.tee $x + (unreachable) + ) ) ) (br $top) @@ -2552,8 +2778,12 @@ (local.set $x (if (result i32) (i32.const 1) - (unreachable) - (local.get $y) + (then + (unreachable) + ) + (else + (local.get $y) + ) ) ) (br $top) @@ -2600,12 +2830,16 @@ (unreachable) (if (i32.const 0) - (block $A - (return - (i32.const 0) + (then + (block $A + (return + (i32.const 0) + ) ) ) - (nop) + (else + (nop) + ) ) ) (func $do-not-flow-values-through-unreachable-code-b (result i32) @@ -2613,12 +2847,16 @@ (unreachable) (if (i32.const 0) - (block $A - (return - (i32.const 0) + (then + (block $A + (return + (i32.const 0) + ) ) ) - (nop) + (else + (nop) + ) ) ) ) @@ -2658,9 +2896,11 @@ ) (if (i32.const 1026) - (br_if $label$1 - (local.tee $0 - (i32.const -7) + (then + (br_if $label$1 + (local.tee $0 + (i32.const -7) + ) ) ) ) @@ -2686,8 +2926,10 @@ (block (result i32) (if (local.get $x) - (return - (i32.const 5) + (then + (return + (i32.const 5) + ) ) ) (i32.const 6) @@ -2699,8 +2941,12 @@ (select (if (result i32) (unreachable) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) (i32.const 1) (i32.const 2) diff --git a/test/passes/remove-unused-brs_enable-multivalue.wast b/test/passes/remove-unused-brs_enable-multivalue.wast index 493ead96e4c..0deff0db881 100644 --- a/test/passes/remove-unused-brs_enable-multivalue.wast +++ b/test/passes/remove-unused-brs_enable-multivalue.wast @@ -125,26 +125,30 @@ (block $topmost (if (i32.const 1) - (block $block1 - (drop - (i32.const 12) - ) - (block + (then + (block $block1 (drop - (i32.const 1) + (i32.const 12) + ) + (block + (drop + (i32.const 1) + ) + (br $topmost) ) - (br $topmost) ) ) - (block $block3 - (drop - (i32.const 27) - ) - (block + (else + (block $block3 (drop - (i32.const 2) + (i32.const 27) + ) + (block + (drop + (i32.const 2) + ) + (br $topmost) ) - (br $topmost) ) ) ) @@ -154,23 +158,27 @@ (block $topmost (result i32) (if (i32.const 1) - (block $block1 - (drop - (i32.const 12) - ) - (drop - (br_if $topmost - (i32.const 1) - (i32.const 1) + (then + (block $block1 + (drop + (i32.const 12) + ) + (drop + (br_if $topmost + (i32.const 1) + (i32.const 1) + ) ) ) ) - (block $block3 - (drop - (i32.const 27) - ) - (br $topmost - (i32.const 2) + (else + (block $block3 + (drop + (i32.const 27) + ) + (br $topmost + (i32.const 2) + ) ) ) ) @@ -181,11 +189,15 @@ (block $topmost (result i32) (if (result i32) (i32.const 1) - (block $block1 (result i32) - (i32.const 12) + (then + (block $block1 (result i32) + (i32.const 12) + ) ) - (block $block3 (result i32) - (i32.const 27) + (else + (block $block3 (result i32) + (i32.const 27) + ) ) ) ) @@ -194,16 +206,20 @@ (block $topmost (result i32 i64) (if (result i32 i64) (i32.const 1) - (block $block1 (result i32 i64) - (tuple.make 2 - (i32.const 12) - (i64.const 12) + (then + (block $block1 (result i32 i64) + (tuple.make 2 + (i32.const 12) + (i64.const 12) + ) ) ) - (block $block3 (result i32 i64) - (tuple.make 2 - (i32.const 27) - (i64.const 27) + (else + (block $block3 (result i32 i64) + (tuple.make 2 + (i32.const 27) + (i64.const 27) + ) ) ) ) @@ -213,7 +229,9 @@ (block $topmost (if (i32.const 17) - (br $topmost) + (then + (br $topmost) + ) ) ) ) @@ -221,11 +239,13 @@ (block $topmost (if (i32.const 18) - (block - (drop - (i32.const 0) + (then + (block + (drop + (i32.const 0) + ) + (br $topmost) ) - (br $topmost) ) ) ) @@ -263,33 +283,45 @@ (block $a (if (i32.const 0) - (block $block1 - (br $a) + (then + (block $block1 + (br $a) + ) ) - (block $block3 - (br $a) + (else + (block $block3 + (br $a) + ) ) ) ) (block $a (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (block $block6 - (br $a) + (else + (block $block6 + (br $a) + ) ) ) ) (block $a (if (i32.const 0) - (block $block8 - (br $a) + (then + (block $block8 + (br $a) + ) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 1) + ) ) ) ) @@ -297,11 +329,15 @@ (block $b (if (i32.const 0) - (block $block11 - (br $b) + (then + (block $block11 + (br $b) + ) ) - (block $block13 - (br $c) + (else + (block $block13 + (br $c) + ) ) ) ) @@ -321,10 +357,14 @@ (block $block0 (if (i32.const 0) - (return) - (block $block3 + (then (return) ) + (else + (block $block3 + (return) + ) + ) ) ) ) @@ -341,37 +381,45 @@ (block $a (if (i32.const 0) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (block $block2 - (block + (else + (block $block2 + (block + (drop + (i32.const 2) + ) + (br $a) + ) (drop - (i32.const 2) + (i32.const 3) ) - (br $a) - ) - (drop - (i32.const 3) ) ) ) (if (i32.const 0) - (block $block4 - (block + (then + (block $block4 + (block + (drop + (i32.const 2) + ) + (br $a) + ) (drop - (i32.const 2) + (i32.const 3) ) - (br $a) ) + ) + (else (drop - (i32.const 3) + (i32.const 1) ) ) - (drop - (i32.const 1) - ) ) (if (block $block6 (result i32) @@ -383,11 +431,15 @@ ) (i32.const 3) ) - (drop - (i32.const 0) + (then + (drop + (i32.const 0) + ) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 1) + ) ) ) (if @@ -396,20 +448,24 @@ (i32.const 0) ) ) - (block $a - (block - (drop - (i32.const 1) + (then + (block $a + (block + (drop + (i32.const 1) + ) + (br $a) ) - (br $a) ) ) - (block $a - (block - (drop - (i32.const 2) + (else + (block $a + (block + (drop + (i32.const 2) + ) + (br $a) ) - (br $a) ) ) ) @@ -420,11 +476,13 @@ (block $do-once$0 (if (call $b13) - (block - (drop - (i32.const 0) + (then + (block + (drop + (i32.const 0) + ) + (br $do-once$0) ) - (br $do-once$0) ) ) (drop @@ -434,11 +492,13 @@ (block $do-once$0 (if (call $b13) - (block - (drop - (call $b14) + (then + (block + (drop + (call $b14) + ) + (br $do-once$0) ) - (br $do-once$0) ) ) (drop @@ -448,11 +508,13 @@ (block $do-once$0 (if (i32.const 0) - (block - (drop - (call $b14) + (then + (block + (drop + (call $b14) + ) + (br $do-once$0) ) - (br $do-once$0) ) ) (drop @@ -464,9 +526,11 @@ (local.tee $x (i32.const 1) ) - (br $do-once$0 - (local.tee $x - (i32.const 2) + (then + (br $do-once$0 + (local.tee $x + (i32.const 2) + ) ) ) ) @@ -476,7 +540,7 @@ (func $loops (loop $in (block $out - (if (i32.const 0) (br $out)) + (if (i32.const 0) (then (br $out))) (br $in) ;; we can conditionalize this, and then the br out can vanish ) ) @@ -485,13 +549,13 @@ ) (loop (block $out - (if (i32.const 0) (br $out)) + (if (i32.const 0) (then (br $out))) (br $out) ) ) (loop $in (block $out - (if (i32.const 0) (br $out)) + (if (i32.const 0) (then (br $out))) (br $out) ) ) @@ -501,28 +565,30 @@ ) (loop $in (block $out - (if (i32.const 0) (br $out)) + (if (i32.const 0) (then (br $out))) (br_if $in (i32.const 1)) ) ) (loop $in (block $out - (if (i32.const 0) (br $in)) + (if (i32.const 0) (then (br $in))) (br $out) ) ) (loop $in (block $out - (if (i32.const 0) (unreachable)) + (if (i32.const 0) (then (unreachable))) (br $in) ) ) (loop $in (block $out (if (i32.const 0) - (block - (call $loops) - (br $out) + (then + (block + (call $loops) + (br $out) + ) ) ) (br $in) @@ -530,7 +596,7 @@ ) (loop $in-todo ;; br_if into if (block $out-todo - (if (i32.const 0) (br $out-todo)) + (if (i32.const 0) (then (br $out-todo))) (call $loops) (br $in-todo) ) @@ -538,8 +604,12 @@ (loop $in (block $out (if (i32.const 0) - (br $out) - (call $loops) + (then + (br $out) + ) + (else + (call $loops) + ) ) (br $in) ) @@ -547,8 +617,12 @@ (loop $in (block $out (if (i32.const 0) - (call $loops) - (br $out) + (then + (call $loops) + ) + (else + (br $out) + ) ) (br $in) ) @@ -556,11 +630,15 @@ (loop $in (block $out (if (i32.const 0) - (block - (drop (i32.const 1)) - (call $loops) + (then + (block + (drop (i32.const 1)) + (call $loops) + ) + ) + (else + (br $out) ) - (br $out) ) (br $in) ) @@ -568,8 +646,12 @@ (loop $in (block $out (if (i32.const 0) - (br $out) - (call $loops) + (then + (br $out) + ) + (else + (call $loops) + ) ) (drop (i32.const 100)) (br $in) @@ -578,8 +660,12 @@ (loop $in (block $out (if (i32.const 0) - (call $loops) - (br $out) + (then + (call $loops) + ) + (else + (br $out) + ) ) (drop (i32.const 101)) (br $in) @@ -588,11 +674,15 @@ (loop $in (block $out (if (i32.const 0) - (block - (drop (i32.const 1)) - (call $loops) + (then + (block + (drop (i32.const 1)) + (call $loops) + ) + ) + (else + (br $out) ) - (br $out) ) (drop (i32.const 102)) (br $in) @@ -601,8 +691,12 @@ (loop $in (block $out (if (i32.const 0) - (br $out) - (call $loops) + (then + (br $out) + ) + (else + (call $loops) + ) ) (return) (br $in) @@ -611,8 +705,12 @@ (loop $in (block $out (if (i32.const 0) - (br $out) - (call $loops) + (then + (br $out) + ) + (else + (call $loops) + ) ) (br $out) (br $in) @@ -621,8 +719,12 @@ (loop $in (block $out (if (i32.const 0) - (br $out) - (call $loops) + (then + (br $out) + ) + (else + (call $loops) + ) ) (drop (block $out2 (result i32) @@ -677,14 +779,14 @@ (func $br_if_in_block (result i32) (block $outval (result i32) (block $in - (if (i32.const 1) (br $in) (br $in)) + (if (i32.const 1) (then (br $in) )(else (br $in))) (drop (i32.const 2)) - (if (i32.const 3) (unreachable) (br $in)) + (if (i32.const 3) (then (unreachable) )(else (br $in))) (drop (i32.const 4)) - (if (i32.const 5) (br $in) (unreachable)) + (if (i32.const 5) (then (br $in) )(else (unreachable))) (drop (i32.const 6)) ) - (if (result i32) (i32.const 6) (br $outval (i32.const 7)) (i32.const 8)) + (if (result i32) (i32.const 6) (then (br $outval (i32.const 7)) )(else (i32.const 8))) ) ) (func $threading @@ -694,7 +796,9 @@ (block $out (block $in (if (i32.const 1) - (br $in) + (then + (br $in) + ) ) (br_if $in (i32.const 2)) (br $value-in (i32.const 3)) @@ -710,7 +814,9 @@ (block $stack3 (block $stack4 (if (i32.const 1) - (br $stack4) + (then + (br $stack4) + ) ) (unreachable) ) @@ -727,13 +833,17 @@ (block $out (result i32) (if (local.get $x) - (br $out - (block (result i32) - (local.set $x (i32.const 0)) - (i32.const 1) + (then + (br $out + (block (result i32) + (local.set $x (i32.const 0)) + (i32.const 1) + ) ) ) - (br_if $leave (i32.const 1)) + (else + (br_if $leave (i32.const 1)) + ) ) (unreachable) ) @@ -747,11 +857,15 @@ (block $out (result i32) (if (local.get $x) - (br_if $leave (i32.const 1)) - (br $out - (block (result i32) - (local.set $x (i32.const 0)) - (i32.const 1) + (then + (br_if $leave (i32.const 1)) + ) + (else + (br $out + (block (result i32) + (local.set $x (i32.const 0)) + (i32.const 1) + ) ) ) ) @@ -767,11 +881,13 @@ (block $out (result i32) (if (local.get $x) - (br $out - (block (result i32) - (drop (call $if-to-br_if-value-sideeffect (i32.const 0) (i32.const 1))) - (nop) - (i32.const 1) + (then + (br $out + (block (result i32) + (drop (call $if-to-br_if-value-sideeffect (i32.const 0) (i32.const 1))) + (nop) + (i32.const 1) + ) ) ) ) @@ -790,19 +906,23 @@ (local.get $j) (i32.const 2147483640) ) - (block $x - (block $y - (block $z - (br_if $y - (local.get $j) + (then + (block $x + (block $y + (block $z + (br_if $y + (local.get $j) + ) + (br $x) ;; don't be confused by this ) - (br $x) ;; don't be confused by this + (nop) ;; get me to the store! ) - (nop) ;; get me to the store! ) ) - (block $switch$26 - (nop) + (else + (block $switch$26 + (nop) + ) ) ) (i32.store @@ -857,9 +977,11 @@ ;; element in the block, (if (i32.const 2) - (block - (drop (call $loop-if)) - (br $outer (i32.const 0)) + (then + (block + (drop (call $loop-if)) + (br $outer (i32.const 0)) + ) ) ) (br $typed) @@ -927,10 +1049,14 @@ (i32.load8_s (i32.const 201460482) ) - (br $label$0) - (block $label$3 - (br_if $label$3 - (local.get $0) + (then + (br $label$0) + ) + (else + (block $label$3 + (br_if $label$3 + (local.get $0) + ) ) ) ) @@ -971,7 +1097,9 @@ ) (if (i32.const 0) - (nop) + (then + (nop) + ) ) ) ) @@ -980,8 +1108,12 @@ (drop (if (result f64) (unreachable) - (f64.const 1) - (br $label$3) + (then + (f64.const 1) + ) + (else + (br $label$3) + ) ) ) (i64.const 1) @@ -992,12 +1124,20 @@ (drop (if (result i32) (unreachable) - (if (result i32) - (i32.const 1) - (br $label$39) ;; if we nop this, then the parent type must change + (then + (if (result i32) + (i32.const 1) + (then + (br $label$39) ;; if we nop this, then the parent type must change + ) + (else + (i32.const 0) + ) + ) + ) + (else (i32.const 0) ) - (i32.const 0) ) ) ) @@ -1008,19 +1148,25 @@ (block $label$0 (if (local.get $0) - (block $label$11 - (return - (f32.const 239) - ) - (if - (i32.const 0) + (then + (block $label$11 (return - (local.get $2) + (f32.const 239) + ) + (if + (i32.const 0) + (then + (return + (local.get $2) + ) + ) ) ) ) - (return - (f32.const -9223372036854775808) + (else + (return + (f32.const -9223372036854775808) + ) ) ) ) @@ -1029,11 +1175,13 @@ (loop $loop (if (i32.const 1) - (block $block - (br_if $block + (then + (block $block + (br_if $block + (br $loop) + ) (br $loop) ) - (br $loop) ) ) (br $loop) ;; we 100% go back to the loop top, the loop is never exited. but opts move code around so that is not obvious anymore, and the loop becomes a nop, but the func has a return value @@ -1047,11 +1195,13 @@ (loop $label$5 (if (i32.const 11) - (block $label$8 ;; this block is none - it has a break, even if not taken - and so looks like it might flow out, - (br_if $label$8 ;; and so we can't move it outside to be the end of the loop's block - (unreachable) + (then + (block $label$8 ;; this block is none - it has a break, even if not taken - and so looks like it might flow out, + (br_if $label$8 ;; and so we can't move it outside to be the end of the loop's block + (unreachable) + ) + (br $label$5) ) - (br $label$5) ) ) (br $label$5) @@ -1554,22 +1704,34 @@ (local.set $x (if (result i32) (local.get $p) - (br $out) - (i32.const 1) + (then + (br $out) + ) + (else + (i32.const 1) + ) ) ) (local.set $x (if (result i32) (local.get $p) - (i32.const 2) - (br $out) + (then + (i32.const 2) + ) + (else + (br $out) + ) ) ) (local.set $x (if (result i32) (local.get $p) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1579,22 +1741,28 @@ (local $var$6 f64) (if (i32.const 0) - (drop - (loop $label$3 (result i64) - (block $label$4 (result i64) - (block $label$5 - (block $label$6 - (local.set $var$1 - (if (result f64) - (unreachable) - (br $label$5) - (f64.const 1) + (then + (drop + (loop $label$3 (result i64) + (block $label$4 (result i64) + (block $label$5 + (block $label$6 + (local.set $var$1 + (if (result f64) + (unreachable) + (then + (br $label$5) + ) + (else + (f64.const 1) + ) + ) ) ) + (nop) ) - (nop) + (i64.const 1) ) - (i64.const 1) ) ) ) @@ -1604,42 +1772,64 @@ (func $if-flow-1 (result i32) (if (i32.const 0) - (return (i32.const 1)) - (return (i32.const 2)) + (then + (return (i32.const 1)) + ) + (else + (return (i32.const 2)) + ) ) ) (func $if-flow-2 (result i32) (if (i32.const 0) - (unreachable) - (return (i32.const 2)) + (then + (unreachable) + ) + (else + (return (i32.const 2)) + ) ) ) (func $if-flow-3 (result i32) (if (i32.const 0) - (return (i32.const 1)) - (unreachable) + (then + (return (i32.const 1)) + ) + (else + (unreachable) + ) ) ) (func $if-flow-4 (result i32) (if (return (i32.const 0)) - (return (i32.const 1)) - (return (i32.const 2)) + (then + (return (i32.const 1)) + ) + (else + (return (i32.const 2)) + ) ) ) (func $iff-flow-fuzz-bug (result i32) (loop $label$1 (if (i32.const 1) - (loop $label$2 - (unreachable) - (if ;; a loop that is never reached at the end of a loop - (i32.const 0) - (nop) - (return + (then + (loop $label$2 + (unreachable) + (if ;; a loop that is never reached at the end of a loop (i32.const 0) + (then + (nop) + ) + (else + (return + (i32.const 0) + ) + ) ) ) ) @@ -1653,12 +1843,14 @@ (block $label$2 (result i32) (if (local.get $0) - (local.set $0 - (loop $label$5 - (br_if $label$5 - (br_if $label$2 - (unreachable) - (i32.const 0) + (then + (local.set $0 + (loop $label$5 + (br_if $label$5 + (br_if $label$2 + (unreachable) + (i32.const 0) + ) ) ) ) @@ -1728,9 +1920,11 @@ (block $label (if (i32.const 1) - (block - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (block + (drop (i32.const 2)) + (drop (i32.const 3)) + ) ) ) ) @@ -1739,9 +1933,11 @@ (block $label (if (br $label) ;; use outside of arm - (block - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (block + (drop (i32.const 2)) + (drop (i32.const 3)) + ) ) ) ) @@ -1750,7 +1946,9 @@ (block $label (if (i32.const 1) - (br $label) + (then + (br $label) + ) ) ) ) @@ -1758,8 +1956,12 @@ (block $label (if (i32.const 1) - (br $label) - (drop (i32.const 3)) + (then + (br $label) + ) + (else + (drop (i32.const 3)) + ) ) ) ) @@ -1767,8 +1969,12 @@ (block $label (if (i32.const 1) - (drop (i32.const 3)) - (br $label) + (then + (drop (i32.const 3)) + ) + (else + (br $label) + ) ) ) ) @@ -1776,8 +1982,12 @@ (block $label (if (i32.const 1) - (br $label) - (br $label) + (then + (br $label) + ) + (else + (br $label) + ) ) ) ) @@ -1785,8 +1995,12 @@ (block $label (if (i32.const 1) - (drop (i32.const 2)) - (drop (i32.const 3)) + (then + (drop (i32.const 2)) + ) + (else + (drop (i32.const 3)) + ) ) ) ) @@ -1794,8 +2008,12 @@ (block $label (result i32) (if (result i32) (i32.const 1) - (i32.const 2) - (i32.const 3) + (then + (i32.const 2) + ) + (else + (i32.const 3) + ) ) ) ) @@ -1808,7 +2026,9 @@ (block $label$4 (unreachable) ) - (br $label$3) + (then + (br $label$3) + ) ) ) (unreachable) @@ -1820,31 +2040,43 @@ (block $label$1 (if (unreachable) ;; unreachable condition - (nop) - (unreachable) + (then + (nop) + ) + (else + (unreachable) + ) ) ) ) (func $propagate-type-if-we-optimize (if (i32.const 1) - (nop) - (block - (drop - (loop $label$3 (result i64) - (br_if $label$3 - (block $label$4 (result i32) - (if - (i32.const 0) - (unreachable) - (unreachable) + (then + (nop) + ) + (else + (block + (drop + (loop $label$3 (result i64) + (br_if $label$3 + (block $label$4 (result i32) + (if + (i32.const 0) + (then + (unreachable) + ) + (else + (unreachable) + ) + ) ) ) + (i64.const -9) ) - (i64.const -9) ) + (unreachable) ) - (unreachable) ) ) ) @@ -1905,15 +2137,21 @@ (loop $label$1 (if (i32.const 0) - (block $label$3 - (if - (i32.const 0) - (block - (nop) - (br $label$3) - ) - (return - (i32.const -8192) + (then + (block $label$3 + (if + (i32.const 0) + (then + (block + (nop) + (br $label$3) + ) + ) + (else + (return + (i32.const -8192) + ) + ) ) ) ) @@ -1950,13 +2188,17 @@ (local.get $x) (i32.const 1) ) - (i32.mul - (i32.const 2) - (i32.const 3) + (then + (i32.mul + (i32.const 2) + (i32.const 3) + ) ) - (i32.mul - (i32.const 2) - (i32.const 3) + (else + (i32.mul + (i32.const 2) + (i32.const 3) + ) ) ) ) @@ -1966,13 +2208,17 @@ (local.get $x) (i32.const 1) ) - (i32.add - (i32.const 2) - (i32.const 3) + (then + (i32.add + (i32.const 2) + (i32.const 3) + ) ) - (i32.add - (i32.const 2) - (i32.const 3) + (else + (i32.add + (i32.const 2) + (i32.const 3) + ) ) ) ) @@ -1983,8 +2229,12 @@ (local.get $0) (i32.const 2) ) - (i32.const 1) - (i32.const 0) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) )) ) (func $no-selectify-when-arm-side-effects (param $0 i32) @@ -1993,16 +2243,24 @@ (local.get $0) (i32.const 2) ) - (local.tee $0 (i32.const 1)) - (i32.const 0) + (then + (local.tee $0 (i32.const 1)) + ) + (else + (i32.const 0) + ) )) (drop (if (result i32) (i32.rem_s (local.get $0) (i32.const 2) ) - (i32.const 0) - (local.tee $0 (i32.const 1)) + (then + (i32.const 0) + ) + (else + (local.tee $0 (i32.const 1)) + ) )) ) (func $no-selectify-when-effects-invalidate (param $0 i32) @@ -2012,16 +2270,24 @@ (local.tee $0 (i32.const 3)) (i32.const 2) ) - (local.get $0) - (i32.const 0) + (then + (local.get $0) + ) + (else + (i32.const 0) + ) )) (drop (if (result i32) (i32.rem_s (local.tee $0 (i32.const 3)) (i32.const 2) ) - (i32.const 0) - (local.get $0) + (then + (i32.const 0) + ) + (else + (local.get $0) + ) )) ;; but different locals do not invalidate (drop (if (result i32) @@ -2029,8 +2295,12 @@ (local.tee $0 (i32.const 3)) (i32.const 2) ) - (i32.const 0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (local.get $1) + ) )) ) (func $if-one-side (result i32) @@ -2038,8 +2308,12 @@ (local.set $x (if (result i32) (i32.const 1) - (i32.const 2) - (local.get $x) + (then + (i32.const 2) + ) + (else + (local.get $x) + ) ) ) (local.get $x) @@ -2049,8 +2323,12 @@ (local.set $x (if (result i32) (i32.const 1) - (local.get $x) - (i32.const 2) + (then + (local.get $x) + ) + (else + (i32.const 2) + ) ) ) (local.get $x) @@ -2068,8 +2346,12 @@ (local.tee $x (if (result i32) (i32.const -3) - (i32.const -4) - (local.get $x) + (then + (i32.const -4) + ) + (else + (local.get $x) + ) ) ) ) @@ -2080,16 +2362,28 @@ (local.set $20 (if (result i32) (i32.const 1) - (if (result i32) - (i32.const 2) + (then (if (result i32) - (i32.const 3) - (i32.const 4) - (local.get $20) + (i32.const 2) + (then + (if (result i32) + (i32.const 3) + (then + (i32.const 4) + ) + (else + (local.get $20) + ) + ) + ) + (else + (local.get $20) + ) ) + ) + (else (local.get $20) ) - (local.get $20) ) ) (local.get $20) @@ -2101,8 +2395,12 @@ (local.set $x (if (result i32) (i32.const 1) - (local.get $x) - (local.get $y) + (then + (local.get $x) + ) + (else + (local.get $y) + ) ) ) (br $top) @@ -2115,8 +2413,12 @@ (local.set $x (if (result i32) (i32.const 1) - (unreachable) - (local.get $x) + (then + (unreachable) + ) + (else + (local.get $x) + ) ) ) (br $top) @@ -2129,8 +2431,12 @@ (local.set $x (if (result i32) (i32.const 1) - (unreachable) - (local.get $y) + (then + (unreachable) + ) + (else + (local.get $y) + ) ) ) (br $top) @@ -2144,8 +2450,12 @@ (local.tee $x (if (result i32) (i32.const 1) - (local.get $x) - (i32.const 2) + (then + (local.get $x) + ) + (else + (i32.const 2) + ) ) ) ) @@ -2157,8 +2467,12 @@ (nop) (if (local.get $x) - (br $loop) - (local.set $x (i32.const 1)) + (then + (br $loop) + ) + (else + (local.set $x (i32.const 1)) + ) ) ) (local.get $x) @@ -2168,8 +2482,12 @@ (nop) (if (result i32) (local.get $x) - (br $loop) - (i32.const 1) + (then + (br $loop) + ) + (else + (i32.const 1) + ) ) ) ) @@ -2179,10 +2497,14 @@ (block $A (if (i32.const 0) - (return - (i32.const 0) ;; seems to flow out, but we are in unreachable code, and do not actually reach anywhere + (then + (return + (i32.const 0) ;; seems to flow out, but we are in unreachable code, and do not actually reach anywhere + ) + ) + (else + (br $A) ;; can be a nop ) - (br $A) ;; can be a nop ) ) ) @@ -2193,10 +2515,14 @@ (block $A (if (i32.const 0) - (return - (i32.const 0) + (then + (return + (i32.const 0) + ) + ) + (else + (br $A) ) - (br $A) ) ) ) @@ -2208,17 +2534,21 @@ (local.tee $0 ;; note side effect; it's ok (i32.const 1024) ) - (br_if $label$1 - (i32.eqz - (i32.const -4) + (then + (br_if $label$1 + (i32.eqz + (i32.const -4) + ) ) ) ) (if (i32.const 1025) - (br_if $label$1 - (i32.eqz - (i32.const -5) + (then + (br_if $label$1 + (i32.eqz + (i32.const -5) + ) ) ) ) @@ -2226,17 +2556,21 @@ (local.tee $0 ;; note side effect; it's ok (i32.const 1025) ) - (br_if $label$1 - (i32.eqz - (i32.const -6) + (then + (br_if $label$1 + (i32.eqz + (i32.const -6) + ) ) ) ) (if (i32.const 1026) - (br_if $label$1 - (local.tee $0 ;; but here it is *not* ok - (i32.const -7) + (then + (br_if $label$1 + (local.tee $0 ;; but here it is *not* ok + (i32.const -7) + ) ) ) ) @@ -2262,8 +2596,10 @@ (block (result i32) (if (local.get $x) - (return - (i32.const 5) + (then + (return + (i32.const 5) + ) ) ) (i32.const 6) @@ -2275,8 +2611,12 @@ (select (if (result i32) (unreachable) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) (i32.const 1) (i32.const 2) diff --git a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast index 909e9514ac1..5c0fe15363b 100644 --- a/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast +++ b/test/passes/remove-unused-brs_precompute_vacuum_remove-unused-brs.wast @@ -11,14 +11,18 @@ (i32.const 9) (i32.const 0) ) - (return - (f64.const -3.4) + (then + (return + (f64.const -3.4) + ) ) ) (if (local.get $x) - (return - (f64.const 5.6) + (then + (return + (f64.const 5.6) + ) ) ) (return diff --git a/test/passes/remove-unused-brs_shrink-level=1.txt b/test/passes/remove-unused-brs_shrink-level=1.txt index c32b64d0330..06b4e4e7278 100644 --- a/test/passes/remove-unused-brs_shrink-level=1.txt +++ b/test/passes/remove-unused-brs_shrink-level=1.txt @@ -17,10 +17,14 @@ (drop (if (result i32) (i32.const 1) - (i32.load - (i32.const 10) + (then + (i32.load + (i32.const 10) + ) + ) + (else + (i32.const 27) ) - (i32.const 27) ) ) (drop @@ -36,10 +40,14 @@ (drop (if (result i32) (i32.const 1) - (i32.trunc_f64_u - (f64.const 12.34) + (then + (i32.trunc_f64_u + (f64.const 12.34) + ) + ) + (else + (i32.const 27) ) - (i32.const 27) ) ) (i32.const 0) @@ -108,9 +116,11 @@ (i32.const 0) ) ) - (block $out8 - (nop) - (nop) + (then + (block $out8 + (nop) + (nop) + ) ) ) (block $out83 diff --git a/test/passes/remove-unused-brs_shrink-level=1.wast b/test/passes/remove-unused-brs_shrink-level=1.wast index 2033ffd7ced..ce141c43003 100644 --- a/test/passes/remove-unused-brs_shrink-level=1.wast +++ b/test/passes/remove-unused-brs_shrink-level=1.wast @@ -7,33 +7,49 @@ (drop (if (result i32) ;; with shrinking, this can become a select (i32.const 1) - (block $block1 (result i32) - (i32.const 12) + (then + (block $block1 (result i32) + (i32.const 12) + ) ) - (block $block3 (result i32) - (i32.const 27) + (else + (block $block3 (result i32) + (i32.const 27) + ) ) ) ) (drop (if (result i32) (i32.const 1) - (i32.load (i32.const 10)) ;; load may have side effects, unless ignored - (i32.const 27) + (then + (i32.load (i32.const 10)) ;; load may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (drop (if (result i32) (i32.const 1) - (i32.rem_s (i32.const 11) (i32.const 12)) ;; rem may have side effects, unless ignored - (i32.const 27) + (then + (i32.rem_s (i32.const 11) (i32.const 12)) ;; rem may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (drop (if (result i32) (i32.const 1) - (i32.trunc_f64_u (f64.const 12.34)) ;; float to int may have side effects, unless ignored - (i32.const 27) + (then + (i32.trunc_f64_u (f64.const 12.34)) ;; float to int may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (i32.const 0) diff --git a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt index 6f8f400424a..8398d6ee6fe 100644 --- a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt +++ b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt @@ -108,9 +108,11 @@ (i32.const 0) ) ) - (block $out8 - (nop) - (nop) + (then + (block $out8 + (nop) + (nop) + ) ) ) (block $out83 diff --git a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast index 08d3fb31851..4f15dc9c020 100644 --- a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast +++ b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast @@ -7,33 +7,49 @@ (drop (if (result i32) ;; with shrinking, this can become a select (i32.const 1) - (block $block1 (result i32) - (i32.const 12) + (then + (block $block1 (result i32) + (i32.const 12) + ) ) - (block $block3 (result i32) - (i32.const 27) + (else + (block $block3 (result i32) + (i32.const 27) + ) ) ) ) (drop (if (result i32) (i32.const 1) - (i32.load (i32.const 10)) ;; load may have side effects, unless ignored - (i32.const 27) + (then + (i32.load (i32.const 10)) ;; load may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (drop (if (result i32) (i32.const 1) - (i32.rem_s (i32.const 11) (i32.const 12)) ;; rem may have side effects, unless ignored - (i32.const 27) + (then + (i32.rem_s (i32.const 11) (i32.const 12)) ;; rem may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (drop (if (result i32) (i32.const 1) - (i32.trunc_f64_u (f64.const 12.34)) ;; float to int may have side effects, unless ignored - (i32.const 27) + (then + (i32.trunc_f64_u (f64.const 12.34)) ;; float to int may have side effects, unless ignored + ) + (else + (i32.const 27) + ) ) ) (i32.const 0) diff --git a/test/passes/remove-unused-names_code-folding.txt b/test/passes/remove-unused-names_code-folding.txt index 7d7505b0739..d0486b3c784 100644 --- a/test/passes/remove-unused-names_code-folding.txt +++ b/test/passes/remove-unused-names_code-folding.txt @@ -6,7 +6,9 @@ (func $ifs (if (i32.const 0) - (nop) + (then + (nop) + ) ) (block (drop @@ -16,8 +18,12 @@ ) (if (i32.const 0) - (nop) - (unreachable) + (then + (nop) + ) + (else + (unreachable) + ) ) (drop (block (result i32) @@ -33,13 +39,17 @@ (drop (if (result i32) (i32.const 0) - (i32.add - (i32.const 1) - (i32.const 2) + (then + (i32.add + (i32.const 1) + (i32.const 2) + ) ) - (i32.add - (i32.const 1) - (i32.const 333333333) + (else + (i32.add + (i32.const 1) + (i32.const 333333333) + ) ) ) ) @@ -56,8 +66,10 @@ (block (if (i32.const 0) - (unreachable) - (block + (then + (unreachable) + ) + (else ) ) (nop) @@ -65,24 +77,30 @@ (block (if (i32.const 0) - (block + (then + ) + (else + (unreachable) ) - (unreachable) ) (nop) ) (if (i32.const 0) - (block + (then (nop) (unreachable) ) - (nop) + (else + (nop) + ) ) (if (i32.const 0) - (nop) - (block + (then + (nop) + ) + (else (nop) (unreachable) ) @@ -105,8 +123,10 @@ (block (if (i32.const 0) - (unreachable) - (block + (then + (unreachable) + ) + (else ) ) (drop @@ -119,9 +139,11 @@ (block (if (i32.const 0) - (block + (then + ) + (else + (unreachable) ) - (unreachable) ) (drop (i32.add @@ -132,7 +154,7 @@ ) (if (i32.const 0) - (block + (then (drop (i32.add (i32.const 1) @@ -141,22 +163,26 @@ ) (unreachable) ) - (drop - (i32.add - (i32.const 1) - (i32.const 2) + (else + (drop + (i32.add + (i32.const 1) + (i32.const 2) + ) ) ) ) (if (i32.const 0) - (drop - (i32.add - (i32.const 1) - (i32.const 2) + (then + (drop + (i32.add + (i32.const 1) + (i32.const 2) + ) ) ) - (block + (else (drop (i32.add (i32.const 1) @@ -171,7 +197,7 @@ (block (if (i32.const 1) - (block + (then (drop (i32.const -1234) ) @@ -179,8 +205,10 @@ (i32.const -1000) ) ) - (drop - (i32.const 999) + (else + (drop + (i32.const 999) + ) ) ) (drop @@ -193,7 +221,7 @@ (block (result i32) (if (i32.const 2) - (block + (then (drop (i32.const -1234) ) @@ -201,8 +229,10 @@ (i32.const -1000) ) ) - (drop - (i32.const 999) + (else + (drop + (i32.const 999) + ) ) ) (drop @@ -217,7 +247,7 @@ (block (result i32) (if (i32.const 3) - (block + (then (drop (i32.const -1234) ) @@ -225,8 +255,10 @@ (i32.const -1000) ) ) - (drop - (i32.const 999) + (else + (drop + (i32.const 999) + ) ) ) (drop @@ -242,34 +274,36 @@ (block (if (i32.const 0) - (if - (i32.const 0) - (block - (drop - (i32.const -1234) - ) - (drop - (i32.const -1000) - ) - (br $folding-inner0) - ) - (block - (drop - (i32.const 999) + (then + (if + (i32.const 0) + (then + (drop + (i32.const -1234) + ) + (drop + (i32.const -1000) + ) + (br $folding-inner0) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 999) + ) + (drop + (i32.const 1) + ) + (br $folding-inner0) ) - (br $folding-inner0) ) ) ) (if (i32.const 0) - (block + (then (if (i32.const 0) - (block + (then (drop (i32.const -1234) ) @@ -277,7 +311,7 @@ (i32.const -1000) ) ) - (block + (else (drop (i32.const 999) ) @@ -292,12 +326,12 @@ ) (if (i32.const 0) - (block + (then (if (i32.const 0) - (block + (then ) - (block + (else (drop (i32.const 999) ) @@ -311,10 +345,10 @@ ) (if (i32.const 0) - (block + (then (if (i32.const 0) - (block + (then (drop (i32.const -1234) ) @@ -322,7 +356,7 @@ (i32.const -1000) ) ) - (block + (else ) ) (br $folding-inner0) @@ -332,7 +366,7 @@ (block (if (i32.const 9999) - (block + (then (drop (i32.const -51234) ) @@ -340,7 +374,7 @@ (i32.const -51000) ) ) - (block + (else (drop (i32.const 5999) ) @@ -357,7 +391,7 @@ (block (result i32) (if (i32.const 9999) - (block + (then (drop (i32.const -51234) ) @@ -365,7 +399,7 @@ (i32.const -51000) ) ) - (block + (else (drop (i32.const 5999) ) @@ -383,7 +417,7 @@ (drop (if (result i32) (i32.const 9999) - (block (result i32) + (then (drop (i32.const -51234) ) @@ -393,7 +427,7 @@ (unreachable) (i32.const 10) ) - (block (result i32) + (else (drop (i32.const 5999) ) @@ -414,7 +448,7 @@ (func $no-grandparent (if (i32.const 9999) - (block + (then (drop (i32.const -51234) ) @@ -424,7 +458,7 @@ (unreachable) (unreachable) ) - (block + (else (drop (i32.const 5999) ) @@ -440,7 +474,7 @@ (block (if (i32.const 9999) - (block + (then (drop (i32.const -51234) ) @@ -448,7 +482,7 @@ (i32.const -51000) ) ) - (block + (else (drop (i32.const 5999) ) @@ -478,44 +512,52 @@ (block (if (local.get $x) - (br_if $out - (local.get $y) + (then + (br_if $out + (local.get $y) + ) ) - (br_if $out2 - (local.get $y) + (else + (br_if $out2 + (local.get $y) + ) ) ) (nop) ) (if (i32.const 1234) - (if - (local.get $x) - (block - (nop) - (br_if $out - (local.get $y) + (then + (if + (local.get $x) + (then + (nop) + (br_if $out + (local.get $y) + ) + (nop) ) - (nop) - ) - (block - (nop) - (br_if $out2 - (local.get $y) + (else + (nop) + (br_if $out2 + (local.get $y) + ) + (nop) ) - (nop) ) ) ) (if (local.get $x) - (block $left - (br_if $left - (local.get $y) + (then + (block $left + (br_if $left + (local.get $y) + ) + (nop) ) - (nop) ) - (block + (else (br_if $out (local.get $y) ) @@ -524,17 +566,19 @@ ) (if (local.get $x) - (block + (then (br_if $out (local.get $y) ) (nop) ) - (block $right - (br_if $right - (local.get $y) + (else + (block $right + (br_if $right + (local.get $y) + ) + (nop) ) - (nop) ) ) ) @@ -550,11 +594,15 @@ (block $x (if (i32.const 0) - (br $x) + (then + (br $x) + ) ) (if (i32.const 0) - (br $x) + (then + (br $x) + ) ) (br $x) ) @@ -569,7 +617,7 @@ (block $x (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -581,7 +629,7 @@ ) (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -604,7 +652,7 @@ (block $x (if (i32.const 0) - (block + (then (drop (i32.const 1000) ) @@ -613,7 +661,7 @@ ) (if (i32.const 0) - (block + (then (drop (i32.const 2000) ) @@ -665,10 +713,12 @@ (block (if (i32.const 1) - (drop - (i32.const 3) + (then + (drop + (i32.const 3) + ) ) - (block + (else (drop (i32.const 4) ) @@ -725,7 +775,9 @@ (block $x (if (i32.const 0) - (br $x) + (then + (br $x) + ) ) ) (drop @@ -739,7 +791,7 @@ (block $y (result i32) (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -766,7 +818,7 @@ (block $z (result i32) (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -790,7 +842,7 @@ (block $w (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -812,7 +864,7 @@ (block $x1 (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -837,7 +889,7 @@ ) (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -860,7 +912,7 @@ ) (if (i32.const 0) - (block + (then (drop (i32.const 1) ) @@ -884,15 +936,21 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) ) (return) @@ -915,15 +973,21 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (unreachable) ) @@ -947,15 +1011,21 @@ (block (result i32) (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (i32.const 4) ) @@ -979,15 +1049,19 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (block + (then (nop) (nop) (nop) @@ -1028,15 +1102,19 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner1) + (then + (br $folding-inner1) + ) ) (if (i32.const 3) - (block + (then (drop (i32.const 10) ) @@ -1069,19 +1147,27 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 1) - (br $folding-inner1) + (then + (br $folding-inner1) + ) ) (if (i32.const 1) - (br $folding-inner1) + (then + (br $folding-inner1) + ) ) ) (return) @@ -1124,15 +1210,21 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) ) (return) @@ -1145,7 +1237,7 @@ (func $terminating-not-worth-it (if (i32.const 1) - (block + (then (nop) (nop) (unreachable) @@ -1153,7 +1245,7 @@ ) (if (i32.const 2) - (block + (then (nop) (nop) (unreachable) @@ -1161,7 +1253,7 @@ ) (if (i32.const 3) - (block + (then (nop) (nop) (unreachable) @@ -1173,15 +1265,21 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) ) (return) @@ -1204,19 +1302,25 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (block + (then (nop) (return (i32.add @@ -1245,19 +1349,25 @@ (block (result i32) (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (block + (then (nop) (return (i32.add @@ -1284,27 +1394,39 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 4) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 5) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 6) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (unreachable) ) @@ -1321,26 +1443,36 @@ (block (if (i32.const 1) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 2) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 4) - (br $folding-inner0) + (then + (br $folding-inner0) + ) ) (if (i32.const 3) - (return - (i32.add - (i32.const 1) - (i32.const 234567) + (then + (return + (i32.add + (i32.const 1) + (i32.const 234567) + ) ) ) ) @@ -1368,7 +1500,9 @@ (func $drop-if-with-value-but-unreachable (if (i32.const 0) - (nop) + (then + (nop) + ) ) (block (drop @@ -1380,8 +1514,12 @@ ) (if (i32.const 0) - (nop) - (unreachable) + (then + (nop) + ) + (else + (unreachable) + ) ) (nop) (drop @@ -1400,13 +1538,17 @@ (drop (if (result i32) (i32.const 0) - (i32.add - (i32.const 1) - (i32.const 2) + (then + (i32.add + (i32.const 1) + (i32.const 2) + ) ) - (i32.add - (i32.const 1) - (i32.const 333333333) + (else + (i32.add + (i32.const 1) + (i32.const 333333333) + ) ) ) ) @@ -1417,17 +1559,23 @@ (block $x (if (i32.const 0) - (br $x) + (then + (br $x) + ) ) (if (i32.const 0) - (br $x) + (then + (br $x) + ) ) (br $x) ) (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (drop (i32.const 1) @@ -1447,27 +1595,33 @@ (block (if (i32.const 0) - (block + (then (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (br $folding-inner0) ) ) (if (i32.const 0) - (block + (then (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (br $folding-inner0) ) ) (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (br $folding-inner0) ) @@ -1492,26 +1646,30 @@ (block (if (i32.const 0) - (block + (then (if (i32.add (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) (br $folding-inner0) ) ) (if (i32.const 0) - (block + (then (if (i32.add (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) (br $folding-inner0) ) @@ -1521,7 +1679,9 @@ (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) (br $folding-inner0) ) @@ -1546,26 +1706,30 @@ (block (if (i32.const 0) - (block + (then (if (i32.add (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) (br $out) ) ) (if (i32.const 0) - (block + (then (if (i32.add (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) (br $out) ) @@ -1575,7 +1739,9 @@ (i32.const 0) (i32.const 1) ) - (br $middle) + (then + (br $middle) + ) ) ) ) @@ -1613,11 +1779,15 @@ (block (if (i32.const 0) - (br $out) + (then + (br $out) + ) ) (if (i32.const 0) - (br $out) + (then + (br $out) + ) ) (br $out) ) @@ -1628,7 +1798,9 @@ (i32.const 0) (i32.const 1) ) - (br $x) + (then + (br $x) + ) ) (drop (i32.const 1) @@ -1649,11 +1821,15 @@ (block (if (i32.const 0) - (br $out) + (then + (br $out) + ) ) (if (i32.const 0) - (br $out) + (then + (br $out) + ) ) (br $out) ) @@ -1664,7 +1840,9 @@ (i32.const 0) (i32.const 1) ) - (br $x) + (then + (br $x) + ) ) ) (drop @@ -1682,11 +1860,13 @@ (block (if (local.get $x) - (block + (then ) - (drop - (call $if-suffix - (i32.const -1) + (else + (drop + (call $if-suffix + (i32.const -1) + ) ) ) ) @@ -1697,11 +1877,13 @@ (block (result i32) (if (local.get $x) - (block + (then ) - (drop - (call $if-suffix - (i32.const -2) + (else + (drop + (call $if-suffix + (i32.const -2) + ) ) ) ) diff --git a/test/passes/remove-unused-names_code-folding.wast b/test/passes/remove-unused-names_code-folding.wast index 9979a0a3c28..642bbdf7c09 100644 --- a/test/passes/remove-unused-names_code-folding.wast +++ b/test/passes/remove-unused-names_code-folding.wast @@ -1,162 +1,222 @@ (module (func $ifs - (if (i32.const 0) (nop)) - (if (i32.const 0) (nop) (nop)) - (if (i32.const 0) (nop) (unreachable)) + (if (i32.const 0) (then (nop))) + (if (i32.const 0) (then (nop) )(else (nop))) + (if (i32.const 0) (then (nop) )(else (unreachable))) (drop (if (result i32) (i32.const 0) - (i32.add (i32.const 1) (i32.const 2)) - (i32.add (i32.const 1) (i32.const 2)) + (then + (i32.add (i32.const 1) (i32.const 2)) + ) + (else + (i32.add (i32.const 1) (i32.const 2)) + ) ) ) (drop (if (result i32) (i32.const 0) - (i32.add (i32.const 1) (i32.const 2)) - (i32.add (i32.const 1) (i32.const 333333333)) + (then + (i32.add (i32.const 1) (i32.const 2)) + ) + (else + (i32.add (i32.const 1) (i32.const 333333333)) + ) ) ) ) (func $ifs-blocks (if (i32.const 0) - (block - (nop) + (then + (block + (nop) + ) ) - (block - (nop) + (else + (block + (nop) + ) ) ) (if (i32.const 0) - (block - (unreachable) - (nop) + (then + (block + (unreachable) + (nop) + ) ) - (block - (nop) + (else + (block + (nop) + ) ) ) (if (i32.const 0) - (block - (nop) + (then + (block + (nop) + ) ) - (block - (unreachable) - (nop) + (else + (block + (unreachable) + (nop) + ) ) ) (if (i32.const 0) - (block - (nop) - (unreachable) + (then + (block + (nop) + (unreachable) + ) ) - (block - (nop) + (else + (block + (nop) + ) ) ) (if (i32.const 0) - (block - (nop) + (then + (block + (nop) + ) ) - (block - (nop) - (unreachable) + (else + (block + (nop) + (unreachable) + ) ) ) ) (func $ifs-blocks-big (if (i32.const 0) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (else + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 0) - (block - (unreachable) - (drop (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (unreachable) + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (else + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 0) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) - (block - (unreachable) - (drop (i32.add (i32.const 1) (i32.const 2))) + (else + (block + (unreachable) + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 0) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) - (unreachable) + (then + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + (unreachable) + ) ) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (else + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 0) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + ) ) - (block - (drop (i32.add (i32.const 1) (i32.const 2))) - (unreachable) + (else + (block + (drop (i32.add (i32.const 1) (i32.const 2))) + (unreachable) + ) ) ) ) (func $ifs-blocks-long (if (i32.const 1) - (block - (drop (i32.const -1234)) - (drop (i32.const -1000)) - (drop (i32.const 1)) - (nop) - (unreachable) - ) - (block - (drop (i32.const 999)) - (drop (i32.const 1)) - (nop) - (unreachable) - ) - ) - (drop - (if (result i32) (i32.const 2) - (block (result i32) + (then + (block (drop (i32.const -1234)) (drop (i32.const -1000)) (drop (i32.const 1)) (nop) (unreachable) - (i32.const 2) ) - (block (result i32) + ) + (else + (block (drop (i32.const 999)) (drop (i32.const 1)) (nop) (unreachable) - (i32.const 2) + ) + ) + ) + (drop + (if (result i32) (i32.const 2) + (then + (block (result i32) + (drop (i32.const -1234)) + (drop (i32.const -1000)) + (drop (i32.const 1)) + (nop) + (unreachable) + (i32.const 2) + ) + ) + (else + (block (result i32) + (drop (i32.const 999)) + (drop (i32.const 1)) + (nop) + (unreachable) + (i32.const 2) + ) ) ) ) (drop (if (result i32) (i32.const 3) - (block (result i32) - (drop (i32.const -1234)) - (drop (i32.const -1000)) - (drop (i32.const 1)) - (nop) - (i32.const 2) + (then + (block (result i32) + (drop (i32.const -1234)) + (drop (i32.const -1000)) + (drop (i32.const 1)) + (nop) + (i32.const 2) + ) ) - (block (result i32) - (drop (i32.const 999)) - (drop (i32.const 1)) - (nop) - (i32.const 2) + (else + (block (result i32) + (drop (i32.const 999)) + (drop (i32.const 1)) + (nop) + (i32.const 2) + ) ) ) ) @@ -164,84 +224,112 @@ (func $if-worth-it-i-dunno ;; just 2, so not worth it (if (i32.const 0) ;; (put them in ifs, so no block outside which would make us more confident in creating a block in hopes it would vanish) - (if (i32.const 0) - (block - (drop (i32.const -1234)) - (drop (i32.const -1000)) - (unreachable) - (unreachable) - ) - (block - (drop (i32.const 999)) - (drop (i32.const 1)) - (unreachable) - (unreachable) + (then + (if (i32.const 0) + (then + (block + (drop (i32.const -1234)) + (drop (i32.const -1000)) + (unreachable) + (unreachable) + ) + ) + (else + (block + (drop (i32.const 999)) + (drop (i32.const 1)) + (unreachable) + (unreachable) + ) + ) ) ) ) ;; 3, so why not (if (i32.const 0) ;; (put them in ifs, so no block outside which would make us more confident in creating a block in hopes it would vanish) - (if (i32.const 0) - (block - (drop (i32.const -1234)) - (drop (i32.const -1000)) - (unreachable) - (unreachable) - (unreachable) - ) - (block - (drop (i32.const 999)) - (drop (i32.const 1)) - (unreachable) - (unreachable) - (unreachable) + (then + (if (i32.const 0) + (then + (block + (drop (i32.const -1234)) + (drop (i32.const -1000)) + (unreachable) + (unreachable) + (unreachable) + ) + ) + (else + (block + (drop (i32.const 999)) + (drop (i32.const 1)) + (unreachable) + (unreachable) + (unreachable) + ) + ) ) ) ) ;; just 2, but we'll empty out a block (if (i32.const 0) ;; (put them in ifs, so no block outside which would make us more confident in creating a block in hopes it would vanish) - (if (i32.const 0) - (block - (unreachable) - (unreachable) - ) - (block - (drop (i32.const 999)) - (drop (i32.const 1)) - (unreachable) - (unreachable) + (then + (if (i32.const 0) + (then + (block + (unreachable) + (unreachable) + ) + ) + (else + (block + (drop (i32.const 999)) + (drop (i32.const 1)) + (unreachable) + (unreachable) + ) + ) ) ) ) ;; just 2, but we'll empty out a block (if (i32.const 0) ;; (put them in ifs, so no block outside which would make us more confident in creating a block in hopes it would vanish) - (if (i32.const 0) - (block - (drop (i32.const -1234)) - (drop (i32.const -1000)) - (unreachable) - (unreachable) - ) - (block - (unreachable) - (unreachable) + (then + (if (i32.const 0) + (then + (block + (drop (i32.const -1234)) + (drop (i32.const -1000)) + (unreachable) + (unreachable) + ) + ) + (else + (block + (unreachable) + (unreachable) + ) + ) ) ) ) ;; just two, but on a block, so we hope to merge, and can optimize here (block $a-holding-block (if (i32.const 9999) - (block - (drop (i32.const -51234)) - (drop (i32.const -51000)) - (unreachable) - (unreachable) + (then + (block + (drop (i32.const -51234)) + (drop (i32.const -51000)) + (unreachable) + (unreachable) + ) ) - (block - (drop (i32.const 5999)) - (drop (i32.const 51)) - (unreachable) - (unreachable) + (else + (block + (drop (i32.const 5999)) + (drop (i32.const 51)) + (unreachable) + (unreachable) + ) ) ) ) @@ -249,17 +337,21 @@ (drop (block $b-holding-block (result i32) (if (result i32) (i32.const 9999) - (block (result i32) - (drop (i32.const -51234)) - (drop (i32.const -51000)) - (unreachable) - (i32.const 10) + (then + (block (result i32) + (drop (i32.const -51234)) + (drop (i32.const -51000)) + (unreachable) + (i32.const 10) + ) ) - (block (result i32) - (drop (i32.const 5999)) - (drop (i32.const 51)) - (unreachable) - (i32.const 10) + (else + (block (result i32) + (drop (i32.const 5999)) + (drop (i32.const 51)) + (unreachable) + (i32.const 10) + ) ) ) ) @@ -268,17 +360,21 @@ (block $c-holding-block (drop (if (result i32) (i32.const 9999) - (block (result i32) - (drop (i32.const -51234)) - (drop (i32.const -51000)) - (unreachable) - (i32.const 10) + (then + (block (result i32) + (drop (i32.const -51234)) + (drop (i32.const -51000)) + (unreachable) + (i32.const 10) + ) ) - (block (result i32) - (drop (i32.const 5999)) - (drop (i32.const 51)) - (unreachable) - (i32.const 10) + (else + (block (result i32) + (drop (i32.const 5999)) + (drop (i32.const 51)) + (unreachable) + (i32.const 10) + ) ) ) ) @@ -287,29 +383,15 @@ (func $no-grandparent ;; if we had a parent block, we might optimize this (if (i32.const 9999) - (block - (drop (i32.const -51234)) - (drop (i32.const -51000)) - (unreachable) - (unreachable) - ) - (block - (drop (i32.const 5999)) - (drop (i32.const 51)) - (unreachable) - (unreachable) - ) - ) - ) - (func $yes-grandparent - (block - (if (i32.const 9999) + (then (block (drop (i32.const -51234)) (drop (i32.const -51000)) (unreachable) (unreachable) ) + ) + (else (block (drop (i32.const 5999)) (drop (i32.const 51)) @@ -319,61 +401,105 @@ ) ) ) - (func $ifs-named-block (param $x i32) (param $y i32) (result i32) - (block $out - (block $out2 - (if (local.get $x) + (func $yes-grandparent + (block + (if (i32.const 9999) + (then (block - (br_if $out (local.get $y i32)) - (nop) + (drop (i32.const -51234)) + (drop (i32.const -51000)) + (unreachable) + (unreachable) ) + ) + (else (block - (br_if $out (local.get $y i32)) - (nop) + (drop (i32.const 5999)) + (drop (i32.const 51)) + (unreachable) + (unreachable) ) ) + ) + ) + ) + (func $ifs-named-block (param $x i32) (param $y i32) (result i32) + (block $out + (block $out2 (if (local.get $x) - (block - (br_if $out (local.get $y i32)) - (nop) + (then + (block + (br_if $out (local.get $y i32)) + (nop) + ) ) - (block - (br_if $out2 (local.get $y i32)) - (nop) + (else + (block + (br_if $out (local.get $y i32)) + (nop) + ) ) ) - (if (i32.const 1234) - (if (local.get $x) + (if (local.get $x) + (then (block - (nop) (br_if $out (local.get $y i32)) (nop) ) + ) + (else (block - (nop) (br_if $out2 (local.get $y i32)) (nop) ) ) ) + (if (i32.const 1234) + (then + (if (local.get $x) + (then + (block + (nop) + (br_if $out (local.get $y i32)) + (nop) + ) + ) + (else + (block + (nop) + (br_if $out2 (local.get $y i32)) + (nop) + ) + ) + ) + ) + ) (if (local.get $x) - (block $left - (br_if $left (local.get $y i32)) - (nop) + (then + (block $left + (br_if $left (local.get $y i32)) + (nop) + ) ) - (block - (br_if $out (local.get $y i32)) - (nop) + (else + (block + (br_if $out (local.get $y i32)) + (nop) + ) ) ) (if (local.get $x) - (block - (br_if $out (local.get $y i32)) - (nop) + (then + (block + (br_if $out (local.get $y i32)) + (nop) + ) ) - (block $right - (br_if $right (local.get $y i32)) - (nop) + (else + (block $right + (br_if $right (local.get $y i32)) + (nop) + ) ) ) ) @@ -384,17 +510,21 @@ (func $block (block $x (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) ;; no fallthrough, another thing to merge @@ -406,17 +536,21 @@ (func $block2 (block $x (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 333333)) - (br $x) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 333333)) + (br $x) + ) ) ) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) ;; no fallthrough, another thing to merge @@ -428,20 +562,24 @@ (func $block3 (block $x (if (i32.const 0) - (block - (drop (i32.const 1000)) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 1000)) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) (if (i32.const 0) - (block - (drop (i32.const 2000)) - (drop (i32.const 3000)) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 2000)) + (drop (i32.const 3000)) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) (drop (i32.const 4000)) @@ -456,59 +594,75 @@ (func $mixture (block $out ;; then we reach the block, and the tail infos are stale, should ignore (if (i32.const 1) ;; then we optimize the if, pushing those brs outside! - (block - (drop (i32.const 2)) ;; first we note the block tails for $out - (nop) (nop) (nop) (nop) (nop) (nop) ;; totally worth it - (br $out) + (then + (block + (drop (i32.const 2)) ;; first we note the block tails for $out + (nop) (nop) (nop) (nop) (nop) (nop) ;; totally worth it + (br $out) + ) ) - (block - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out) + (else + (block + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out) + ) ) ) ) (block $out2 (if (i32.const 1) - (block - (drop (i32.const 3)) ;; leave something - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out2) + (then + (block + (drop (i32.const 3)) ;; leave something + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out2) + ) ) - (block - (drop (i32.const 4)) ;; leave something - (drop (i32.const 5)) ;; leave something - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out2) + (else + (block + (drop (i32.const 4)) ;; leave something + (drop (i32.const 5)) ;; leave something + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out2) + ) ) ) ) ;; now a case where do **do** want to fold for the block (which we can only do in a later pass) (block $out3 (if (i32.const 1) - (block - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out3) + (then + (block + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out3) + ) ) - (block - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out3) + (else + (block + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out3) + ) ) ) (if (i32.const 1) - (block - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out3) + (then + (block + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out3) + ) ) - (block - (drop (i32.const 2)) - (nop) (nop) (nop) (nop) (nop) (nop) - (br $out3) + (else + (block + (drop (i32.const 2)) + (nop) (nop) (nop) (nop) (nop) (nop) + (br $out3) + ) ) ) (drop (i32.const 2)) @@ -520,10 +674,12 @@ ;; these should be merged (block $x (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) + ) ) ) (drop (i32.const 1)) @@ -534,10 +690,12 @@ (drop (block $y (result i32) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $y (i32.const 3)) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $y (i32.const 3)) + ) ) ) (drop (i32.const 1)) @@ -548,10 +706,12 @@ (drop (block $z (result i32) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $z (i32.const 2)) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $z (i32.const 2)) + ) ) ) (drop (i32.const 1)) @@ -562,10 +722,12 @@ ;; condition (block $w (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br_if $w (i32.const 3)) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br_if $w (i32.const 3)) + ) ) ) (drop (i32.const 1)) @@ -574,11 +736,13 @@ ;; not at the end (block $x1 (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x1) - (nop) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x1) + (nop) + ) ) ) (drop (i32.const 1)) @@ -589,10 +753,12 @@ (block $x2 (br_table $x2 $side (i32.const 0)) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x2) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x2) + ) ) ) (drop (i32.const 1)) @@ -601,10 +767,12 @@ (block $x3 (br_table $side $x3 (i32.const 0)) (if (i32.const 0) - (block - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x3) + (then + (block + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x3) + ) ) ) (drop (i32.const 1)) @@ -614,267 +782,339 @@ ) (func $terminating (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) ) (func $terminating-unreachable (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (unreachable) ) (func $terminating-value (result i32) (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (i32.const 4) ) (func $terminating-just-2 (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (drop (i32.const 10)) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (drop (i32.const 10)) + (unreachable) + ) ) ) ) (func $terminating-shortness (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ;; shorter. we do the two long ones greedily, then the merged one and this can also be opted - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) ;; shorter. we do the two long ones greedily, then the merged one and this can also be opted + (unreachable) + ) ) ) (if (i32.const 3) - (block - (drop (i32.const 10)) - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (unreachable) + (then + (block + (drop (i32.const 10)) + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (unreachable) + ) ) ) ) (func $terminating-multiple-separate (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (drop (i32.const 1)) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (drop (i32.const 1)) + (unreachable) + ) ) ) (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (drop (i32.const 1)) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (drop (i32.const 1)) + (unreachable) + ) ) ) (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (drop (i32.const 2)) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (drop (i32.const 2)) + (unreachable) + ) ) ) (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (drop (i32.const 2)) - (unreachable) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (drop (i32.const 2)) + (unreachable) + ) ) ) ) (func $terminating-just-worth-it (if (i32.const 1) - (block - (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) (nop) + (unreachable) + ) ) ) ) (func $terminating-not-worth-it (if (i32.const 1) - (block - (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) + (unreachable) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) - (unreachable) + (then + (block + (nop) (nop) + (unreachable) + ) ) ) ) (func $terminating-return (if (i32.const 1) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (return) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (return) + ) ) ) (if (i32.const 2) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (return) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (return) + ) ) ) (if (i32.const 3) - (block - (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) - (return) + (then + (block + (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) (nop) + (return) + ) ) ) ) (func $terminating-return-value (result i32) (if (i32.const 1) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 2) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 3) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 3) - (block - (nop) - (return (i32.add (i32.const 111111111) (i32.const 2222222))) + (then + (block + (nop) + (return (i32.add (i32.const 111111111) (i32.const 2222222))) + ) ) ) (return (i32.const 1234)) ) (func $terminating-fallthrough-value (result i32) (if (i32.const 1) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 2) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 3) - (block - (nop) - (return (i32.add (i32.const 1) (i32.const 2))) + (then + (block + (nop) + (return (i32.add (i32.const 1) (i32.const 2))) + ) ) ) (if (i32.const 3) - (block - (nop) - (return (i32.add (i32.const 111111111) (i32.const 2222222))) + (then + (block + (nop) + (return (i32.add (i32.const 111111111) (i32.const 2222222))) + ) ) ) (i32.const 1234) ) (func $big-return (result i32) - (if (i32.const 1) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 2) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 3) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 4) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 5) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 6) (return (i32.add (i32.const 1) (i32.const 2)))) + (if (i32.const 1) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 2) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 3) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 4) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 5) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 6) (then (return (i32.add (i32.const 1) (i32.const 2))))) (unreachable) ) (func $return-mix (result i32) - (if (i32.const 1) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 2) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 3) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 4) (return (i32.add (i32.const 1) (i32.const 2)))) - (if (i32.const 3) (return (i32.add (i32.const 1) (i32.const 234567)))) + (if (i32.const 1) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 2) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 3) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 4) (then (return (i32.add (i32.const 1) (i32.const 2))))) + (if (i32.const 3) (then (return (i32.add (i32.const 1) (i32.const 234567))))) (return (i32.add (i32.const 1) (i32.const 2))) ;; on a block, and the toplevel in fact ) (func $just-unreachable @@ -887,42 +1127,56 @@ (block $label$0 (if (i32.const 0) - (block $label$1 - (nop) + (then + (block $label$1 + (nop) + ) ) ) (if (i32.const 0) - (block $label$2 - (nop) + (then + (block $label$2 + (nop) + ) ) - (block $label$3 - (nop) + (else + (block $label$3 + (nop) + ) ) ) (if (i32.const 0) - (block $label$4 - (nop) + (then + (block $label$4 + (nop) + ) ) - (block $label$5 - (unreachable) + (else + (block $label$5 + (unreachable) + ) ) ) (nop) (drop (if (result i32) ;; we replace this if, must replace with same type! (unreachable) - (block $label$6 (result i32) - (i32.add - (i32.const 1) - (i32.const 2) + (then + (block $label$6 (result i32) + (i32.add + (i32.const 1) + (i32.const 2) + ) ) ) - (block $label$7 (result i32) - (i32.add - (i32.const 1) - (i32.const 2) + (else + (block $label$7 (result i32) + (i32.add + (i32.const 1) + (i32.const 2) + ) ) ) ) @@ -930,16 +1184,20 @@ (drop (if (result i32) (i32.const 0) - (block $label$8 (result i32) - (i32.add - (i32.const 1) - (i32.const 2) + (then + (block $label$8 (result i32) + (i32.add + (i32.const 1) + (i32.const 2) + ) ) ) - (block $label$9 (result i32) - (i32.add - (i32.const 1) - (i32.const 333333333) + (else + (block $label$9 (result i32) + (i32.add + (i32.const 1) + (i32.const 333333333) + ) ) ) ) @@ -950,28 +1208,38 @@ (block $out (block $x (if (i32.const 0) - (block - (if (i32.const 1) - (br $out) + (then + (block + (if (i32.const 1) + (then + (br $out) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) ) ) (if (i32.const 0) - (block - (if (i32.const 1) - (br $out) + (then + (block + (if (i32.const 1) + (then + (br $out) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $x) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $x) ) ) ;; no fallthrough, another thing to merge (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (drop (i32.const 1)) (drop (i32.const 2)) @@ -984,28 +1252,38 @@ (block $out (block $x (if (i32.const 0) - (block - (if (i32.const 1) - (br $out) ;; this br cannot be moved out of the $out block! + (then + (block + (if (i32.const 1) + (then + (br $out) ;; this br cannot be moved out of the $out block! + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (return) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (return) ) ) (if (i32.const 0) - (block - (if (i32.const 1) - (br $out) + (then + (block + (if (i32.const 1) + (then + (br $out) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (return) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (return) ) ) ;; no fallthrough, another thing to merge (if (i32.const 1) - (br $out) + (then + (br $out) + ) ) (drop (i32.const 1)) (drop (i32.const 2)) @@ -1019,28 +1297,38 @@ (block $middle (block $x (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $middle) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (return) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (return) ) ) (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $middle) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (return) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (return) ) ) ;; no fallthrough, another thing to merge (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) + (then + (br $middle) + ) ) (drop (i32.const 1)) (drop (i32.const 2)) @@ -1055,40 +1343,50 @@ (block $middle (block $x (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) ;; this is dangerous - we branch to middle with is inside out, so we can't move this out of out + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $middle) ;; this is dangerous - we branch to middle with is inside out, so we can't move this out of out + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (drop (i32.const 3)) + (drop (i32.const 4)) + (drop (i32.const 1)) + (drop (i32.const 2)) + (drop (i32.const 3)) + (drop (i32.const 4)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (drop (i32.const 3)) - (drop (i32.const 4)) - (drop (i32.const 1)) - (drop (i32.const 2)) - (drop (i32.const 3)) - (drop (i32.const 4)) - (br $out) ) ) (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $middle) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (drop (i32.const 3)) + (drop (i32.const 4)) + (drop (i32.const 1)) + (drop (i32.const 2)) + (drop (i32.const 3)) + (drop (i32.const 4)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (drop (i32.const 3)) - (drop (i32.const 4)) - (drop (i32.const 1)) - (drop (i32.const 2)) - (drop (i32.const 3)) - (drop (i32.const 4)) - (br $out) ) ) ;; no fallthrough, another thing to merge (if (i32.add (i32.const 0) (i32.const 1)) - (br $middle) + (then + (br $middle) + ) ) ) ) @@ -1100,28 +1398,38 @@ (block $out (block $middle (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) ;; this is ok - we branch to x which is outside of out + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $x) ;; this is ok - we branch to x which is outside of out + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $out) ) ) (if (i32.const 0) - (block - (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) + (then + (block + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $x) + ) + ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $out) ) ) ;; no fallthrough, another thing to merge (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) + (then + (br $x) + ) ) (drop (i32.const 1)) (drop (i32.const 2)) @@ -1137,33 +1445,43 @@ (block $out (block $middle (if (i32.const 0) - (block - (block $x - (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) ;; this is ok - we branch to x which is nested in us + (then + (block + (block $x + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $x) ;; this is ok - we branch to x which is nested in us + ) + ) ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $out) ) ) (if (i32.const 0) - (block - (block $x - (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) ;; this is ok - we branch to x which is nested in us + (then + (block + (block $x + (if (i32.add (i32.const 0) (i32.const 1)) + (then + (br $x) ;; this is ok - we branch to x which is nested in us + ) + ) ) + (drop (i32.const 1)) + (drop (i32.const 2)) + (br $out) ) - (drop (i32.const 1)) - (drop (i32.const 2)) - (br $out) ) ) ;; no fallthrough, another thing to merge (block $x (if (i32.add (i32.const 0) (i32.const 1)) - (br $x) ;; this is ok - we branch to x which is nested in us + (then + (br $x) ;; this is ok - we branch to x which is nested in us + ) ) ) (drop (i32.const 1)) @@ -1176,19 +1494,27 @@ (func $if-suffix (param $x i32) (result i32) (if (local.get $x) - (local.set $x (i32.const 1)) - (block - (drop (call $if-suffix (i32.const -1))) + (then (local.set $x (i32.const 1)) ) + (else + (block + (drop (call $if-suffix (i32.const -1))) + (local.set $x (i32.const 1)) + ) + ) ) (if (result i32) (local.get $x) - (i32.const 2) - (block (result i32) - (drop (call $if-suffix (i32.const -2))) + (then (i32.const 2) ) + (else + (block (result i32) + (drop (call $if-suffix (i32.const -2))) + (i32.const 2) + ) + ) ) ) ) diff --git a/test/passes/remove-unused-names_merge-blocks_all-features.txt b/test/passes/remove-unused-names_merge-blocks_all-features.txt index ac7647507b7..05f27ea4c98 100644 --- a/test/passes/remove-unused-names_merge-blocks_all-features.txt +++ b/test/passes/remove-unused-names_merge-blocks_all-features.txt @@ -767,14 +767,16 @@ (local.get $0) (local.get $1) ) - (nop) + (then + (nop) + ) ) ) (func $do-reorder (type $i) (param $x i32) (local $y i32) (if (i32.const 1) - (block + (then (local.set $y (i32.const 5) ) @@ -791,14 +793,16 @@ (local $y i32) (if (i32.const 1) - (local.set $x - (i32.le_u - (local.get $y) - (block (result i32) - (local.set $y - (i32.const 5) + (then + (local.set $x + (i32.le_u + (local.get $y) + (block (result i32) + (local.set $y + (i32.const 5) + ) + (i32.const 10) ) - (i32.const 10) ) ) ) @@ -959,8 +963,10 @@ (block $l5 (if (i32.const 10) - (br_if $l5 - (i32.const 11) + (then + (br_if $l5 + (i32.const 11) + ) ) ) (drop @@ -1100,8 +1106,10 @@ (loop $l5 (if (i32.const 10) - (br_if $l5 - (i32.const 11) + (then + (br_if $l5 + (i32.const 11) + ) ) ) ) diff --git a/test/passes/remove-unused-names_merge-blocks_all-features.wast b/test/passes/remove-unused-names_merge-blocks_all-features.wast index 1063e246331..3a159abd91c 100644 --- a/test/passes/remove-unused-names_merge-blocks_all-features.wast +++ b/test/passes/remove-unused-names_merge-blocks_all-features.wast @@ -945,19 +945,23 @@ (local.get $1) ) ) - (nop) + (then + (nop) + ) ) ) (func $do-reorder (param $x i32) (local $y i32) (if (i32.const 1) - (block - (local.set $x - (i32.le_u - (local.get $x) - (block (result i32) - (local.set $y (i32.const 5)) - (i32.const 10) + (then + (block + (local.set $x + (i32.le_u + (local.get $x) + (block (result i32) + (local.set $y (i32.const 5)) + (i32.const 10) + ) ) ) ) @@ -967,13 +971,15 @@ (func $do-not-reorder (param $x i32) (local $y i32) (if (i32.const 1) - (block - (local.set $x - (i32.le_u - (local.get $y) - (block (result i32) - (local.set $y (i32.const 5)) - (i32.const 10) + (then + (block + (local.set $x + (i32.le_u + (local.get $y) + (block (result i32) + (local.set $y (i32.const 5)) + (i32.const 10) + ) ) ) ) @@ -1123,7 +1129,9 @@ ) (block $l5 (if (i32.const 10) - (br_if $l5 (i32.const 11)) + (then + (br_if $l5 (i32.const 11)) + ) ) (drop (i32.const 12)) ) @@ -1201,7 +1209,9 @@ ) (loop $l5 (if (i32.const 10) - (br_if $l5 (i32.const 11)) + (then + (br_if $l5 (i32.const 11)) + ) ) (drop (i32.const 12)) ) diff --git a/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt b/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt index a5e0c17ff22..2a157dcf98c 100644 --- a/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt +++ b/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt @@ -68,28 +68,38 @@ (local $var$8 i32) (if (local.get $var$4) - (block $label$3 - (block - (if - (local.get $var$8) - (loop $label$8 - (if - (local.get $var$3) - (br $label$8) - ) - ) + (then + (block $label$3 + (block (if - (i32.eqz - (local.get $var$6) + (local.get $var$8) + (then + (loop $label$8 + (if + (local.get $var$3) + (then + (br $label$8) + ) + ) + ) + ) + (else + (if + (i32.eqz + (local.get $var$6) + ) + (then + (br $label$3) + ) + ) ) - (br $label$3) ) - ) - (drop - (call $23 - (local.get $var$7) - (local.get $var$4) - (local.get $var$0) + (drop + (call $23 + (local.get $var$7) + (local.get $var$4) + (local.get $var$0) + ) ) ) ) diff --git a/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast b/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast index f1e1d6ad3d0..54d0fbdf98c 100644 --- a/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast +++ b/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast @@ -78,42 +78,56 @@ (block $label$3 (if (local.get $var$4) - (block $label$4 - (if - (local.get $var$8) - (block $label$7 - (loop $label$8 - (block $label$9 + (then + (block $label$4 + (if + (local.get $var$8) + (then + (block $label$7 + (loop $label$8 + (block $label$9 + (if + (local.get $var$3) + (then + (block $label$12 ;; these empty blocks must never be unreachable-typed + ) + ) + (else + (block $label$13 + (br $label$9) + ) + ) + ) + (br $label$8) + ) + ) + ) + ) + (else + (block $label$16 (if - (local.get $var$3) - (block $label$12 ;; these empty blocks must never be unreachable-typed + (local.get $var$6) + (then + (block $label$17 + ) ) - (block $label$13 - (br $label$9) + (else + (block $label$18 + (br $label$3) + ) ) ) - (br $label$8) ) ) ) - (block $label$16 - (if - (local.get $var$6) - (block $label$17 - ) - (block $label$18 - (br $label$3) - ) + (drop + (call $23 + (local.get $var$7) + (local.get $var$4) + (local.get $var$0) ) ) ) - (drop - (call $23 - (local.get $var$7) - (local.get $var$4) - (local.get $var$0) - ) - ) ) ) ) @@ -130,10 +144,14 @@ (i32.load8_s (i32.const 201460482) ) - (br $label$0) - (block $label$3 - (br_if $label$3 - (local.get $0) + (then + (br $label$0) + ) + (else + (block $label$3 + (br_if $label$3 + (local.get $0) + ) ) ) ) diff --git a/test/passes/remove-unused-names_vacuum_ignore-implicit-traps.wast b/test/passes/remove-unused-names_vacuum_ignore-implicit-traps.wast index 532fdc7c8d8..e6ccc84aaaa 100644 --- a/test/passes/remove-unused-names_vacuum_ignore-implicit-traps.wast +++ b/test/passes/remove-unused-names_vacuum_ignore-implicit-traps.wast @@ -27,18 +27,22 @@ (drop (if (result f64) (i32.const 1) - (block (result f64) - (nop) - (f64.load - (i32.const 19) + (then + (block (result f64) + (nop) + (f64.load + (i32.const 19) + ) ) ) - (block - (drop - (f64.const 1) + (else + (block + (drop + (f64.const 1) + ) + (br $label$1) + (nop) ) - (br $label$1) - (nop) ) ) ) diff --git a/test/passes/remove-unused-nonfunction-module-elements_all-features.txt b/test/passes/remove-unused-nonfunction-module-elements_all-features.txt index b54087b8176..88998c6ca3b 100644 --- a/test/passes/remove-unused-nonfunction-module-elements_all-features.txt +++ b/test/passes/remove-unused-nonfunction-module-elements_all-features.txt @@ -292,8 +292,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) @@ -306,11 +310,15 @@ (f64.const 1) (f64.const 1) ) - (call_indirect $0 (type $0) - (f64.const 1) - (i32.const 0) + (then + (call_indirect $0 (type $0) + (f64.const 1) + (i32.const 0) + ) + ) + (else + (f64.const 0) ) - (f64.const 0) ) ) ) @@ -324,8 +332,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) diff --git a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast index 942a20ee7e1..5ed444ca244 100644 --- a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast +++ b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast @@ -227,8 +227,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) @@ -241,8 +245,12 @@ (f64.const 1) (f64.const 1) ) - (call_indirect (type $0) (f64.const 1) (i32.const 0)) - (f64.const 0) + (then + (call_indirect (type $0) (f64.const 1) (i32.const 0)) + ) + (else + (f64.const 0) + ) ) ) ) @@ -256,8 +264,12 @@ (f64.const 1) (f64.const 1) ) - (f64.const 1) - (f64.const 0) + (then + (f64.const 1) + ) + (else + (f64.const 0) + ) ) ) ) diff --git a/test/passes/reverse_dwarf_abbrevs.bin.txt b/test/passes/reverse_dwarf_abbrevs.bin.txt index cbc04ac439b..2500b625b1b 100644 --- a/test/passes/reverse_dwarf_abbrevs.bin.txt +++ b/test/passes/reverse_dwarf_abbrevs.bin.txt @@ -175,10 +175,12 @@ file_names[ 1]: ;; code offset: 0x1d (local.get $0) ) - ;; code offset: 0x24 - (return - ;; code offset: 0x22 - (i32.const 0) + (then + ;; code offset: 0x24 + (return + ;; code offset: 0x22 + (i32.const 0) + ) ) ) ;; code offset: 0x2a @@ -325,177 +327,179 @@ file_names[ 1]: ) ) ) - ;; code offset: 0xa7 - (loop $label$5 - ;; code offset: 0xb3 - (br_if $label$3 - ;; code offset: 0xb2 - (i32.eq - ;; code offset: 0xa9 - (local.get $6) - ;; code offset: 0xb0 - (local.tee $4 - ;; code offset: 0xad - (i32.load offset=12 - ;; code offset: 0xab - (local.get $3) + (then + ;; code offset: 0xa7 + (loop $label$5 + ;; code offset: 0xb3 + (br_if $label$3 + ;; code offset: 0xb2 + (i32.eq + ;; code offset: 0xa9 + (local.get $6) + ;; code offset: 0xb0 + (local.tee $4 + ;; code offset: 0xad + (i32.load offset=12 + ;; code offset: 0xab + (local.get $3) + ) ) ) ) - ) - ;; code offset: 0xba - (br_if $label$2 - ;; code offset: 0xb9 - (i32.le_s - ;; code offset: 0xb5 - (local.get $4) - ;; code offset: 0xb7 - (i32.const -1) + ;; code offset: 0xba + (br_if $label$2 + ;; code offset: 0xb9 + (i32.le_s + ;; code offset: 0xb5 + (local.get $4) + ;; code offset: 0xb7 + (i32.const -1) + ) ) - ) - ;; code offset: 0xe2 - (i32.store - ;; code offset: 0xce - (local.tee $9 - ;; code offset: 0xcd - (i32.add - ;; code offset: 0xbc - (local.get $1) - ;; code offset: 0xcc - (i32.shl - ;; code offset: 0xc8 - (local.tee $5 - ;; code offset: 0xc7 - (i32.gt_u - ;; code offset: 0xbe - (local.get $4) - ;; code offset: 0xc5 - (local.tee $8 - ;; code offset: 0xc2 - (i32.load offset=4 - ;; code offset: 0xc0 - (local.get $1) + ;; code offset: 0xe2 + (i32.store + ;; code offset: 0xce + (local.tee $9 + ;; code offset: 0xcd + (i32.add + ;; code offset: 0xbc + (local.get $1) + ;; code offset: 0xcc + (i32.shl + ;; code offset: 0xc8 + (local.tee $5 + ;; code offset: 0xc7 + (i32.gt_u + ;; code offset: 0xbe + (local.get $4) + ;; code offset: 0xc5 + (local.tee $8 + ;; code offset: 0xc2 + (i32.load offset=4 + ;; code offset: 0xc0 + (local.get $1) + ) ) ) ) + ;; code offset: 0xca + (i32.const 3) + ) + ) + ) + ;; code offset: 0xe1 + (i32.add + ;; code offset: 0xda + (local.tee $8 + ;; code offset: 0xd9 + (i32.sub + ;; code offset: 0xd0 + (local.get $4) + ;; code offset: 0xd8 + (select + ;; code offset: 0xd2 + (local.get $8) + ;; code offset: 0xd4 + (i32.const 0) + ;; code offset: 0xd6 + (local.get $5) + ) ) - ;; code offset: 0xca - (i32.const 3) + ) + ;; code offset: 0xde + (i32.load + ;; code offset: 0xdc + (local.get $9) ) ) ) - ;; code offset: 0xe1 - (i32.add - ;; code offset: 0xda - (local.tee $8 - ;; code offset: 0xd9 - (i32.sub - ;; code offset: 0xd0 - (local.get $4) - ;; code offset: 0xd8 + ;; code offset: 0xf9 + (i32.store + ;; code offset: 0xef + (local.tee $9 + ;; code offset: 0xee + (i32.add + ;; code offset: 0xe5 + (local.get $1) + ;; code offset: 0xed (select - ;; code offset: 0xd2 - (local.get $8) - ;; code offset: 0xd4 - (i32.const 0) - ;; code offset: 0xd6 + ;; code offset: 0xe7 + (i32.const 12) + ;; code offset: 0xe9 + (i32.const 4) + ;; code offset: 0xeb (local.get $5) ) ) ) - ;; code offset: 0xde - (i32.load - ;; code offset: 0xdc - (local.get $9) - ) - ) - ) - ;; code offset: 0xf9 - (i32.store - ;; code offset: 0xef - (local.tee $9 - ;; code offset: 0xee - (i32.add - ;; code offset: 0xe5 - (local.get $1) - ;; code offset: 0xed - (select - ;; code offset: 0xe7 - (i32.const 12) - ;; code offset: 0xe9 - (i32.const 4) - ;; code offset: 0xeb - (local.get $5) + ;; code offset: 0xf8 + (i32.sub + ;; code offset: 0xf3 + (i32.load + ;; code offset: 0xf1 + (local.get $9) ) + ;; code offset: 0xf6 + (local.get $8) ) ) - ;; code offset: 0xf8 - (i32.sub - ;; code offset: 0xf3 - (i32.load - ;; code offset: 0xf1 - (local.get $9) + ;; code offset: 0x101 + (local.set $6 + ;; code offset: 0x100 + (i32.sub + ;; code offset: 0xfc + (local.get $6) + ;; code offset: 0xfe + (local.get $4) ) - ;; code offset: 0xf6 - (local.get $8) - ) - ) - ;; code offset: 0x101 - (local.set $6 - ;; code offset: 0x100 - (i32.sub - ;; code offset: 0xfc - (local.get $6) - ;; code offset: 0xfe - (local.get $4) ) - ) - ;; code offset: 0x125 - (br_if $label$5 - ;; code offset: 0x124 - (i32.eqz - ;; code offset: 0x122 - (call $4 - ;; code offset: 0x120 - (call $fimport$0 - ;; code offset: 0x105 - (i32.load offset=60 - ;; code offset: 0x103 - (local.get $0) - ) - ;; code offset: 0x112 - (local.tee $1 - ;; code offset: 0x111 - (select - ;; code offset: 0x10c - (i32.add - ;; code offset: 0x108 + ;; code offset: 0x125 + (br_if $label$5 + ;; code offset: 0x124 + (i32.eqz + ;; code offset: 0x122 + (call $4 + ;; code offset: 0x120 + (call $fimport$0 + ;; code offset: 0x105 + (i32.load offset=60 + ;; code offset: 0x103 + (local.get $0) + ) + ;; code offset: 0x112 + (local.tee $1 + ;; code offset: 0x111 + (select + ;; code offset: 0x10c + (i32.add + ;; code offset: 0x108 + (local.get $1) + ;; code offset: 0x10a + (i32.const 8) + ) + ;; code offset: 0x10d (local.get $1) - ;; code offset: 0x10a - (i32.const 8) + ;; code offset: 0x10f + (local.get $5) ) - ;; code offset: 0x10d - (local.get $1) - ;; code offset: 0x10f - (local.get $5) ) - ) - ;; code offset: 0x119 - (local.tee $7 - ;; code offset: 0x118 - (i32.sub - ;; code offset: 0x114 - (local.get $7) - ;; code offset: 0x116 - (local.get $5) + ;; code offset: 0x119 + (local.tee $7 + ;; code offset: 0x118 + (i32.sub + ;; code offset: 0x114 + (local.get $7) + ;; code offset: 0x116 + (local.get $5) + ) + ) + ;; code offset: 0x11f + (i32.add + ;; code offset: 0x11b + (local.get $3) + ;; code offset: 0x11d + (i32.const 12) ) - ) - ;; code offset: 0x11f - (i32.add - ;; code offset: 0x11b - (local.get $3) - ;; code offset: 0x11d - (i32.const 12) ) ) ) @@ -682,7 +686,7 @@ file_names[ 1]: ;; code offset: 0x1c0 (i32.const 8) ) - (block + (then ;; code offset: 0x1cc (i32.store ;; code offset: 0x1c5 @@ -760,7 +764,7 @@ file_names[ 1]: ;; code offset: 0x208 (i32.const 512) ) - (block + (then ;; code offset: 0x216 (drop ;; code offset: 0x214 @@ -809,7 +813,7 @@ file_names[ 1]: (i32.const 3) ) ) - (block + (then ;; code offset: 0x22f (block $label$4 ;; code offset: 0x236 @@ -821,7 +825,7 @@ file_names[ 1]: ;; code offset: 0x233 (i32.const 1) ) - (block + (then ;; code offset: 0x23a (local.set $2 ;; code offset: 0x238 @@ -843,7 +847,7 @@ file_names[ 1]: (i32.const 3) ) ) - (block + (then ;; code offset: 0x249 (local.set $2 ;; code offset: 0x247 @@ -1204,7 +1208,7 @@ file_names[ 1]: ;; code offset: 0x378 (i32.const 4) ) - (block + (then ;; code offset: 0x37f (local.set $2 ;; code offset: 0x37d @@ -1231,7 +1235,7 @@ file_names[ 1]: ;; code offset: 0x38b (local.get $0) ) - (block + (then ;; code offset: 0x392 (local.set $2 ;; code offset: 0x390 @@ -1327,44 +1331,46 @@ file_names[ 1]: ;; code offset: 0x3dc (local.get $3) ) - ;; code offset: 0x3e1 - (loop $label$15 - ;; code offset: 0x3ea - (i32.store8 - ;; code offset: 0x3e3 - (local.get $2) - ;; code offset: 0x3e7 - (i32.load8_u - ;; code offset: 0x3e5 - (local.get $1) + (then + ;; code offset: 0x3e1 + (loop $label$15 + ;; code offset: 0x3ea + (i32.store8 + ;; code offset: 0x3e3 + (local.get $2) + ;; code offset: 0x3e7 + (i32.load8_u + ;; code offset: 0x3e5 + (local.get $1) + ) ) - ) - ;; code offset: 0x3f2 - (local.set $1 - ;; code offset: 0x3f1 - (i32.add - ;; code offset: 0x3ed - (local.get $1) - ;; code offset: 0x3ef - (i32.const 1) + ;; code offset: 0x3f2 + (local.set $1 + ;; code offset: 0x3f1 + (i32.add + ;; code offset: 0x3ed + (local.get $1) + ;; code offset: 0x3ef + (i32.const 1) + ) ) - ) - ;; code offset: 0x3fe - (br_if $label$15 - ;; code offset: 0x3fd - (i32.ne - ;; code offset: 0x3f9 - (local.tee $2 - ;; code offset: 0x3f8 - (i32.add - ;; code offset: 0x3f4 - (local.get $2) - ;; code offset: 0x3f6 - (i32.const 1) + ;; code offset: 0x3fe + (br_if $label$15 + ;; code offset: 0x3fd + (i32.ne + ;; code offset: 0x3f9 + (local.tee $2 + ;; code offset: 0x3f8 + (i32.add + ;; code offset: 0x3f4 + (local.get $2) + ;; code offset: 0x3f6 + (i32.const 1) + ) ) + ;; code offset: 0x3fb + (local.get $3) ) - ;; code offset: 0x3fb - (local.get $3) ) ) ) @@ -1395,7 +1401,7 @@ file_names[ 1]: ) ) ) - (block + (then ;; code offset: 0x422 (br_if $label$1 ;; code offset: 0x420 @@ -1433,20 +1439,22 @@ file_names[ 1]: (local.get $1) ) ) - ;; code offset: 0x44a - (return - ;; code offset: 0x447 - (call_indirect (type $1) - ;; code offset: 0x43c - (local.get $2) - ;; code offset: 0x43e - (local.get $0) - ;; code offset: 0x440 - (local.get $1) - ;; code offset: 0x444 - (i32.load offset=36 - ;; code offset: 0x442 + (then + ;; code offset: 0x44a + (return + ;; code offset: 0x447 + (call_indirect (type $1) + ;; code offset: 0x43c (local.get $2) + ;; code offset: 0x43e + (local.get $0) + ;; code offset: 0x440 + (local.get $1) + ;; code offset: 0x444 + (i32.load offset=36 + ;; code offset: 0x442 + (local.get $2) + ) ) ) ) @@ -1638,7 +1646,7 @@ file_names[ 1]: ;; code offset: 0x4dc (i32.const -1) ) - (block + (then ;; code offset: 0x4e9 (local.set $0 ;; code offset: 0x4e7 @@ -1698,16 +1706,18 @@ file_names[ 1]: ;; code offset: 0x50a (local.get $4) ) - ;; code offset: 0x516 - (return - ;; code offset: 0x515 - (select - ;; code offset: 0x50f - (local.get $2) - ;; code offset: 0x511 - (i32.const 0) - ;; code offset: 0x513 - (local.get $1) + (then + ;; code offset: 0x516 + (return + ;; code offset: 0x515 + (select + ;; code offset: 0x50f + (local.get $2) + ;; code offset: 0x511 + (i32.const 0) + ;; code offset: 0x513 + (local.get $1) + ) ) ) ) @@ -1790,7 +1800,7 @@ file_names[ 1]: ) ) ) - (block + (then ;; code offset: 0x560 (local.set $2 ;; code offset: 0x55e @@ -1950,12 +1960,14 @@ file_names[ 1]: ;; code offset: 0x5df (i32.const 0) ) - ;; code offset: 0x5e8 - (local.set $2 - ;; code offset: 0x5e6 - (call $15 - ;; code offset: 0x5e4 - (local.get $1) + (then + ;; code offset: 0x5e8 + (local.set $2 + ;; code offset: 0x5e6 + (call $15 + ;; code offset: 0x5e4 + (local.get $1) + ) ) ) ) @@ -2060,10 +2072,12 @@ file_names[ 1]: (if ;; code offset: 0x638 (local.get $2) - ;; code offset: 0x63e - (call $16 - ;; code offset: 0x63c - (local.get $1) + (then + ;; code offset: 0x63e + (call $16 + ;; code offset: 0x63c + (local.get $1) + ) ) ) ;; code offset: 0x641 @@ -2112,10 +2126,12 @@ file_names[ 1]: (local.get $0) ) ) - ;; code offset: 0x670 - (return - ;; code offset: 0x66e - (i32.const 0) + (then + ;; code offset: 0x670 + (return + ;; code offset: 0x66e + (i32.const 0) + ) ) ) ;; code offset: 0x672 @@ -2215,14 +2231,16 @@ file_names[ 1]: (i32.const 255) ) ) - ;; code offset: 0x6c3 - (return - ;; code offset: 0x6c2 - (i32.sub - ;; code offset: 0x6be - (local.get $2) - ;; code offset: 0x6c0 - (local.get $0) + (then + ;; code offset: 0x6c3 + (return + ;; code offset: 0x6c2 + (i32.sub + ;; code offset: 0x6be + (local.get $2) + ;; code offset: 0x6c0 + (local.get $0) + ) ) ) ) diff --git a/test/passes/roundtrip_signed.bin.txt b/test/passes/roundtrip_signed.bin.txt index ea3fb8646b7..686a35260a5 100644 --- a/test/passes/roundtrip_signed.bin.txt +++ b/test/passes/roundtrip_signed.bin.txt @@ -9,7 +9,9 @@ (i32.eqz (global.get $global$0) ) - (return) + (then + (return) + ) ) (global.set $global$0 (i32.sub diff --git a/test/passes/rse_all-features.txt b/test/passes/rse_all-features.txt index 33032d47bb2..acc037290b7 100644 --- a/test/passes/rse_all-features.txt +++ b/test/passes/rse_all-features.txt @@ -118,11 +118,15 @@ (local $x i32) (if (i32.const 0) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) - (local.set $x - (i32.const 1) + (else + (local.set $x + (i32.const 1) + ) ) ) (drop @@ -135,11 +139,15 @@ (local.tee $x (i32.const 1) ) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (drop - (i32.const 1) + (else + (drop + (i32.const 1) + ) ) ) (drop @@ -152,11 +160,15 @@ (local.tee $x (i32.const 1) ) - (drop - (i32.const 1) + (then + (drop + (i32.const 1) + ) ) - (local.set $x - (i32.const 2) + (else + (local.set $x + (i32.const 2) + ) ) ) (local.set $x @@ -180,8 +192,12 @@ ) (if (i32.const 1) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (local.set $y (local.get $x) @@ -191,8 +207,12 @@ ) (if (i32.const 1) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (drop (i32.const 2) @@ -259,8 +279,12 @@ ) (if (i32.const 1) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (local.set $y (local.get $x) @@ -278,8 +302,12 @@ ) (if (i32.const 1) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (drop (local.get $x) @@ -310,11 +338,15 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) - (local.set $x - (i32.const 1) + (else + (local.set $x + (i32.const 1) + ) ) ) (drop @@ -347,9 +379,13 @@ ) (if (i32.const 1) - (nop) - (drop - (local.get $1) + (then + (nop) + ) + (else + (drop + (local.get $1) + ) ) ) ) @@ -359,8 +395,10 @@ ) (if (i32.const 1) - (drop - (local.get $1) + (then + (drop + (local.get $1) + ) ) ) ) @@ -388,8 +426,10 @@ ) (if (i32.const 0) - (drop - (local.get $0) + (then + (drop + (local.get $0) + ) ) ) ) @@ -399,7 +439,7 @@ (block $label$5 (if (i32.const 1) - (block + (then (local.set $x (i32.const 203) ) @@ -415,10 +455,16 @@ (if (if (result i32) (i32.const 3) - (i32.const 4) - (i32.const 5) + (then + (i32.const 4) + ) + (else + (i32.const 5) + ) + ) + (then + (br $label$7) ) - (br $label$7) ) ) ) @@ -426,10 +472,14 @@ (local $var$1 i32) (if (i32.const 0) - (if - (i32.const 1) - (local.set $var$1 - (i32.const 2) + (then + (if + (i32.const 1) + (then + (local.set $var$1 + (i32.const 2) + ) + ) ) ) ) @@ -437,8 +487,10 @@ (block $label$11 (if (i32.const 5) - (br_if $label$11 - (i32.const 6) + (then + (br_if $label$11 + (i32.const 6) + ) ) ) (br $label$10) @@ -469,8 +521,10 @@ ) (if (i32.const 0) - (drop - (local.get $0) + (then + (drop + (local.get $0) + ) ) ) ) diff --git a/test/passes/rse_all-features.wast b/test/passes/rse_all-features.wast index 7ac7a057935..6e08a1c94e5 100644 --- a/test/passes/rse_all-features.wast +++ b/test/passes/rse_all-features.wast @@ -59,24 +59,36 @@ (func $if (local $x i32) (if (local.tee $x (i32.const 0)) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 1)) + ) ) (local.set $x (i32.const 1)) ) (func $if2 (local $x i32) (if (local.tee $x (i32.const 1)) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 1)) + ) ) (local.set $x (i32.const 1)) ) (func $if3 (local $x i32) (if (local.tee $x (i32.const 1)) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 2)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 2)) + ) ) (local.set $x (i32.const 1)) ) @@ -87,10 +99,10 @@ (local.set $y (local.get $x)) (local.set $y (i32.const 1)) (local.set $x (i32.const 2)) - (if (i32.const 1) (nop) (nop)) ;; control flow + (if (i32.const 1) (then (nop) )(else (nop))) ;; control flow (local.set $y (local.get $x)) (local.set $y (i32.const 2)) - (if (i32.const 1) (nop) (nop)) ;; control flow + (if (i32.const 1) (then (nop) )(else (nop))) ;; control flow (local.set $y (i32.const 2)) ;; flip (local.set $x (i32.const 3)) @@ -116,12 +128,12 @@ (local.set $y (local.get $x)) (local.set $y (local.get $x)) (local.set $x (i32.eqz (i32.const 789))) - (if (i32.const 1) (nop) (nop)) ;; control flow + (if (i32.const 1) (then (nop) )(else (nop))) ;; control flow (local.set $y (local.get $x)) (local.set $y (local.get $x)) (local.set $x (i32.eqz (i32.const 1000))) (local.set $y (local.get $x)) - (if (i32.const 1) (nop) (nop)) ;; control flow + (if (i32.const 1) (then (nop) )(else (nop))) ;; control flow (local.set $y (local.get $x)) ) (func $identical_complex (param $x i32) @@ -136,8 +148,12 @@ (func $merge (local $x i32) (if (i32.const 1) - (local.set $x (i32.const 1)) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) + (else + (local.set $x (i32.const 1)) + ) ) (local.set $x (i32.const 1)) (local.set $x (i32.const 2)) @@ -157,9 +173,13 @@ ) (if (i32.const 1) - (nop) - (local.set $3 - (local.get $1) + (then + (nop) + ) + (else + (local.set $3 + (local.get $1) + ) ) ) ) @@ -171,8 +191,10 @@ ) (if (i32.const 1) - (local.set $3 - (local.get $1) + (then + (local.set $3 + (local.get $1) + ) ) ) ) @@ -200,8 +222,10 @@ ) (if (i32.const 0) - (local.set $1 ;; we can drop this - (local.get $0) + (then + (local.set $1 ;; we can drop this + (local.get $0) + ) ) ) ) @@ -211,11 +235,13 @@ (block $label$5 (if (i32.const 1) - (block - (local.set $x - (i32.const 203) + (then + (block + (local.set $x + (i32.const 203) + ) + (br $label$5) ) - (br $label$5) ) ) (br_if $label$4 @@ -227,10 +253,16 @@ (if (if (result i32) (i32.const 3) - (i32.const 4) - (i32.const 5) + (then + (i32.const 4) + ) + (else + (i32.const 5) + ) + ) + (then + (br $label$7) ) - (br $label$7) ) ) ) @@ -238,10 +270,14 @@ (local $var$1 i32) (if (i32.const 0) - (if - (i32.const 1) - (local.set $var$1 - (i32.const 2) + (then + (if + (i32.const 1) + (then + (local.set $var$1 + (i32.const 2) + ) + ) ) ) ) @@ -249,8 +285,10 @@ (block $label$11 (if (i32.const 5) - (br_if $label$11 - (i32.const 6) + (then + (br_if $label$11 + (i32.const 6) + ) ) ) (br $label$10) @@ -281,8 +319,10 @@ ) (if (i32.const 0) - (local.set $1 ;; we can drop this - (local.get $0) + (then + (local.set $1 ;; we can drop this + (local.get $0) + ) ) ) ) diff --git a/test/passes/safe-heap_disable-simd.txt b/test/passes/safe-heap_disable-simd.txt index a678bc0dcf4..bb55667b1cb 100644 --- a/test/passes/safe-heap_disable-simd.txt +++ b/test/passes/safe-heap_disable-simd.txt @@ -37,7 +37,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -67,7 +69,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -97,7 +101,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -127,14 +133,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -164,7 +174,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -194,14 +206,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -231,7 +247,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -261,14 +279,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -298,14 +320,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -335,7 +361,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -365,7 +393,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -395,7 +425,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -425,14 +457,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -462,7 +498,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -492,14 +530,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -529,7 +571,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -559,14 +603,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -596,14 +644,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -633,7 +685,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -663,14 +717,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -700,14 +758,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -737,7 +799,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -767,14 +831,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -804,14 +872,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -841,14 +913,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -878,7 +954,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -908,14 +986,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -945,14 +1027,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -982,7 +1068,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -1012,14 +1100,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -1049,14 +1141,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -1086,14 +1182,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -1123,7 +1223,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -1154,7 +1256,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -1185,14 +1289,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -1223,7 +1331,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -1254,14 +1364,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -1292,14 +1406,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -1330,7 +1448,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -1361,7 +1481,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -1392,14 +1514,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -1430,7 +1556,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -1461,14 +1589,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -1499,14 +1631,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -1537,7 +1673,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -1568,14 +1706,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -1606,14 +1748,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -1644,14 +1790,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -1682,7 +1832,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -1713,14 +1865,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -1751,14 +1907,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -1789,7 +1949,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -1820,14 +1982,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -1858,14 +2024,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -1896,14 +2066,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -1950,7 +2124,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -1980,7 +2156,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -2010,7 +2188,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -2040,14 +2220,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -2077,7 +2261,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -2107,14 +2293,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -2144,7 +2334,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -2174,14 +2366,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -2211,14 +2407,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -2248,7 +2448,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -2278,7 +2480,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -2308,7 +2512,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -2338,14 +2544,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -2375,7 +2585,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -2405,14 +2617,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -2442,7 +2658,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -2472,14 +2690,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -2509,14 +2731,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -2546,7 +2772,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -2576,14 +2804,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -2613,14 +2845,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -2650,7 +2886,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -2680,14 +2918,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -2717,14 +2959,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -2754,14 +3000,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -2791,7 +3041,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -2821,14 +3073,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -2858,14 +3114,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -2895,7 +3155,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -2925,14 +3187,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -2962,14 +3228,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -2999,14 +3269,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -3036,7 +3310,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -3067,7 +3343,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -3098,14 +3376,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -3136,7 +3418,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -3167,14 +3451,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -3205,14 +3493,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -3243,7 +3535,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -3274,7 +3568,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -3305,14 +3601,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -3343,7 +3643,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -3374,14 +3676,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -3412,14 +3718,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -3450,7 +3760,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -3481,14 +3793,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -3519,14 +3835,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -3557,14 +3877,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -3595,7 +3919,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -3626,14 +3952,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -3664,14 +3994,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -3702,7 +4036,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -3733,14 +4069,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -3771,14 +4111,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -3809,14 +4153,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -3871,7 +4219,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -3901,7 +4251,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -3931,7 +4283,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -3961,14 +4315,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -3998,7 +4356,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -4028,14 +4388,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -4065,7 +4429,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -4095,14 +4461,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -4132,14 +4502,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -4169,7 +4543,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -4199,7 +4575,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -4229,7 +4607,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -4259,14 +4639,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -4296,7 +4680,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -4326,14 +4712,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -4363,7 +4753,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -4393,14 +4785,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -4430,14 +4826,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -4467,7 +4867,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -4497,14 +4899,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -4534,14 +4940,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -4571,7 +4981,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -4601,14 +5013,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -4638,14 +5054,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -4675,14 +5095,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -4712,7 +5136,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -4742,14 +5168,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -4779,14 +5209,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -4816,7 +5250,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -4846,14 +5282,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -4883,14 +5323,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -4920,14 +5364,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -4957,7 +5405,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -4988,7 +5438,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -5019,14 +5471,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -5057,7 +5513,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -5088,14 +5546,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -5126,14 +5588,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -5164,7 +5630,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -5195,7 +5663,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -5226,14 +5696,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -5264,7 +5738,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -5295,14 +5771,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -5333,14 +5813,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -5371,7 +5855,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -5402,14 +5888,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -5440,14 +5930,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -5478,14 +5972,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -5516,7 +6014,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -5547,14 +6047,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -5585,14 +6089,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -5623,7 +6131,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -5654,14 +6164,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -5692,14 +6206,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -5730,14 +6248,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) diff --git a/test/passes/safe-heap_enable-threads_enable-simd.txt b/test/passes/safe-heap_enable-threads_enable-simd.txt index c1f8110077c..aeea4f02cd0 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd.txt @@ -208,7 +208,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -244,7 +246,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -274,7 +278,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -304,7 +310,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -334,7 +342,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -364,14 +374,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -407,14 +421,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -444,7 +462,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -474,14 +494,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -511,14 +535,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -548,7 +576,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -578,14 +608,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -615,14 +649,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -652,14 +690,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -689,7 +731,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -725,7 +769,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -755,7 +801,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -785,7 +833,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -815,7 +865,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -845,14 +897,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -888,14 +944,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -925,7 +985,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -955,14 +1017,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -992,14 +1058,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -1029,7 +1099,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -1059,14 +1131,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -1096,14 +1172,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -1139,14 +1219,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -1176,7 +1260,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -1206,14 +1292,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -1243,14 +1333,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -1280,14 +1374,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -1317,7 +1415,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -1347,14 +1447,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -1384,14 +1488,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -1421,14 +1529,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -1458,14 +1570,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -1495,7 +1611,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -1525,14 +1643,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -1562,14 +1684,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -1599,7 +1725,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -1629,14 +1757,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -1666,14 +1798,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -1703,14 +1839,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -1740,7 +1880,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -1770,14 +1912,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -1807,14 +1953,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -1844,14 +1994,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -1881,14 +2035,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -1918,7 +2076,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -1949,7 +2109,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -1980,7 +2142,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -2011,14 +2175,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -2049,14 +2217,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -2087,7 +2259,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -2118,14 +2292,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -2156,14 +2334,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -2194,14 +2376,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -2232,7 +2418,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -2263,7 +2451,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -2294,7 +2484,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -2325,14 +2517,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -2363,14 +2559,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -2401,7 +2601,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -2432,14 +2634,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -2470,14 +2676,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -2508,14 +2718,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -2546,7 +2760,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -2577,14 +2793,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -2615,14 +2835,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -2653,14 +2877,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -2691,14 +2919,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -2729,7 +2961,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -2760,14 +2994,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -2798,14 +3036,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -2836,7 +3078,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -2867,14 +3111,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -2905,14 +3153,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -2943,14 +3195,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -2981,7 +3237,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -3012,14 +3270,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -3050,14 +3312,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -3088,14 +3354,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -3126,14 +3396,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -3190,7 +3464,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -3220,7 +3496,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -3250,7 +3528,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -3280,14 +3560,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -3317,7 +3601,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -3347,14 +3633,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -3384,7 +3674,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -3414,14 +3706,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -3451,14 +3747,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -3488,7 +3788,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -3518,7 +3820,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -3548,7 +3852,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -3578,14 +3884,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -3615,7 +3925,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -3645,14 +3957,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -3682,7 +3998,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -3712,14 +4030,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -3749,14 +4071,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -3786,7 +4112,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -3816,14 +4144,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -3853,14 +4185,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -3890,7 +4226,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -3920,14 +4258,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -3957,14 +4299,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -3994,14 +4340,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -4031,7 +4381,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -4061,14 +4413,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -4098,14 +4454,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -4135,7 +4495,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -4165,14 +4527,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -4202,14 +4568,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -4239,14 +4609,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -4276,7 +4650,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -4306,14 +4682,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -4343,14 +4723,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -4380,14 +4764,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -4417,14 +4805,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -4454,7 +4846,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -4485,7 +4879,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -4516,14 +4912,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -4554,7 +4954,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -4585,14 +4987,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -4623,14 +5029,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -4661,7 +5071,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -4692,7 +5104,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -4723,14 +5137,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -4761,7 +5179,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -4792,14 +5212,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -4830,14 +5254,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -4868,7 +5296,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -4899,14 +5329,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -4937,14 +5371,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -4975,14 +5413,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -5013,7 +5455,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -5044,14 +5488,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -5082,14 +5530,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -5120,7 +5572,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -5151,14 +5605,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -5189,14 +5647,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -5227,14 +5689,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -5265,7 +5731,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -5296,14 +5764,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -5334,14 +5806,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -5372,14 +5848,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -5410,14 +5890,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -5479,7 +5963,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -5515,7 +6001,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -5545,7 +6033,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -5575,7 +6065,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -5605,7 +6097,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -5635,14 +6129,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -5678,14 +6176,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -5715,7 +6217,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -5745,14 +6249,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -5782,14 +6290,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -5819,7 +6331,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -5849,14 +6363,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -5886,14 +6404,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -5923,14 +6445,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -5960,7 +6486,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -5996,7 +6524,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -6026,7 +6556,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -6056,7 +6588,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -6086,7 +6620,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -6116,14 +6652,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6159,14 +6699,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -6196,7 +6740,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -6226,14 +6772,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -6263,14 +6813,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -6300,7 +6854,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -6330,14 +6886,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -6367,14 +6927,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6410,14 +6974,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -6447,7 +7015,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -6477,14 +7047,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -6514,14 +7088,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -6551,14 +7129,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -6588,7 +7170,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -6618,14 +7202,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -6655,14 +7243,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -6692,14 +7284,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -6729,14 +7325,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -6766,7 +7366,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -6796,14 +7398,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -6833,14 +7439,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -6870,7 +7480,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -6900,14 +7512,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -6937,14 +7553,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -6974,14 +7594,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -7011,7 +7635,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -7041,14 +7667,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -7078,14 +7708,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -7115,14 +7749,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -7152,14 +7790,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -7189,7 +7831,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -7220,7 +7864,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -7251,7 +7897,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -7282,14 +7930,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -7320,14 +7972,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -7358,7 +8014,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -7389,14 +8047,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -7427,14 +8089,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -7465,14 +8131,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -7503,7 +8173,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -7534,7 +8206,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -7565,7 +8239,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -7596,14 +8272,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -7634,14 +8314,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -7672,7 +8356,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -7703,14 +8389,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -7741,14 +8431,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -7779,14 +8473,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -7817,7 +8515,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -7848,14 +8548,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -7886,14 +8590,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -7924,14 +8632,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -7962,14 +8674,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -8000,7 +8716,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -8031,14 +8749,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -8069,14 +8791,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -8107,7 +8833,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -8138,14 +8866,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -8176,14 +8908,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -8214,14 +8950,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -8252,7 +8992,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -8283,14 +9025,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -8321,14 +9067,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -8359,14 +9109,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -8397,14 +9151,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) diff --git a/test/passes/safe-heap_enable-threads_enable-simd64.txt b/test/passes/safe-heap_enable-threads_enable-simd64.txt index 49319377e44..c76b664d53d 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd64.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd64.txt @@ -208,7 +208,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -244,7 +246,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -274,7 +278,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -304,7 +310,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -334,7 +342,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -364,7 +374,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -373,7 +385,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -409,7 +423,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -418,7 +434,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -448,7 +466,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -478,7 +498,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -487,7 +509,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -517,7 +541,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -526,7 +552,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -556,7 +584,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -586,7 +616,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -595,7 +627,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -625,7 +659,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -634,7 +670,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -664,7 +702,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -673,7 +713,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -703,7 +745,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -739,7 +783,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -769,7 +815,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -799,7 +847,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -829,7 +879,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -859,7 +911,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -868,7 +922,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -904,7 +960,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -913,7 +971,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -943,7 +1003,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -973,7 +1035,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -982,7 +1046,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -1012,7 +1078,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1021,7 +1089,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -1051,7 +1121,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -1081,7 +1153,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1090,7 +1164,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -1120,7 +1196,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1129,7 +1207,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -1165,7 +1245,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1174,7 +1256,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -1204,7 +1288,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -1234,7 +1320,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1243,7 +1331,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -1273,7 +1363,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1282,7 +1374,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -1312,7 +1406,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1321,7 +1417,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -1351,7 +1449,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -1381,7 +1481,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1390,7 +1492,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -1420,7 +1524,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1429,7 +1535,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -1459,7 +1567,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1468,7 +1578,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -1498,7 +1610,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1507,7 +1621,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -1537,7 +1653,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -1567,7 +1685,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1576,7 +1696,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -1606,7 +1728,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1615,7 +1739,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -1645,7 +1771,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -1675,7 +1803,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1684,7 +1814,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -1714,7 +1846,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1723,7 +1857,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -1753,7 +1889,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1762,7 +1900,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -1792,7 +1932,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -1822,7 +1964,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1831,7 +1975,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -1861,7 +2007,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1870,7 +2018,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -1900,7 +2050,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1909,7 +2061,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -1939,7 +2093,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -1948,7 +2104,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -1978,7 +2136,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -2009,7 +2169,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -2040,7 +2202,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -2071,7 +2235,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2080,7 +2246,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -2111,7 +2279,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2120,7 +2290,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -2151,7 +2323,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -2182,7 +2356,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2191,7 +2367,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -2222,7 +2400,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2231,7 +2411,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -2262,7 +2444,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2271,7 +2455,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -2302,7 +2488,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -2333,7 +2521,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -2364,7 +2554,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -2395,7 +2587,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2404,7 +2598,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -2435,7 +2631,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2444,7 +2642,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -2475,7 +2675,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -2506,7 +2708,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2515,7 +2719,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -2546,7 +2752,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2555,7 +2763,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -2586,7 +2796,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2595,7 +2807,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -2626,7 +2840,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -2657,7 +2873,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2666,7 +2884,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -2697,7 +2917,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2706,7 +2928,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -2737,7 +2961,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2746,7 +2972,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -2777,7 +3005,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2786,7 +3016,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -2817,7 +3049,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -2848,7 +3082,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2857,7 +3093,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -2888,7 +3126,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2897,7 +3137,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -2928,7 +3170,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -2959,7 +3203,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -2968,7 +3214,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -2999,7 +3247,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3008,7 +3258,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -3039,7 +3291,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3048,7 +3302,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -3079,7 +3335,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -3110,7 +3368,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3119,7 +3379,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -3150,7 +3412,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3159,7 +3423,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -3190,7 +3456,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3199,7 +3467,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -3230,7 +3500,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3239,7 +3511,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -3296,7 +3570,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -3326,7 +3602,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -3356,7 +3634,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -3386,7 +3666,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3395,7 +3677,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -3425,7 +3709,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -3455,7 +3741,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3464,7 +3752,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -3494,7 +3784,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -3524,7 +3816,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3533,7 +3827,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -3563,7 +3859,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3572,7 +3870,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -3602,7 +3902,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -3632,7 +3934,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -3662,7 +3966,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -3692,7 +3998,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3701,7 +4009,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -3731,7 +4041,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -3761,7 +4073,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3770,7 +4084,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -3800,7 +4116,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -3830,7 +4148,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3839,7 +4159,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -3869,7 +4191,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3878,7 +4202,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -3908,7 +4234,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -3938,7 +4266,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3947,7 +4277,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -3977,7 +4309,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -3986,7 +4320,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -4016,7 +4352,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -4046,7 +4384,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4055,7 +4395,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -4085,7 +4427,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4094,7 +4438,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -4124,7 +4470,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4133,7 +4481,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -4163,7 +4513,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -4193,7 +4545,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4202,7 +4556,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -4232,7 +4588,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4241,7 +4599,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -4271,7 +4631,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -4301,7 +4663,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4310,7 +4674,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -4340,7 +4706,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4349,7 +4717,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -4379,7 +4749,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4388,7 +4760,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -4418,7 +4792,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -4448,7 +4824,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4457,7 +4835,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -4487,7 +4867,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4496,7 +4878,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -4526,7 +4910,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4535,7 +4921,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -4565,7 +4953,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4574,7 +4964,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -4604,7 +4996,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -4635,7 +5029,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -4666,7 +5062,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4675,7 +5073,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -4706,7 +5106,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -4737,7 +5139,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4746,7 +5150,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -4777,7 +5183,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4786,7 +5194,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -4817,7 +5227,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -4848,7 +5260,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -4879,7 +5293,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4888,7 +5304,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -4919,7 +5337,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -4950,7 +5370,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4959,7 +5381,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -4990,7 +5414,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -4999,7 +5425,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -5030,7 +5458,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -5061,7 +5491,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5070,7 +5502,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -5101,7 +5535,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5110,7 +5546,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -5141,7 +5579,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5150,7 +5590,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -5181,7 +5623,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -5212,7 +5656,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5221,7 +5667,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -5252,7 +5700,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5261,7 +5711,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -5292,7 +5744,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -5323,7 +5777,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5332,7 +5788,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -5363,7 +5821,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5372,7 +5832,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -5403,7 +5865,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5412,7 +5876,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -5443,7 +5909,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -5474,7 +5942,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5483,7 +5953,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -5514,7 +5986,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5523,7 +5997,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -5554,7 +6030,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5563,7 +6041,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -5594,7 +6074,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5603,7 +6085,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -5665,7 +6149,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -5701,7 +6187,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -5731,7 +6219,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -5761,7 +6251,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -5791,7 +6283,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -5821,7 +6315,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5830,7 +6326,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -5866,7 +6364,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5875,7 +6375,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -5905,7 +6407,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -5935,7 +6439,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5944,7 +6450,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -5974,7 +6482,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -5983,7 +6493,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -6013,7 +6525,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -6043,7 +6557,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6052,7 +6568,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -6082,7 +6600,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6091,7 +6611,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -6121,7 +6643,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6130,7 +6654,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -6160,7 +6686,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -6196,7 +6724,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -6226,7 +6756,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -6256,7 +6788,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -6286,7 +6820,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -6316,7 +6852,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6325,7 +6863,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6361,7 +6901,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6370,7 +6912,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -6400,7 +6944,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -6430,7 +6976,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6439,7 +6987,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -6469,7 +7019,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6478,7 +7030,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -6508,7 +7062,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -6538,7 +7094,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6547,7 +7105,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -6577,7 +7137,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6586,7 +7148,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6622,7 +7186,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6631,7 +7197,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -6661,7 +7229,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -6691,7 +7261,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6700,7 +7272,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -6730,7 +7304,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6739,7 +7315,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -6769,7 +7347,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6778,7 +7358,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -6808,7 +7390,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -6838,7 +7422,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6847,7 +7433,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -6877,7 +7465,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6886,7 +7476,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -6916,7 +7508,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6925,7 +7519,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -6955,7 +7551,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -6964,7 +7562,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -6994,7 +7594,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -7024,7 +7626,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7033,7 +7637,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -7063,7 +7669,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7072,7 +7680,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -7102,7 +7712,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -7132,7 +7744,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7141,7 +7755,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -7171,7 +7787,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7180,7 +7798,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -7210,7 +7830,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7219,7 +7841,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -7249,7 +7873,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -7279,7 +7905,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7288,7 +7916,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -7318,7 +7948,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7327,7 +7959,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -7357,7 +7991,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7366,7 +8002,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -7396,7 +8034,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7405,7 +8045,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -7435,7 +8077,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -7466,7 +8110,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -7497,7 +8143,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -7528,7 +8176,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7537,7 +8187,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -7568,7 +8220,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7577,7 +8231,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -7608,7 +8264,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -7639,7 +8297,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7648,7 +8308,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -7679,7 +8341,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7688,7 +8352,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -7719,7 +8385,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7728,7 +8396,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -7759,7 +8429,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -7790,7 +8462,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -7821,7 +8495,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -7852,7 +8528,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7861,7 +8539,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -7892,7 +8572,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7901,7 +8583,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -7932,7 +8616,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -7963,7 +8649,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -7972,7 +8660,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -8003,7 +8693,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8012,7 +8704,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -8043,7 +8737,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8052,7 +8748,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -8083,7 +8781,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -8114,7 +8814,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8123,7 +8825,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -8154,7 +8858,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8163,7 +8869,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -8194,7 +8902,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8203,7 +8913,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -8234,7 +8946,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8243,7 +8957,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -8274,7 +8990,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -8305,7 +9023,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8314,7 +9034,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -8345,7 +9067,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8354,7 +9078,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -8385,7 +9111,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -8416,7 +9144,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8425,7 +9155,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -8456,7 +9188,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8465,7 +9199,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -8496,7 +9232,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8505,7 +9243,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -8536,7 +9276,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -8567,7 +9309,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8576,7 +9320,9 @@ ) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -8607,7 +9353,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8616,7 +9364,9 @@ ) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -8647,7 +9397,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8656,7 +9408,9 @@ ) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -8687,7 +9441,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and @@ -8696,7 +9452,9 @@ ) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) diff --git a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt index 53b048331a7..02904abadeb 100644 --- a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt @@ -208,7 +208,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -244,7 +246,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -274,7 +278,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -304,7 +310,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -334,7 +342,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -364,14 +374,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -407,14 +421,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -444,7 +462,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -474,14 +494,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -511,14 +535,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -548,7 +576,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -578,14 +608,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -615,14 +649,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -652,14 +690,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -689,7 +731,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -725,7 +769,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -755,7 +801,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -785,7 +833,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -815,7 +865,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -845,14 +897,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -888,14 +944,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -925,7 +985,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -955,14 +1017,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -992,14 +1058,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -1029,7 +1099,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -1059,14 +1131,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -1096,14 +1172,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -1139,14 +1219,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -1176,7 +1260,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -1206,14 +1292,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -1243,14 +1333,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -1280,14 +1374,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -1317,7 +1415,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -1347,14 +1447,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -1384,14 +1488,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -1421,14 +1529,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -1458,14 +1570,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -1495,7 +1611,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -1525,14 +1643,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -1562,14 +1684,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -1599,7 +1725,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -1629,14 +1757,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -1666,14 +1798,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -1703,14 +1839,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -1740,7 +1880,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -1770,14 +1912,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -1807,14 +1953,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -1844,14 +1994,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -1881,14 +2035,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -1918,7 +2076,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -1949,7 +2109,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -1980,7 +2142,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -2011,14 +2175,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -2049,14 +2217,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -2087,7 +2259,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -2118,14 +2292,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -2156,14 +2334,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -2194,14 +2376,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -2232,7 +2418,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -2263,7 +2451,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -2294,7 +2484,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -2325,14 +2517,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -2363,14 +2559,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -2401,7 +2601,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -2432,14 +2634,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -2470,14 +2676,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -2508,14 +2718,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -2546,7 +2760,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -2577,14 +2793,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -2615,14 +2835,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -2653,14 +2877,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -2691,14 +2919,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -2729,7 +2961,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -2760,14 +2994,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -2798,14 +3036,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -2836,7 +3078,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -2867,14 +3111,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -2905,14 +3153,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -2943,14 +3195,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -2981,7 +3237,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -3012,14 +3270,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -3050,14 +3312,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -3088,14 +3354,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -3126,14 +3396,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -3190,7 +3464,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -3220,7 +3496,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -3250,7 +3528,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -3280,14 +3560,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -3317,7 +3601,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -3347,14 +3633,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -3384,7 +3674,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -3414,14 +3706,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -3451,14 +3747,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -3488,7 +3788,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -3518,7 +3820,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -3548,7 +3852,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -3578,14 +3884,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -3615,7 +3925,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -3645,14 +3957,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -3682,7 +3998,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -3712,14 +4030,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -3749,14 +4071,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -3786,7 +4112,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -3816,14 +4144,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -3853,14 +4185,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -3890,7 +4226,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -3920,14 +4258,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -3957,14 +4299,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -3994,14 +4340,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -4031,7 +4381,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -4061,14 +4413,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -4098,14 +4454,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -4135,7 +4495,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -4165,14 +4527,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -4202,14 +4568,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -4239,14 +4609,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -4276,7 +4650,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -4306,14 +4682,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -4343,14 +4723,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -4380,14 +4764,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -4417,14 +4805,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -4454,7 +4846,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -4485,7 +4879,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -4516,14 +4912,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -4554,7 +4954,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -4585,14 +4987,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -4623,14 +5029,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -4661,7 +5071,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -4692,7 +5104,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -4723,14 +5137,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -4761,7 +5179,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -4792,14 +5212,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -4830,14 +5254,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -4868,7 +5296,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -4899,14 +5329,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -4937,14 +5371,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -4975,14 +5413,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -5013,7 +5455,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -5044,14 +5488,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -5082,14 +5530,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -5120,7 +5572,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -5151,14 +5605,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -5189,14 +5647,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -5227,14 +5689,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -5265,7 +5731,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -5296,14 +5764,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -5334,14 +5806,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -5372,14 +5848,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -5410,14 +5890,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) @@ -5479,7 +5963,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.shr_s (i32.shl @@ -5515,7 +6001,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -5545,7 +6033,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.load8_u (local.get $2) @@ -5575,7 +6065,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -5605,7 +6097,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -5635,14 +6129,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.shr_s (i32.shl @@ -5678,14 +6176,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -5715,7 +6217,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -5745,14 +6249,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load16_u (local.get $2) @@ -5782,14 +6290,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -5819,7 +6331,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -5849,14 +6363,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -5886,14 +6404,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.load (local.get $2) @@ -5923,14 +6445,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -5960,7 +6486,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.shr_s (i64.shl @@ -5996,7 +6524,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -6026,7 +6556,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.load8_u (local.get $2) @@ -6056,7 +6588,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -6086,7 +6620,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -6116,14 +6652,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6159,14 +6699,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -6196,7 +6740,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -6226,14 +6772,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load16_u (local.get $2) @@ -6263,14 +6813,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -6300,7 +6854,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -6330,14 +6886,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -6367,14 +6927,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.shr_s (i64.shl @@ -6410,14 +6974,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -6447,7 +7015,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -6477,14 +7047,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -6514,14 +7088,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load32_u (local.get $2) @@ -6551,14 +7129,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -6588,7 +7170,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -6618,14 +7202,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -6655,14 +7243,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -6692,14 +7284,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.load (local.get $2) @@ -6729,14 +7325,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -6766,7 +7366,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -6796,14 +7398,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -6833,14 +7439,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -6870,7 +7480,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -6900,14 +7512,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -6937,14 +7553,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -6974,14 +7594,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -7011,7 +7635,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.load align=1 (local.get $2) @@ -7041,14 +7667,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=2 (local.get $2) @@ -7078,14 +7708,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=4 (local.get $2) @@ -7115,14 +7749,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load align=8 (local.get $2) @@ -7152,14 +7790,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.load (local.get $2) @@ -7189,7 +7831,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.atomic.store8 (local.get $3) @@ -7220,7 +7864,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -7251,7 +7897,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -7282,14 +7930,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store16 (local.get $3) @@ -7320,14 +7972,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -7358,7 +8014,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -7389,14 +8047,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -7427,14 +8089,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.atomic.store (local.get $3) @@ -7465,14 +8131,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -7503,7 +8173,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.atomic.store8 (local.get $3) @@ -7534,7 +8206,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -7565,7 +8239,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -7596,14 +8272,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store16 (local.get $3) @@ -7634,14 +8314,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -7672,7 +8356,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -7703,14 +8389,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -7741,14 +8431,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store32 (local.get $3) @@ -7779,14 +8473,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -7817,7 +8515,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -7848,14 +8548,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -7886,14 +8590,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -7924,14 +8632,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.atomic.store (local.get $3) @@ -7962,14 +8674,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -8000,7 +8716,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -8031,14 +8749,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -8069,14 +8791,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -8107,7 +8833,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -8138,14 +8866,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -8176,14 +8908,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -8214,14 +8950,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) @@ -8252,7 +8992,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (v128.store align=1 (local.get $3) @@ -8283,14 +9025,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=2 (local.get $3) @@ -8321,14 +9067,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=4 (local.get $3) @@ -8359,14 +9109,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store align=8 (local.get $3) @@ -8397,14 +9151,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 15) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (v128.store (local.get $3) diff --git a/test/passes/safe-heap_start-function.txt b/test/passes/safe-heap_start-function.txt index ae7559a9796..11b258945a4 100644 --- a/test/passes/safe-heap_start-function.txt +++ b/test/passes/safe-heap_start-function.txt @@ -74,7 +74,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_s (local.get $2) @@ -104,7 +106,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load8_u (local.get $2) @@ -134,7 +138,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_s align=1 (local.get $2) @@ -164,14 +170,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_s (local.get $2) @@ -201,7 +211,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load16_u align=1 (local.get $2) @@ -231,14 +243,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load16_u (local.get $2) @@ -268,7 +284,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.load align=1 (local.get $2) @@ -298,14 +316,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load align=2 (local.get $2) @@ -335,14 +357,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.load (local.get $2) @@ -372,7 +398,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_s (local.get $2) @@ -402,7 +430,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load8_u (local.get $2) @@ -432,7 +462,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_s align=1 (local.get $2) @@ -462,14 +494,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_s (local.get $2) @@ -499,7 +535,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load16_u align=1 (local.get $2) @@ -529,14 +567,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load16_u (local.get $2) @@ -566,7 +608,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_s align=1 (local.get $2) @@ -596,14 +640,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s align=2 (local.get $2) @@ -633,14 +681,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_s (local.get $2) @@ -670,7 +722,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load32_u align=1 (local.get $2) @@ -700,14 +754,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u align=2 (local.get $2) @@ -737,14 +795,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load32_u (local.get $2) @@ -774,7 +836,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.load align=1 (local.get $2) @@ -804,14 +868,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=2 (local.get $2) @@ -841,14 +909,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load align=4 (local.get $2) @@ -878,14 +950,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.load (local.get $2) @@ -915,7 +991,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.load align=1 (local.get $2) @@ -945,14 +1023,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load align=2 (local.get $2) @@ -982,14 +1064,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.load (local.get $2) @@ -1019,7 +1105,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.load align=1 (local.get $2) @@ -1049,14 +1137,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=2 (local.get $2) @@ -1086,14 +1178,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load align=4 (local.get $2) @@ -1123,14 +1219,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $2) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.load (local.get $2) @@ -1160,7 +1260,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store8 (local.get $3) @@ -1191,7 +1293,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store16 align=1 (local.get $3) @@ -1222,14 +1326,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store16 (local.get $3) @@ -1260,7 +1368,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i32.store align=1 (local.get $3) @@ -1291,14 +1401,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store align=2 (local.get $3) @@ -1329,14 +1443,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i32.store (local.get $3) @@ -1367,7 +1485,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store8 (local.get $3) @@ -1398,7 +1518,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store16 align=1 (local.get $3) @@ -1429,14 +1551,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store16 (local.get $3) @@ -1467,7 +1593,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store32 align=1 (local.get $3) @@ -1498,14 +1626,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 align=2 (local.get $3) @@ -1536,14 +1668,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store32 (local.get $3) @@ -1574,7 +1710,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (i64.store align=1 (local.get $3) @@ -1605,14 +1743,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=2 (local.get $3) @@ -1643,14 +1785,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store align=4 (local.get $3) @@ -1681,14 +1827,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (i64.store (local.get $3) @@ -1719,7 +1869,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f32.store align=1 (local.get $3) @@ -1750,14 +1902,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store align=2 (local.get $3) @@ -1788,14 +1944,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f32.store (local.get $3) @@ -1826,7 +1986,9 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (f64.store align=1 (local.get $3) @@ -1857,14 +2019,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 1) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=2 (local.get $3) @@ -1895,14 +2061,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 3) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store align=4 (local.get $3) @@ -1933,14 +2103,18 @@ ) ) ) - (call $segfault) + (then + (call $segfault) + ) ) (if (i32.and (local.get $3) (i32.const 7) ) - (call $alignfault) + (then + (call $alignfault) + ) ) (f64.store (local.get $3) diff --git a/test/passes/simplify-globals-optimizing_all-features.txt b/test/passes/simplify-globals-optimizing_all-features.txt index 72c0620a675..3f8d4374be9 100644 --- a/test/passes/simplify-globals-optimizing_all-features.txt +++ b/test/passes/simplify-globals-optimizing_all-features.txt @@ -82,8 +82,10 @@ ) (if (local.get $0) - (return - (i32.const 0) + (then + (return + (i32.const 0) + ) ) ) (if @@ -93,8 +95,10 @@ (global.get $g2) ) ) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (global.set $g1 diff --git a/test/passes/simplify-globals-optimizing_all-features.wast b/test/passes/simplify-globals-optimizing_all-features.wast index 988650a74e9..2b26654c9be 100644 --- a/test/passes/simplify-globals-optimizing_all-features.wast +++ b/test/passes/simplify-globals-optimizing_all-features.wast @@ -69,14 +69,14 @@ (func $f (param $x i32) (result i32) (global.set $g1 (i32.const 100)) (global.set $g2 (local.get $x)) - (if (local.get $x) (return (i32.const 0))) + (if (local.get $x) (then (return (i32.const 0)))) (local.set $x (i32.add (global.get $g1) (global.get $g2) ) ) - (if (local.get $x) (return (i32.const 1))) + (if (local.get $x) (then (return (i32.const 1)))) (global.set $g1 (i32.const 200)) (global.set $g2 (local.get $x)) (local.set $x @@ -137,7 +137,9 @@ (i32.eqz (global.get $global$1) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 2) ) diff --git a/test/passes/simplify-globals_all-features.txt b/test/passes/simplify-globals_all-features.txt index e885b3cfe40..5bb7213f2df 100644 --- a/test/passes/simplify-globals_all-features.txt +++ b/test/passes/simplify-globals_all-features.txt @@ -120,8 +120,10 @@ ) (if (local.get $x) - (return - (i32.const 0) + (then + (return + (i32.const 0) + ) ) ) (local.set $x @@ -132,8 +134,10 @@ ) (if (local.get $x) - (return - (i32.const 1) + (then + (return + (i32.const 1) + ) ) ) (global.set $g1 diff --git a/test/passes/simplify-globals_all-features.wast b/test/passes/simplify-globals_all-features.wast index 52d57b656bc..6efe5eaa8f8 100644 --- a/test/passes/simplify-globals_all-features.wast +++ b/test/passes/simplify-globals_all-features.wast @@ -69,14 +69,14 @@ (func $f (param $x i32) (result i32) (global.set $g1 (i32.const 100)) (global.set $g2 (local.get $x)) - (if (local.get $x) (return (i32.const 0))) + (if (local.get $x) (then (return (i32.const 0)))) (local.set $x (i32.add (global.get $g1) (global.get $g2) ) ) - (if (local.get $x) (return (i32.const 1))) + (if (local.get $x) (then (return (i32.const 1)))) (global.set $g1 (i32.const 200)) (global.set $g2 (local.get $x)) (local.set $x diff --git a/test/passes/simplify-locals-nonesting.txt b/test/passes/simplify-locals-nonesting.txt index abc3aecb939..a5dd4d3436b 100644 --- a/test/passes/simplify-locals-nonesting.txt +++ b/test/passes/simplify-locals-nonesting.txt @@ -87,7 +87,7 @@ ) (if (local.get $8) - (block + (then (block $block1 (nop) (nop) @@ -127,7 +127,7 @@ ) (unreachable) ) - (block + (else (unreachable) (unreachable) ) @@ -157,7 +157,7 @@ ) (if (local.get $2) - (block + (then (nop) (nop) (local.set $x @@ -168,7 +168,7 @@ ) (nop) ) - (block + (else (nop) (nop) (local.set $x diff --git a/test/passes/simplify-locals-nonesting.wast b/test/passes/simplify-locals-nonesting.wast index b49ffe13897..8c4da016823 100644 --- a/test/passes/simplify-locals-nonesting.wast +++ b/test/passes/simplify-locals-nonesting.wast @@ -113,69 +113,73 @@ ) (if (local.get $8) - (block - (block $block - (local.set $9 - (local.get $a) - ) - (local.set $10 - (local.get $x) - ) - (local.set $11 - (i64.eq - (local.get $9) - (local.get $10) + (then + (block + (block $block + (local.set $9 + (local.get $a) ) - ) - (local.set $i - (local.get $11) - ) - (nop) - (local.set $12 - (local.get $a) - ) - (local.set $13 - (local.get $y) - ) - (local.set $14 - (i64.ne - (local.get $12) - (local.get $13) + (local.set $10 + (local.get $x) ) - ) - (local.set $j - (local.get $14) - ) - (nop) - (local.set $15 - (local.get $i) - ) - (local.set $16 - (local.get $j) - ) - (local.set $17 - (i32.and - (local.get $15) - (local.get $16) + (local.set $11 + (i64.eq + (local.get $9) + (local.get $10) + ) ) - ) - (local.set $r - (local.get $17) - ) - (nop) - (local.set $18 - (local.get $r) - ) - (return - (local.get $18) + (local.set $i + (local.get $11) + ) + (nop) + (local.set $12 + (local.get $a) + ) + (local.set $13 + (local.get $y) + ) + (local.set $14 + (i64.ne + (local.get $12) + (local.get $13) + ) + ) + (local.set $j + (local.get $14) + ) + (nop) + (local.set $15 + (local.get $i) + ) + (local.set $16 + (local.get $j) + ) + (local.set $17 + (i32.and + (local.get $15) + (local.get $16) + ) + ) + (local.set $r + (local.get $17) + ) + (nop) + (local.set $18 + (local.get $r) + ) + (return + (local.get $18) + ) + (unreachable) ) (unreachable) ) - (unreachable) ) - (block - (unreachable) - (unreachable) + (else + (block + (unreachable) + (unreachable) + ) ) ) ) @@ -205,35 +209,39 @@ ) (if (local.get $2) - (block - (local.set $3 - (local.get $x) - ) - (local.set $4 - (i32.add - (local.get $3) - (i32.const 1) + (then + (block + (local.set $3 + (local.get $x) ) + (local.set $4 + (i32.add + (local.get $3) + (i32.const 1) + ) + ) + (local.set $x + (local.get $4) + ) + (nop) ) - (local.set $x - (local.get $4) - ) - (nop) ) - (block - (local.set $5 - (local.get $x) - ) - (local.set $6 - (i32.add - (local.get $5) - (i32.const 2) + (else + (block + (local.set $5 + (local.get $x) ) + (local.set $6 + (i32.add + (local.get $5) + (i32.const 2) + ) + ) + (local.set $x + (local.get $6) + ) + (nop) ) - (local.set $x - (local.get $6) - ) - (nop) ) ) ) diff --git a/test/passes/simplify-locals-nostructure.txt b/test/passes/simplify-locals-nostructure.txt index f0be46edc9e..18b7052d4e2 100644 --- a/test/passes/simplify-locals-nostructure.txt +++ b/test/passes/simplify-locals-nostructure.txt @@ -14,18 +14,26 @@ (local.tee $x (i32.const 1) ) - (nop) + (then + (nop) + ) ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (nop) (drop (if (result i32) (i32.const 2) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) ) (nop) @@ -36,11 +44,15 @@ ) (if (i32.const 6) - (local.set $a - (i32.const 7) + (then + (local.set $a + (i32.const 7) + ) ) - (local.set $a - (i32.const 8) + (else + (local.set $a + (i32.const 8) + ) ) ) (drop @@ -49,7 +61,7 @@ (block $val (if (i32.const 10) - (block + (then (local.set $b (i32.const 11) ) @@ -97,8 +109,10 @@ ) (if (i32.const 1) - (drop - (local.get $other) + (then + (drop + (local.get $other) + ) ) ) ) @@ -119,10 +133,12 @@ (local $y i32) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) ) - (block + (else (nop) (nop) ) diff --git a/test/passes/simplify-locals-nostructure.wast b/test/passes/simplify-locals-nostructure.wast index 4dc6cfb827b..e93a77ced04 100644 --- a/test/passes/simplify-locals-nostructure.wast +++ b/test/passes/simplify-locals-nostructure.wast @@ -7,22 +7,28 @@ (local $a i32) (local $b i32) (local.set $x (i32.const 1)) - (if (local.get $x) (nop)) - (if (local.get $x) (nop)) - (local.set $y (if (result i32) (i32.const 2) (i32.const 3) (i32.const 4))) + (if (local.get $x) (then (nop))) + (if (local.get $x) (then (nop))) + (local.set $y (if (result i32) (i32.const 2) (then (i32.const 3) )(else (i32.const 4)))) (drop (local.get $y)) (local.set $z (block (result i32) (i32.const 5))) (drop (local.get $z)) (if (i32.const 6) - (local.set $a (i32.const 7)) - (local.set $a (i32.const 8)) + (then + (local.set $a (i32.const 7)) + ) + (else + (local.set $a (i32.const 8)) + ) ) (drop (local.get $a)) (block $val (if (i32.const 10) - (block - (local.set $b (i32.const 11)) - (br $val) + (then + (block + (local.set $b (i32.const 11)) + (br $val) + ) ) ) (local.set $b (i32.const 12)) @@ -65,8 +71,10 @@ (local.get $var$0) ) (if (i32.const 1) - (drop - (local.get $other) + (then + (drop + (local.get $other) + ) ) ) ) @@ -88,10 +96,14 @@ (func $if-value-structure-equivalent (param $x i32) (result i32) (local $y i32) (if (i32.const 1) - (local.set $x (i32.const 2)) - (block - (local.set $y (local.get $x)) - (local.set $x (local.get $y)) + (then + (local.set $x (i32.const 2)) + ) + (else + (block + (local.set $y (local.get $x)) + (local.set $x (local.get $y)) + ) ) ) (local.get $x) diff --git a/test/passes/simplify-locals-notee-nostructure.txt b/test/passes/simplify-locals-notee-nostructure.txt index 0c8a3d78bfd..6015fc83328 100644 --- a/test/passes/simplify-locals-notee-nostructure.txt +++ b/test/passes/simplify-locals-notee-nostructure.txt @@ -11,18 +11,26 @@ ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (nop) (drop (if (result i32) (i32.const 2) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) ) (nop) @@ -33,11 +41,15 @@ ) (if (i32.const 6) - (local.set $a - (i32.const 7) + (then + (local.set $a + (i32.const 7) + ) ) - (local.set $a - (i32.const 8) + (else + (local.set $a + (i32.const 8) + ) ) ) (drop @@ -46,7 +58,7 @@ (block $val (if (i32.const 10) - (block + (then (local.set $b (i32.const 11) ) diff --git a/test/passes/simplify-locals-notee-nostructure.wast b/test/passes/simplify-locals-notee-nostructure.wast index 8185bbe3523..51f910eebcb 100644 --- a/test/passes/simplify-locals-notee-nostructure.wast +++ b/test/passes/simplify-locals-notee-nostructure.wast @@ -6,22 +6,28 @@ (local $a i32) (local $b i32) (local.set $x (i32.const 1)) - (if (local.get $x) (nop)) - (if (local.get $x) (nop)) - (local.set $y (if (result i32) (i32.const 2) (i32.const 3) (i32.const 4))) + (if (local.get $x) (then (nop))) + (if (local.get $x) (then (nop))) + (local.set $y (if (result i32) (i32.const 2) (then (i32.const 3) )(else (i32.const 4)))) (drop (local.get $y)) (local.set $z (block (result i32) (i32.const 5))) (drop (local.get $z)) (if (i32.const 6) - (local.set $a (i32.const 7)) - (local.set $a (i32.const 8)) + (then + (local.set $a (i32.const 7)) + ) + (else + (local.set $a (i32.const 8)) + ) ) (drop (local.get $a)) (block $val (if (i32.const 10) - (block - (local.set $b (i32.const 11)) - (br $val) + (then + (block + (local.set $b (i32.const 11)) + (br $val) + ) ) ) (local.set $b (i32.const 12)) diff --git a/test/passes/simplify-locals-notee.txt b/test/passes/simplify-locals-notee.txt index 56ac575f2f3..ae12af8c992 100644 --- a/test/passes/simplify-locals-notee.txt +++ b/test/passes/simplify-locals-notee.txt @@ -11,18 +11,26 @@ ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (nop) (drop (if (result i32) (i32.const 2) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) ) (nop) @@ -35,11 +43,11 @@ (drop (if (result i32) (i32.const 6) - (block (result i32) + (then (nop) (i32.const 7) ) - (block (result i32) + (else (nop) (i32.const 8) ) @@ -50,7 +58,7 @@ (block $val (result i32) (if (i32.const 10) - (block + (then (nop) (br $val (i32.const 11) diff --git a/test/passes/simplify-locals-notee.wast b/test/passes/simplify-locals-notee.wast index 8185bbe3523..51f910eebcb 100644 --- a/test/passes/simplify-locals-notee.wast +++ b/test/passes/simplify-locals-notee.wast @@ -6,22 +6,28 @@ (local $a i32) (local $b i32) (local.set $x (i32.const 1)) - (if (local.get $x) (nop)) - (if (local.get $x) (nop)) - (local.set $y (if (result i32) (i32.const 2) (i32.const 3) (i32.const 4))) + (if (local.get $x) (then (nop))) + (if (local.get $x) (then (nop))) + (local.set $y (if (result i32) (i32.const 2) (then (i32.const 3) )(else (i32.const 4)))) (drop (local.get $y)) (local.set $z (block (result i32) (i32.const 5))) (drop (local.get $z)) (if (i32.const 6) - (local.set $a (i32.const 7)) - (local.set $a (i32.const 8)) + (then + (local.set $a (i32.const 7)) + ) + (else + (local.set $a (i32.const 8)) + ) ) (drop (local.get $a)) (block $val (if (i32.const 10) - (block - (local.set $b (i32.const 11)) - (br $val) + (then + (block + (local.set $b (i32.const 11)) + (br $val) + ) ) ) (local.set $b (i32.const 12)) diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt index 4225a70336e..36a635e2973 100644 --- a/test/passes/simplify-locals_all-features.txt +++ b/test/passes/simplify-locals_all-features.txt @@ -31,18 +31,26 @@ (local.tee $x (i32.const 1) ) - (nop) + (then + (nop) + ) ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (nop) (drop (if (result i32) (i32.const 2) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) ) (nop) @@ -55,11 +63,11 @@ (drop (if (result i32) (i32.const 6) - (block (result i32) + (then (nop) (i32.const 7) ) - (block (result i32) + (else (nop) (i32.const 8) ) @@ -70,7 +78,7 @@ (block $val (result i32) (if (i32.const 10) - (block + (then (nop) (br $val (i32.const 11) @@ -488,8 +496,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -503,8 +515,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -514,8 +530,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -533,8 +553,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -548,8 +572,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -559,8 +587,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -672,11 +704,11 @@ (local.set $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 13) ) - (block (result i32) + (else (nop) (i32.const 24) ) @@ -689,13 +721,13 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (block $block3 (nop) ) (i32.const 14) ) - (block (result i32) + (else (block $block5 (nop) ) @@ -820,19 +852,23 @@ (drop (if (result i32) (local.get $x) - (block $block53 (result i32) - (nop) - (local.set $temp - (local.get $y) + (then + (block $block53 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) - (block $block54 (result i32) - (nop) - (local.set $temp - (local.get $y) + (else + (block $block54 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) ) ) @@ -852,19 +888,21 @@ (local.get $label) (i32.const 15) ) - (block $block - (nop) - (nop) - (drop - (br_if $label$break$L4 - (local.tee $label - (i32.const 0) - ) - (i32.eqz - (i32.eq - (local.get $$$0151) + (then + (block $block + (nop) + (nop) + (drop + (br_if $label$break$L4 + (local.tee $label (i32.const 0) ) + (i32.eqz + (i32.eq + (local.get $$$0151) + (i32.const 0) + ) + ) ) ) ) @@ -887,11 +925,15 @@ (func $if-return-but-unreachable (type $11) (param $var$0 i64) (if (unreachable) - (drop - (local.get $var$0) + (then + (drop + (local.get $var$0) + ) ) - (local.set $var$0 - (i64.const 1) + (else + (local.set $var$0 + (i64.const 1) + ) ) ) ) @@ -901,11 +943,13 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $x) + (else + (local.get $x) + ) ) ) ) @@ -918,11 +962,13 @@ (local.set $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $x) + (else + (local.get $x) + ) ) ) (local.get $y) @@ -935,22 +981,24 @@ (local.get $0) (i32.const -1073741824) ) - (block (result i32) + (then (nop) (i32.const -1073741824) ) - (block (result i32) + (else (nop) (if (result i32) (i32.gt_s (local.get $0) (i32.const 1073741823) ) - (block (result i32) + (then (nop) (i32.const 1073741823) ) - (local.get $0) + (else + (local.get $0) + ) ) ) ) @@ -967,8 +1015,12 @@ (local.set $x (if (result i32) (i32.const -1) - (i32.const -2) - (local.get $x) + (then + (i32.const -2) + ) + (else + (local.get $x) + ) ) ) (drop @@ -976,8 +1028,12 @@ (local.tee $x (if (result i32) (i32.const -3) - (i32.const -4) - (local.get $x) + (then + (i32.const -4) + ) + (else + (local.get $x) + ) ) ) ) @@ -988,8 +1044,12 @@ (local.tee $y (if (result i32) (i32.const -5) - (i32.const -6) - (local.get $y) + (then + (i32.const -6) + ) + (else + (local.get $y) + ) ) ) ) @@ -1000,8 +1060,12 @@ (local.tee $z (if (result i32) (i32.const -7) - (i32.const -8) - (local.get $z) + (then + (i32.const -8) + ) + (else + (local.get $z) + ) ) ) (local.get $z) @@ -1016,22 +1080,28 @@ (local.tee $4 (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $4) + (else + (local.get $4) + ) ) ) - (block (result i32) + (then (nop) (i32.const 0) ) - (local.get $4) + (else + (local.get $4) + ) ) ) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 0) ) @@ -1040,16 +1110,28 @@ (local.tee $20 (if (result i32) (i32.const 1) - (if (result i32) - (i32.const 2) + (then (if (result i32) - (i32.const 3) - (i32.const 4) - (local.get $20) + (i32.const 2) + (then + (if (result i32) + (i32.const 3) + (then + (i32.const 4) + ) + (else + (local.get $20) + ) + ) + ) + (else + (local.get $20) + ) ) + ) + (else (local.get $20) ) - (local.get $20) ) ) ) @@ -1085,8 +1167,12 @@ (i32.eqz (local.get $0) ) - (f32.const 4623408228068004207103214e13) - (local.get $3) + (then + (f32.const 4623408228068004207103214e13) + ) + (else + (local.get $3) + ) ) ) ) @@ -1098,7 +1184,7 @@ ) (if (result f64) (global.get $global$0) - (block + (then (global.set $global$0 (i32.sub (global.get $global$0) @@ -1116,7 +1202,9 @@ ) (br $label$1) ) - (f64.const -70) + (else + (f64.const -70) + ) ) ) ) @@ -1319,11 +1407,11 @@ (drop (if (result i32) (i32.const 1) - (block + (then (br $out) (nop) ) - (block (result i32) + (else (nop) (i32.const 2) ) @@ -1332,11 +1420,11 @@ (drop (if (result i32) (i32.const 3) - (block (result i32) + (then (nop) (i32.const 4) ) - (block + (else (br $out) (nop) ) @@ -1344,8 +1432,12 @@ ) (if (i32.const 5) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1356,13 +1448,13 @@ (drop (if (result i32) (i32.const 1) - (block + (then (nop) (nop) (br $out) (nop) ) - (block (result i32) + (else (nop) (nop) (i32.const 4) @@ -1372,12 +1464,12 @@ (drop (if (result i32) (i32.const 6) - (block (result i32) + (then (nop) (nop) (i32.const 7) ) - (block + (else (nop) (nop) (br $out) @@ -1387,12 +1479,12 @@ ) (if (i32.const 11) - (block + (then (nop) (nop) (br $out) ) - (block + (else (nop) (nop) (br $out) @@ -1428,11 +1520,11 @@ (nop) (if (result i32) (i32.const 0) - (block (result i32) + (then (nop) (i32.const 0) ) - (block + (else (loop $label$4 (br $label$4) ) @@ -1453,11 +1545,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $x) + (else + (local.get $x) + ) ) ) (drop @@ -1476,11 +1570,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (drop @@ -1508,11 +1604,13 @@ (local.set $y (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (local.set $x @@ -1521,11 +1619,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (nop) @@ -1542,11 +1642,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (nop) @@ -1603,11 +1705,11 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (block (result i32) + (else (nop) (nop) (local.get $x) @@ -1660,11 +1762,11 @@ (nop) (if (result f32) (call $fimport$0) - (block (result f32) + (then (nop) (f32.const -2048) ) - (block + (else (call $fimport$1 (i32.const -25732) ) diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast index f46f9fd7129..b302a317ded 100644 --- a/test/passes/simplify-locals_all-features.wast +++ b/test/passes/simplify-locals_all-features.wast @@ -21,22 +21,28 @@ (local $a i32) (local $b i32) (local.set $x (i32.const 1)) - (if (local.get $x) (nop)) - (if (local.get $x) (nop)) - (local.set $y (if (result i32) (i32.const 2) (i32.const 3) (i32.const 4))) + (if (local.get $x) (then (nop))) + (if (local.get $x) (then (nop))) + (local.set $y (if (result i32) (i32.const 2) (then (i32.const 3) )(else (i32.const 4)))) (drop (local.get $y)) (local.set $z (block (result i32) (i32.const 5))) (drop (local.get $z)) (if (i32.const 6) - (local.set $a (i32.const 7)) - (local.set $a (i32.const 8)) + (then + (local.set $a (i32.const 7)) + ) + (else + (local.set $a (i32.const 8)) + ) ) (drop (local.get $a)) (block $val (if (i32.const 10) - (block - (local.set $b (i32.const 11)) - (br $val) + (then + (block + (local.set $b (i32.const 11)) + (br $val) + ) ) ) (local.set $b (i32.const 12)) @@ -502,8 +508,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -517,8 +527,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -528,8 +542,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -547,8 +565,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -562,8 +584,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -573,8 +599,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -681,23 +711,31 @@ (block $waka2 (if (i32.const 1) - (local.set $x - (i32.const 13) + (then + (local.set $x + (i32.const 13) + ) ) - (local.set $x - (i32.const 24) + (else + (local.set $x + (i32.const 24) + ) ) ) (if (i32.const 1) - (block $block3 - (local.set $x - (i32.const 14) + (then + (block $block3 + (local.set $x + (i32.const 14) + ) ) ) - (block $block5 - (local.set $x - (i32.const 25) + (else + (block $block5 + (local.set $x + (i32.const 25) + ) ) ) ) @@ -811,19 +849,23 @@ (drop (if (result i32) (local.get $x) - (block $block53 (result i32) - (nop) - (local.set $temp - (local.get $y) + (then + (block $block53 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) - (block $block54 (result i32) - (nop) - (local.set $temp - (local.get $y) + (else + (block $block54 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) ) ) @@ -839,19 +881,21 @@ (local.get $label) (i32.const 15) ) - (block $block - (local.set $label - (i32.const 0) - ) - (local.set $$cond2 - (i32.eq - (local.get $$$0151) + (then + (block $block + (local.set $label (i32.const 0) ) - ) - (br_if $label$break$L4 ;; when we add a value to this, its type changes as it returns the value too, so must be dropped - (i32.eqz - (local.get $$cond2) + (local.set $$cond2 + (i32.eq + (local.get $$$0151) + (i32.const 0) + ) + ) + (br_if $label$break$L4 ;; when we add a value to this, its type changes as it returns the value too, so must be dropped + (i32.eqz + (local.get $$cond2) + ) ) ) ) @@ -876,11 +920,15 @@ (func $if-return-but-unreachable (param $var$0 i64) (if (unreachable) - (local.set $var$0 - (local.get $var$0) + (then + (local.set $var$0 + (local.get $var$0) + ) ) - (local.set $var$0 - (i64.const 1) + (else + (local.set $var$0 + (i64.const 1) + ) ) ) ) @@ -888,8 +936,10 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) ) ) (local.get $x) @@ -902,8 +952,10 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) ) ) (local.get $y) @@ -914,16 +966,22 @@ (local.get $0) (i32.const -1073741824) ) - (local.set $0 - (i32.const -1073741824) - ) - (if - (i32.gt_s - (local.get $0) - (i32.const 1073741823) - ) + (then (local.set $0 - (i32.const 1073741823) + (i32.const -1073741824) + ) + ) + (else + (if + (i32.gt_s + (local.get $0) + (i32.const 1073741823) + ) + (then + (local.set $0 + (i32.const 1073741823) + ) + ) ) ) ) @@ -941,8 +999,12 @@ (local.set $x (if (result i32) (i32.const -1) - (i32.const -2) - (local.get $x) + (then + (i32.const -2) + ) + (else + (local.get $x) + ) ) ) ;; oops, this one is a tee @@ -951,8 +1013,12 @@ (local.tee $x (if (result i32) (i32.const -3) - (i32.const -4) - (local.get $x) + (then + (i32.const -4) + ) + (else + (local.get $x) + ) ) ) ) @@ -961,8 +1027,12 @@ (local.set $y (if (result i32) (i32.const -5) - (i32.const -6) - (local.get $y) + (then + (i32.const -6) + ) + (else + (local.get $y) + ) ) ) (drop (i32.eqz (local.get $y))) @@ -970,8 +1040,12 @@ (local.set $z (if (result i32) (i32.const -7) - (i32.const -8) - (local.get $z) + (then + (i32.const -8) + ) + (else + (local.get $z) + ) ) ) (drop @@ -984,19 +1058,25 @@ (block $label$1 (result i32) (if (i32.const 1) - (local.set $4 - (i32.const 2) + (then + (local.set $4 + (i32.const 2) + ) ) ) (if (local.get $4) - (local.set $4 - (i32.const 0) + (then + (local.set $4 + (i32.const 0) + ) ) ) (local.get $4) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 0) ) @@ -1004,16 +1084,28 @@ (local.set $20 (if (result i32) (i32.const 1) - (if (result i32) - (i32.const 2) + (then (if (result i32) - (i32.const 3) - (i32.const 4) - (local.get $20) + (i32.const 2) + (then + (if (result i32) + (i32.const 3) + (then + (i32.const 4) + ) + (else + (local.get $20) + ) + ) + ) + (else + (local.get $20) + ) ) + ) + (else (local.get $20) ) - (local.get $20) ) ) (local.get $20) @@ -1050,8 +1142,12 @@ (i32.eqz (local.get $0) ) - (f32.const 4623408228068004207103214e13) - (local.get $3) + (then + (f32.const 4623408228068004207103214e13) + ) + (else + (local.get $3) + ) ) ) ) @@ -1063,25 +1159,29 @@ ) (if (result f64) (global.get $global$0) - (block - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (then + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) - ) - (local.set $0 - (i32.const -65) - ) - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (local.set $0 + (i32.const -65) + ) + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) + (br $label$1) ) - (br $label$1) ) - (f64.const -70) + (else + (f64.const -70) + ) ) ) ) @@ -1199,22 +1299,34 @@ (block $out (if (i32.const 1) - (br $out) - (local.set $x - (i32.const 2) + (then + (br $out) + ) + (else + (local.set $x + (i32.const 2) + ) ) ) (if (i32.const 3) - (local.set $x - (i32.const 4) + (then + (local.set $x + (i32.const 4) + ) + ) + (else + (br $out) ) - (br $out) ) (if (i32.const 5) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1224,63 +1336,75 @@ (block $out (if (i32.const 1) - (block - (local.set $x - (i32.const 2) - ) - (local.set $y - (i32.const 3) + (then + (block + (local.set $x + (i32.const 2) + ) + (local.set $y + (i32.const 3) + ) + (br $out) ) - (br $out) ) - (block - (local.set $x - (i32.const 4) - ) - (local.set $y - (i32.const 5) + (else + (block + (local.set $x + (i32.const 4) + ) + (local.set $y + (i32.const 5) + ) ) ) ) (if (i32.const 6) - (block - (local.set $x - (i32.const 7) - ) - (local.set $y - (i32.const 8) + (then + (block + (local.set $x + (i32.const 7) + ) + (local.set $y + (i32.const 8) + ) ) ) - (block - (local.set $x - (i32.const 9) - ) - (local.set $y - (i32.const 10) + (else + (block + (local.set $x + (i32.const 9) + ) + (local.set $y + (i32.const 10) + ) + (br $out) ) - (br $out) ) ) (if (i32.const 11) - (block - (local.set $x - (i32.const 12) - ) - (local.set $y - (i32.const 13) + (then + (block + (local.set $x + (i32.const 12) + ) + (local.set $y + (i32.const 13) + ) + (br $out) ) - (br $out) ) - (block - (local.set $x - (i32.const 14) - ) - (local.set $y - (i32.const 15) + (else + (block + (local.set $x + (i32.const 14) + ) + (local.set $y + (i32.const 15) + ) + (br $out) ) - (br $out) ) ) ) @@ -1308,11 +1432,15 @@ (local $0 i32) (if (i32.const 0) - (local.set $0 - (i32.const 0) + (then + (local.set $0 + (i32.const 0) + ) ) - (loop $label$4 - (br $label$4) + (else + (loop $label$4 + (br $label$4) + ) ) ) (local.get $0) @@ -1322,11 +1450,13 @@ (block $label$2 (if (i32.const 0) - (block - (local.set $var$0 - (i32.const -1) + (then + (block + (local.set $var$0 + (i32.const -1) + ) + (br $label$2) ) - (br $label$2) ) ) (local.set $var$0 @@ -1341,7 +1471,9 @@ (local $y i32) (local.set $x (local.get $y)) (if (i32.const 1) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) ) (local.set $x (local.get $y)) (local.set $x (local.get $y)) @@ -1351,7 +1483,9 @@ (local $y i32) (local.set $y (local.get $x)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $y (local.get $x)) @@ -1366,11 +1500,15 @@ (local.set $w (local.get $z)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -1378,7 +1516,9 @@ (local.set $z (i32.const 2)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -1425,10 +1565,14 @@ (func $if-value-structure-equivalent (param $x i32) (result i32) (local $y i32) (if (i32.const 1) - (local.set $x (i32.const 2)) - (block - (local.set $y (local.get $x)) - (local.set $x (local.get $y)) + (then + (local.set $x (i32.const 2)) + ) + (else + (block + (local.set $y (local.get $x)) + (local.set $x (local.get $y)) + ) ) ) (local.get $x) @@ -1472,14 +1616,18 @@ ) (if (local.get $0) - (local.set $5 - (f32.const -2048) + (then + (local.set $5 + (f32.const -2048) + ) ) - (block - (call $fimport$1 - (i32.const -25732) + (else + (block + (call $fimport$1 + (i32.const -25732) + ) + (br $label$2) ) - (br $label$2) ) ) ) diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.txt b/test/passes/simplify-locals_all-features_disable-exception-handling.txt index 6ee89372d20..f14253c3e73 100644 --- a/test/passes/simplify-locals_all-features_disable-exception-handling.txt +++ b/test/passes/simplify-locals_all-features_disable-exception-handling.txt @@ -31,18 +31,26 @@ (local.tee $x (i32.const 1) ) - (nop) + (then + (nop) + ) ) (if (local.get $x) - (nop) + (then + (nop) + ) ) (nop) (drop (if (result i32) (i32.const 2) - (i32.const 3) - (i32.const 4) + (then + (i32.const 3) + ) + (else + (i32.const 4) + ) ) ) (nop) @@ -55,11 +63,11 @@ (drop (if (result i32) (i32.const 6) - (block (result i32) + (then (nop) (i32.const 7) ) - (block (result i32) + (else (nop) (i32.const 8) ) @@ -70,7 +78,7 @@ (block $val (result i32) (if (i32.const 10) - (block + (then (nop) (br $val (i32.const 11) @@ -492,8 +500,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -510,8 +522,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -521,8 +537,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -550,8 +570,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -568,8 +592,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -579,8 +607,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -666,11 +698,11 @@ (local.set $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 13) ) - (block (result i32) + (else (nop) (i32.const 24) ) @@ -683,13 +715,13 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (block $block3 (nop) ) (i32.const 14) ) - (block (result i32) + (else (block $block5 (nop) ) @@ -814,19 +846,23 @@ (drop (if (result i32) (local.get $x) - (block $block53 (result i32) - (nop) - (local.set $temp - (local.get $y) + (then + (block $block53 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) - (block $block54 (result i32) - (nop) - (local.set $temp - (local.get $y) + (else + (block $block54 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) ) ) @@ -846,19 +882,21 @@ (local.get $label) (i32.const 15) ) - (block $block - (nop) - (nop) - (drop - (br_if $label$break$L4 - (local.tee $label - (i32.const 0) - ) - (i32.eqz - (i32.eq - (local.get $$$0151) + (then + (block $block + (nop) + (nop) + (drop + (br_if $label$break$L4 + (local.tee $label (i32.const 0) ) + (i32.eqz + (i32.eq + (local.get $$$0151) + (i32.const 0) + ) + ) ) ) ) @@ -881,11 +919,15 @@ (func $if-return-but-unreachable (type $11) (param $var$0 i64) (if (unreachable) - (drop - (local.get $var$0) + (then + (drop + (local.get $var$0) + ) ) - (local.set $var$0 - (i64.const 1) + (else + (local.set $var$0 + (i64.const 1) + ) ) ) ) @@ -895,11 +937,13 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $x) + (else + (local.get $x) + ) ) ) ) @@ -912,11 +956,13 @@ (local.set $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $x) + (else + (local.get $x) + ) ) ) (local.get $y) @@ -929,22 +975,24 @@ (local.get $0) (i32.const -1073741824) ) - (block (result i32) + (then (nop) (i32.const -1073741824) ) - (block (result i32) + (else (nop) (if (result i32) (i32.gt_s (local.get $0) (i32.const 1073741823) ) - (block (result i32) + (then (nop) (i32.const 1073741823) ) - (local.get $0) + (else + (local.get $0) + ) ) ) ) @@ -961,8 +1009,12 @@ (local.set $x (if (result i32) (i32.const -1) - (i32.const -2) - (local.get $x) + (then + (i32.const -2) + ) + (else + (local.get $x) + ) ) ) (drop @@ -970,8 +1022,12 @@ (local.tee $x (if (result i32) (i32.const -3) - (i32.const -4) - (local.get $x) + (then + (i32.const -4) + ) + (else + (local.get $x) + ) ) ) ) @@ -982,8 +1038,12 @@ (local.tee $y (if (result i32) (i32.const -5) - (i32.const -6) - (local.get $y) + (then + (i32.const -6) + ) + (else + (local.get $y) + ) ) ) ) @@ -994,8 +1054,12 @@ (local.tee $z (if (result i32) (i32.const -7) - (i32.const -8) - (local.get $z) + (then + (i32.const -8) + ) + (else + (local.get $z) + ) ) ) (local.get $z) @@ -1010,22 +1074,28 @@ (local.tee $4 (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (local.get $4) + (else + (local.get $4) + ) ) ) - (block (result i32) + (then (nop) (i32.const 0) ) - (local.get $4) + (else + (local.get $4) + ) ) ) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 0) ) @@ -1034,16 +1104,28 @@ (local.tee $20 (if (result i32) (i32.const 1) - (if (result i32) - (i32.const 2) + (then (if (result i32) - (i32.const 3) - (i32.const 4) - (local.get $20) + (i32.const 2) + (then + (if (result i32) + (i32.const 3) + (then + (i32.const 4) + ) + (else + (local.get $20) + ) + ) + ) + (else + (local.get $20) + ) ) + ) + (else (local.get $20) ) - (local.get $20) ) ) ) @@ -1079,8 +1161,12 @@ (i32.eqz (local.get $0) ) - (f32.const 4623408228068004207103214e13) - (local.get $3) + (then + (f32.const 4623408228068004207103214e13) + ) + (else + (local.get $3) + ) ) ) ) @@ -1092,7 +1178,7 @@ ) (if (result f64) (global.get $global$0) - (block + (then (global.set $global$0 (i32.sub (global.get $global$0) @@ -1110,7 +1196,9 @@ ) (br $label$1) ) - (f64.const -70) + (else + (f64.const -70) + ) ) ) ) @@ -1313,11 +1401,11 @@ (drop (if (result i32) (i32.const 1) - (block + (then (br $out) (nop) ) - (block (result i32) + (else (nop) (i32.const 2) ) @@ -1326,11 +1414,11 @@ (drop (if (result i32) (i32.const 3) - (block (result i32) + (then (nop) (i32.const 4) ) - (block + (else (br $out) (nop) ) @@ -1338,8 +1426,12 @@ ) (if (i32.const 5) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1350,13 +1442,13 @@ (drop (if (result i32) (i32.const 1) - (block + (then (nop) (nop) (br $out) (nop) ) - (block (result i32) + (else (nop) (nop) (i32.const 4) @@ -1366,12 +1458,12 @@ (drop (if (result i32) (i32.const 6) - (block (result i32) + (then (nop) (nop) (i32.const 7) ) - (block + (else (nop) (nop) (br $out) @@ -1381,12 +1473,12 @@ ) (if (i32.const 11) - (block + (then (nop) (nop) (br $out) ) - (block + (else (nop) (nop) (br $out) @@ -1422,11 +1514,11 @@ (nop) (if (result i32) (i32.const 0) - (block (result i32) + (then (nop) (i32.const 0) ) - (block + (else (loop $label$4 (br $label$4) ) @@ -1447,11 +1539,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $x) + (else + (local.get $x) + ) ) ) (drop @@ -1470,11 +1564,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (drop @@ -1502,11 +1598,13 @@ (local.set $y (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (local.set $x @@ -1515,11 +1613,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (nop) @@ -1536,11 +1636,13 @@ (drop (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 1) ) - (local.get $y) + (else + (local.get $y) + ) ) ) (nop) @@ -1597,11 +1699,11 @@ (local.tee $x (if (result i32) (i32.const 1) - (block (result i32) + (then (nop) (i32.const 2) ) - (block (result i32) + (else (nop) (nop) (local.get $x) @@ -1654,11 +1756,11 @@ (nop) (if (result f32) (call $fimport$0) - (block (result f32) + (then (nop) (f32.const -2048) ) - (block + (else (call $fimport$1 (i32.const -25732) ) diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.wast b/test/passes/simplify-locals_all-features_disable-exception-handling.wast index 1f308723a65..9cb4bf748bd 100644 --- a/test/passes/simplify-locals_all-features_disable-exception-handling.wast +++ b/test/passes/simplify-locals_all-features_disable-exception-handling.wast @@ -21,22 +21,28 @@ (local $a i32) (local $b i32) (local.set $x (i32.const 1)) - (if (local.get $x) (nop)) - (if (local.get $x) (nop)) - (local.set $y (if (result i32) (i32.const 2) (i32.const 3) (i32.const 4))) + (if (local.get $x) (then (nop))) + (if (local.get $x) (then (nop))) + (local.set $y (if (result i32) (i32.const 2) (then (i32.const 3) )(else (i32.const 4)))) (drop (local.get $y)) (local.set $z (block (result i32) (i32.const 5))) (drop (local.get $z)) (if (i32.const 6) - (local.set $a (i32.const 7)) - (local.set $a (i32.const 8)) + (then + (local.set $a (i32.const 7)) + ) + (else + (local.set $a (i32.const 8)) + ) ) (drop (local.get $a)) (block $val (if (i32.const 10) - (block - (local.set $b (i32.const 11)) - (br $val) + (then + (block + (local.set $b (i32.const 11)) + (br $val) + ) ) ) (local.set $b (i32.const 12)) @@ -502,8 +508,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -517,8 +527,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -528,8 +542,12 @@ (local.get $$a$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -547,8 +565,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -562,8 +584,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 31) ) @@ -573,8 +599,12 @@ (local.get $$b$1) (i32.const 0) ) - (i32.const -1) - (i32.const 0) + (then + (i32.const -1) + ) + (else + (i32.const 0) + ) ) (i32.const 1) ) @@ -681,23 +711,31 @@ (block $waka2 (if (i32.const 1) - (local.set $x - (i32.const 13) + (then + (local.set $x + (i32.const 13) + ) ) - (local.set $x - (i32.const 24) + (else + (local.set $x + (i32.const 24) + ) ) ) (if (i32.const 1) - (block $block3 - (local.set $x - (i32.const 14) + (then + (block $block3 + (local.set $x + (i32.const 14) + ) ) ) - (block $block5 - (local.set $x - (i32.const 25) + (else + (block $block5 + (local.set $x + (i32.const 25) + ) ) ) ) @@ -811,19 +849,23 @@ (drop (if (result i32) (local.get $x) - (block $block53 (result i32) - (nop) - (local.set $temp - (local.get $y) + (then + (block $block53 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) - (block $block54 (result i32) - (nop) - (local.set $temp - (local.get $y) + (else + (block $block54 (result i32) + (nop) + (local.set $temp + (local.get $y) + ) + (local.get $z) ) - (local.get $z) ) ) ) @@ -839,19 +881,21 @@ (local.get $label) (i32.const 15) ) - (block $block - (local.set $label - (i32.const 0) - ) - (local.set $$cond2 - (i32.eq - (local.get $$$0151) + (then + (block $block + (local.set $label (i32.const 0) ) - ) - (br_if $label$break$L4 ;; when we add a value to this, its type changes as it returns the value too, so must be dropped - (i32.eqz - (local.get $$cond2) + (local.set $$cond2 + (i32.eq + (local.get $$$0151) + (i32.const 0) + ) + ) + (br_if $label$break$L4 ;; when we add a value to this, its type changes as it returns the value too, so must be dropped + (i32.eqz + (local.get $$cond2) + ) ) ) ) @@ -876,11 +920,15 @@ (func $if-return-but-unreachable (param $var$0 i64) (if (unreachable) - (local.set $var$0 - (local.get $var$0) + (then + (local.set $var$0 + (local.get $var$0) + ) ) - (local.set $var$0 - (i64.const 1) + (else + (local.set $var$0 + (i64.const 1) + ) ) ) ) @@ -888,8 +936,10 @@ (local $x i32) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) ) ) (local.get $x) @@ -902,8 +952,10 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) ) ) (local.get $y) @@ -914,16 +966,22 @@ (local.get $0) (i32.const -1073741824) ) - (local.set $0 - (i32.const -1073741824) - ) - (if - (i32.gt_s - (local.get $0) - (i32.const 1073741823) - ) + (then (local.set $0 - (i32.const 1073741823) + (i32.const -1073741824) + ) + ) + (else + (if + (i32.gt_s + (local.get $0) + (i32.const 1073741823) + ) + (then + (local.set $0 + (i32.const 1073741823) + ) + ) ) ) ) @@ -941,8 +999,12 @@ (local.set $x (if (result i32) (i32.const -1) - (i32.const -2) - (local.get $x) + (then + (i32.const -2) + ) + (else + (local.get $x) + ) ) ) ;; oops, this one is a tee @@ -951,8 +1013,12 @@ (local.tee $x (if (result i32) (i32.const -3) - (i32.const -4) - (local.get $x) + (then + (i32.const -4) + ) + (else + (local.get $x) + ) ) ) ) @@ -961,8 +1027,12 @@ (local.set $y (if (result i32) (i32.const -5) - (i32.const -6) - (local.get $y) + (then + (i32.const -6) + ) + (else + (local.get $y) + ) ) ) (drop (i32.eqz (local.get $y))) @@ -970,8 +1040,12 @@ (local.set $z (if (result i32) (i32.const -7) - (i32.const -8) - (local.get $z) + (then + (i32.const -8) + ) + (else + (local.get $z) + ) ) ) (drop @@ -984,19 +1058,25 @@ (block $label$1 (result i32) (if (i32.const 1) - (local.set $4 - (i32.const 2) + (then + (local.set $4 + (i32.const 2) + ) ) ) (if (local.get $4) - (local.set $4 - (i32.const 0) + (then + (local.set $4 + (i32.const 0) + ) ) ) (local.get $4) ) - (unreachable) + (then + (unreachable) + ) ) (i32.const 0) ) @@ -1004,16 +1084,28 @@ (local.set $20 (if (result i32) (i32.const 1) - (if (result i32) - (i32.const 2) + (then (if (result i32) - (i32.const 3) - (i32.const 4) - (local.get $20) + (i32.const 2) + (then + (if (result i32) + (i32.const 3) + (then + (i32.const 4) + ) + (else + (local.get $20) + ) + ) + ) + (else + (local.get $20) + ) ) + ) + (else (local.get $20) ) - (local.get $20) ) ) (local.get $20) @@ -1050,8 +1142,12 @@ (i32.eqz (local.get $0) ) - (f32.const 4623408228068004207103214e13) - (local.get $3) + (then + (f32.const 4623408228068004207103214e13) + ) + (else + (local.get $3) + ) ) ) ) @@ -1063,25 +1159,29 @@ ) (if (result f64) (global.get $global$0) - (block - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (then + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) - ) - (local.set $0 - (i32.const -65) - ) - (global.set $global$0 - (i32.sub - (global.get $global$0) - (i32.const 1) + (local.set $0 + (i32.const -65) + ) + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) ) + (br $label$1) ) - (br $label$1) ) - (f64.const -70) + (else + (f64.const -70) + ) ) ) ) @@ -1199,22 +1299,34 @@ (block $out (if (i32.const 1) - (br $out) - (local.set $x - (i32.const 2) + (then + (br $out) + ) + (else + (local.set $x + (i32.const 2) + ) ) ) (if (i32.const 3) - (local.set $x - (i32.const 4) + (then + (local.set $x + (i32.const 4) + ) + ) + (else + (br $out) ) - (br $out) ) (if (i32.const 5) - (br $out) - (br $out) + (then + (br $out) + ) + (else + (br $out) + ) ) ) ) @@ -1224,63 +1336,75 @@ (block $out (if (i32.const 1) - (block - (local.set $x - (i32.const 2) - ) - (local.set $y - (i32.const 3) + (then + (block + (local.set $x + (i32.const 2) + ) + (local.set $y + (i32.const 3) + ) + (br $out) ) - (br $out) ) - (block - (local.set $x - (i32.const 4) - ) - (local.set $y - (i32.const 5) + (else + (block + (local.set $x + (i32.const 4) + ) + (local.set $y + (i32.const 5) + ) ) ) ) (if (i32.const 6) - (block - (local.set $x - (i32.const 7) - ) - (local.set $y - (i32.const 8) + (then + (block + (local.set $x + (i32.const 7) + ) + (local.set $y + (i32.const 8) + ) ) ) - (block - (local.set $x - (i32.const 9) - ) - (local.set $y - (i32.const 10) + (else + (block + (local.set $x + (i32.const 9) + ) + (local.set $y + (i32.const 10) + ) + (br $out) ) - (br $out) ) ) (if (i32.const 11) - (block - (local.set $x - (i32.const 12) - ) - (local.set $y - (i32.const 13) + (then + (block + (local.set $x + (i32.const 12) + ) + (local.set $y + (i32.const 13) + ) + (br $out) ) - (br $out) ) - (block - (local.set $x - (i32.const 14) - ) - (local.set $y - (i32.const 15) + (else + (block + (local.set $x + (i32.const 14) + ) + (local.set $y + (i32.const 15) + ) + (br $out) ) - (br $out) ) ) ) @@ -1308,11 +1432,15 @@ (local $0 i32) (if (i32.const 0) - (local.set $0 - (i32.const 0) + (then + (local.set $0 + (i32.const 0) + ) ) - (loop $label$4 - (br $label$4) + (else + (loop $label$4 + (br $label$4) + ) ) ) (local.get $0) @@ -1322,11 +1450,13 @@ (block $label$2 (if (i32.const 0) - (block - (local.set $var$0 - (i32.const -1) + (then + (block + (local.set $var$0 + (i32.const -1) + ) + (br $label$2) ) - (br $label$2) ) ) (local.set $var$0 @@ -1341,7 +1471,9 @@ (local $y i32) (local.set $x (local.get $y)) (if (i32.const 1) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) ) (local.set $x (local.get $y)) (local.set $x (local.get $y)) @@ -1351,7 +1483,9 @@ (local $y i32) (local.set $y (local.get $x)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $y (local.get $x)) @@ -1366,11 +1500,15 @@ (local.set $w (local.get $z)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -1378,7 +1516,9 @@ (local.set $z (i32.const 2)) (local.set $x (local.get $z)) (if (i32.const 1) - (local.set $y (i32.const 1)) + (then + (local.set $y (i32.const 1)) + ) ) (local.set $y (local.get $x)) (local.set $z (local.get $y)) @@ -1425,10 +1565,14 @@ (func $if-value-structure-equivalent (param $x i32) (result i32) (local $y i32) (if (i32.const 1) - (local.set $x (i32.const 2)) - (block - (local.set $y (local.get $x)) - (local.set $x (local.get $y)) + (then + (local.set $x (i32.const 2)) + ) + (else + (block + (local.set $y (local.get $x)) + (local.set $x (local.get $y)) + ) ) ) (local.get $x) @@ -1472,14 +1616,18 @@ ) (if (local.get $0) - (local.set $5 - (f32.const -2048) + (then + (local.set $5 + (f32.const -2048) + ) ) - (block - (call $fimport$1 - (i32.const -25732) + (else + (block + (call $fimport$1 + (i32.const -25732) + ) + (br $label$2) ) - (br $label$2) ) ) ) diff --git a/test/passes/souperify.txt b/test/passes/souperify.txt index c98e21b712a..113400e67c6 100644 --- a/test/passes/souperify.txt +++ b/test/passes/souperify.txt @@ -13,11 +13,13 @@ infer %0 (local $0 i32) (if (i32.const 0) - (loop $label$0 - (local.set $0 - (i32.sub - (i32.const 0) - (i32.const 0) + (then + (loop $label$0 + (local.set $0 + (i32.sub + (i32.const 0) + (i32.const 0) + ) ) ) ) diff --git a/test/passes/souperify.wast b/test/passes/souperify.wast index 97227ed5343..a67c7d04f70 100644 --- a/test/passes/souperify.wast +++ b/test/passes/souperify.wast @@ -4,11 +4,13 @@ (func $if-loop-test (local $0 i32) (if (i32.const 0) - (loop $label$0 - (local.set $0 - (i32.sub - (i32.const 0) - (i32.const 0) + (then + (loop $label$0 + (local.set $0 + (i32.sub + (i32.const 0) + (i32.const 0) + ) ) ) ) diff --git a/test/passes/spill-pointers.txt b/test/passes/spill-pointers.txt index ebfb3b9e7c2..c9b9a4a3edb 100644 --- a/test/passes/spill-pointers.txt +++ b/test/passes/spill-pointers.txt @@ -337,7 +337,7 @@ ) (if (i32.const 1) - (block + (then (local.set $2 (i32.const 2) ) @@ -348,7 +348,7 @@ (local.get $2) ) ) - (block + (else (local.set $3 (i32.const 3) ) @@ -985,7 +985,7 @@ ) (if (i32.const 1) - (block + (then (local.set $2 (i32.const 2) ) @@ -996,7 +996,7 @@ (local.get $2) ) ) - (block + (else (local.set $3 (i32.const 3) ) diff --git a/test/passes/spill-pointers.wast b/test/passes/spill-pointers.wast index 4eb05a72116..4a9d71f144f 100644 --- a/test/passes/spill-pointers.wast +++ b/test/passes/spill-pointers.wast @@ -83,8 +83,12 @@ (call $nothing) (drop (local.get $x)) (if (i32.const 1) - (return (i32.const 2)) - (return (i32.const 3)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 3)) + ) ) (i32.const 4) ) @@ -254,8 +258,12 @@ (call $nothing) (drop (local.get $x)) (if (i32.const 1) - (return (i32.const 2)) - (return (i32.const 3)) + (then + (return (i32.const 2)) + ) + (else + (return (i32.const 3)) + ) ) (i32.const 4) ) diff --git a/test/passes/ssa-nomerge_enable-simd.txt b/test/passes/ssa-nomerge_enable-simd.txt index 55105fe91ed..4c7a186ebce 100644 --- a/test/passes/ssa-nomerge_enable-simd.txt +++ b/test/passes/ssa-nomerge_enable-simd.txt @@ -56,14 +56,20 @@ (drop (if (result i32) (i32.const 1) - (i32.const 0) - (i32.const 0) + (then + (i32.const 0) + ) + (else + (i32.const 0) + ) ) ) (if (i32.const 1) - (local.set $x - (i32.const 1) + (then + (local.set $x + (i32.const 1) + ) ) ) (drop @@ -71,8 +77,10 @@ ) (if (i32.const 1) - (local.set $p - (i32.const 1) + (then + (local.set $p + (i32.const 1) + ) ) ) (drop @@ -80,19 +88,27 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 2) + (then + (local.set $x + (i32.const 2) + ) + ) + (else + (nop) ) - (nop) ) (drop (local.get $x) ) (if (i32.const 1) - (nop) - (local.set $x - (i32.const 3) + (then + (nop) + ) + (else + (local.set $x + (i32.const 3) + ) ) ) (drop @@ -100,11 +116,15 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 4) + (then + (local.set $x + (i32.const 4) + ) ) - (local.set $x - (i32.const 5) + (else + (local.set $x + (i32.const 5) + ) ) ) (drop @@ -112,10 +132,12 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 6) + (then + (local.set $x + (i32.const 6) + ) ) - (block + (else (local.set $3 (i32.const 7) ) @@ -131,7 +153,7 @@ (func $if2 (param $x i32) (if (i32.const 1) - (block + (then (local.set $x (i32.const 1) ) @@ -172,8 +194,10 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 4) + (then + (local.set $x + (i32.const 4) + ) ) ) (call $nomerge @@ -189,11 +213,15 @@ ) (if (i32.const 1) - (local.set $x - (i32.const 6) + (then + (local.set $x + (i32.const 6) + ) ) - (local.set $x - (i32.const 7) + (else + (local.set $x + (i32.const 7) + ) ) ) (call $nomerge diff --git a/test/passes/ssa-nomerge_enable-simd.wast b/test/passes/ssa-nomerge_enable-simd.wast index fa1187a7fdf..f99febe3e5d 100644 --- a/test/passes/ssa-nomerge_enable-simd.wast +++ b/test/passes/ssa-nomerge_enable-simd.wast @@ -25,46 +25,70 @@ (drop (if i32 (i32.const 1) - (local.get $x) - (local.get $y) + (then + (local.get $x) + ) + (else + (local.get $y) + ) ) ) (if (i32.const 1) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) ) (drop (local.get $x)) ;; same but with param (if (i32.const 1) - (local.set $p (i32.const 1)) + (then + (local.set $p (i32.const 1)) + ) ) (drop (local.get $p)) ;; if-else (if (i32.const 1) - (local.set $x (i32.const 2)) - (nop) + (then + (local.set $x (i32.const 2)) + ) + (else + (nop) + ) ) (drop (local.get $x)) (if (i32.const 1) - (nop) - (local.set $x (i32.const 3)) + (then + (nop) + ) + (else + (local.set $x (i32.const 3)) + ) ) (drop (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 4)) - (local.set $x (i32.const 5)) + (then + (local.set $x (i32.const 4)) + ) + (else + (local.set $x (i32.const 5)) + ) ) (drop (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 6)) - (block - (local.set $x (i32.const 7)) - (local.set $x (i32.const 8)) + (then + (local.set $x (i32.const 6)) + ) + (else + (block + (local.set $x (i32.const 7)) + (local.set $x (i32.const 8)) + ) ) ) (drop (local.get $x)) @@ -72,9 +96,11 @@ (func $if2 (param $x i32) (if (i32.const 1) - (block - (local.set $x (i32.const 1)) - (drop (local.get $x)) ;; use between phi set and use + (then + (block + (local.set $x (i32.const 1)) + (drop (local.get $x)) ;; use between phi set and use + ) ) ) (drop (local.get $x)) @@ -88,14 +114,20 @@ (local.set $x (i32.const 3)) ;; but this reaches a merge later (call $nomerge (local.get $x) (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 4)) + (then + (local.set $x (i32.const 4)) + ) ) (call $nomerge (local.get $x) (local.get $x)) (local.set $x (i32.const 5)) ;; this is good again (call $nomerge (local.get $x) (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 6)) ;; these merge, - (local.set $x (i32.const 7)) ;; so no + (then + (local.set $x (i32.const 6)) ;; these merge, + ) + (else + (local.set $x (i32.const 7)) ;; so no + ) ) (call $nomerge (local.get $x) (local.get $x)) ) diff --git a/test/passes/ssa_enable-threads.txt b/test/passes/ssa_enable-threads.txt index d159e0e4158..e2ea811fe61 100644 --- a/test/passes/ssa_enable-threads.txt +++ b/test/passes/ssa_enable-threads.txt @@ -73,17 +73,23 @@ (drop (if (result i32) (i32.const 1) - (i32.const 0) - (i32.const 0) + (then + (i32.const 0) + ) + (else + (i32.const 0) + ) ) ) (if (i32.const 1) - (local.set $3 - (local.tee $15 - (local.tee $14 - (local.tee $12 - (i32.const 1) + (then + (local.set $3 + (local.tee $15 + (local.tee $14 + (local.tee $12 + (i32.const 1) + ) ) ) ) @@ -94,9 +100,11 @@ ) (if (i32.const 1) - (local.set $4 - (local.tee $13 - (i32.const 1) + (then + (local.set $4 + (local.tee $13 + (i32.const 1) + ) ) ) ) @@ -105,24 +113,32 @@ ) (if (i32.const 1) - (local.set $5 - (local.tee $15 - (local.tee $14 - (i32.const 2) + (then + (local.set $5 + (local.tee $15 + (local.tee $14 + (i32.const 2) + ) ) ) ) - (nop) + (else + (nop) + ) ) (drop (local.get $14) ) (if (i32.const 1) - (nop) - (local.set $6 - (local.tee $15 - (i32.const 3) + (then + (nop) + ) + (else + (local.set $6 + (local.tee $15 + (i32.const 3) + ) ) ) ) @@ -131,14 +147,18 @@ ) (if (i32.const 1) - (local.set $7 - (local.tee $16 - (i32.const 4) + (then + (local.set $7 + (local.tee $16 + (i32.const 4) + ) ) ) - (local.set $8 - (local.tee $16 - (i32.const 5) + (else + (local.set $8 + (local.tee $16 + (i32.const 5) + ) ) ) ) @@ -147,12 +167,14 @@ ) (if (i32.const 1) - (local.set $9 - (local.tee $17 - (i32.const 6) + (then + (local.set $9 + (local.tee $17 + (i32.const 6) + ) ) ) - (block + (else (local.set $10 (i32.const 7) ) @@ -177,7 +199,7 @@ (block (if (i32.const 1) - (block + (then (local.set $1 (local.tee $2 (i32.const 1) @@ -239,7 +261,7 @@ ) (if (i32.const 3) - (block + (then (local.set $2 (local.tee $6 (i32.const 1) @@ -264,19 +286,27 @@ ) (if (i32.const 5) - (br $out) + (then + (br $out) + ) ) (drop (local.get $3) ) (if (i32.const 6) - (nop) + (then + (nop) + ) ) (if (i32.const 7) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) (block $in (local.set $4 @@ -453,7 +483,9 @@ (block $stop (if (i32.const 1) - (br $stop) + (then + (br $stop) + ) ) (local.set $inc (i32.add @@ -493,7 +525,9 @@ (loop $more (if (i32.const 1) - (br $stop) + (then + (br $stop) + ) ) (local.set $inc (i32.add @@ -531,7 +565,9 @@ (block $out1 (if (local.get $3) - (br $out1) + (then + (br $out1) + ) ) (local.set $1 (local.tee $4 @@ -547,7 +583,9 @@ (block $out2 (if (local.get $4) - (br $out2) + (then + (br $out2) + ) ) (local.set $2 (local.tee $4 @@ -572,7 +610,9 @@ ) (if (local.get $1) - (br $out1) + (then + (br $out1) + ) ) (br $loop1) ) @@ -581,7 +621,9 @@ (block $out2 (if (local.get $3) - (br $out2) + (then + (br $out2) + ) ) (local.set $2 (local.tee $3 @@ -612,12 +654,16 @@ (loop $loop1 (if (local.get $3) - (br $out) + (then + (br $out) + ) ) (loop $loop2 (if (local.get $4) - (br $out) + (then + (br $out) + ) ) (local.set $1 (local.tee $5 @@ -665,12 +711,16 @@ (loop $loop1 (if (local.get $3) - (br $out) + (then + (br $out) + ) ) (loop $loop2 (if (local.get $4) - (br $out) + (then + (br $out) + ) ) (local.set $1 (local.tee $5 @@ -711,8 +761,10 @@ (i32.eqz (global.get $global$0) ) - (return - (local.get $4) + (then + (return + (local.get $4) + ) ) ) (global.set $global$0 @@ -758,8 +810,10 @@ (i32.eqz (global.get $global$0) ) - (return - (i32.const 12345) + (then + (return + (i32.const 12345) + ) ) ) (global.set $global$0 @@ -769,11 +823,13 @@ (i32.eqz (local.get $7) ) - (br_if $label$1 - (i32.eqz - (local.tee $4 - (local.tee $7 - (i32.const 1) + (then + (br_if $label$1 + (i32.eqz + (local.tee $4 + (local.tee $7 + (i32.const 1) + ) ) ) ) diff --git a/test/passes/ssa_enable-threads.wast b/test/passes/ssa_enable-threads.wast index bbfad89bf99..a368f3c348f 100644 --- a/test/passes/ssa_enable-threads.wast +++ b/test/passes/ssa_enable-threads.wast @@ -24,46 +24,70 @@ (drop (if i32 (i32.const 1) - (local.get $x) - (local.get $y) + (then + (local.get $x) + ) + (else + (local.get $y) + ) ) ) (if (i32.const 1) - (local.set $x (i32.const 1)) + (then + (local.set $x (i32.const 1)) + ) ) (drop (local.get $x)) ;; same but with param (if (i32.const 1) - (local.set $p (i32.const 1)) + (then + (local.set $p (i32.const 1)) + ) ) (drop (local.get $p)) ;; if-else (if (i32.const 1) - (local.set $x (i32.const 2)) - (nop) + (then + (local.set $x (i32.const 2)) + ) + (else + (nop) + ) ) (drop (local.get $x)) (if (i32.const 1) - (nop) - (local.set $x (i32.const 3)) + (then + (nop) + ) + (else + (local.set $x (i32.const 3)) + ) ) (drop (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 4)) - (local.set $x (i32.const 5)) + (then + (local.set $x (i32.const 4)) + ) + (else + (local.set $x (i32.const 5)) + ) ) (drop (local.get $x)) (if (i32.const 1) - (local.set $x (i32.const 6)) - (block - (local.set $x (i32.const 7)) - (local.set $x (i32.const 8)) + (then + (local.set $x (i32.const 6)) + ) + (else + (block + (local.set $x (i32.const 7)) + (local.set $x (i32.const 8)) + ) ) ) (drop (local.get $x)) @@ -71,9 +95,11 @@ (func $if2 (param $x i32) (if (i32.const 1) - (block - (local.set $x (i32.const 1)) - (drop (local.get $x)) ;; use between phi set and use + (then + (block + (local.set $x (i32.const 1)) + (drop (local.get $x)) ;; use between phi set and use + ) ) ) (drop (local.get $x)) @@ -92,25 +118,35 @@ (br_if $out (i32.const 2)) (drop (local.get $x)) (if (i32.const 3) - (block - (local.set $x (i32.const 1)) - (drop (local.get $x)) - (br $out) + (then + (block + (local.set $x (i32.const 1)) + (drop (local.get $x)) + (br $out) + ) ) ) (drop (local.get $x)) (local.set $x (i32.const 4)) (drop (local.get $x)) (if (i32.const 5) - (br $out) + (then + (br $out) + ) ) (drop (local.get $x)) (if (i32.const 6) - (nop) + (then + (nop) + ) ) (if (i32.const 7) - (nop) - (nop) + (then + (nop) + ) + (else + (nop) + ) ) ;; finally, switching (block $in @@ -179,7 +215,9 @@ (block $stop (if (i32.const 1) - (br $stop) + (then + (br $stop) + ) ) (local.set $inc (i32.add @@ -206,7 +244,9 @@ (loop $more (if (i32.const 1) - (br $stop) + (then + (br $stop) + ) ) (local.set $inc (i32.add @@ -228,7 +268,9 @@ (block $out1 (if (local.get $param) - (br $out1) + (then + (br $out1) + ) ) (local.set $param (i32.const 1)) (br $loop1) @@ -238,7 +280,9 @@ (block $out2 (if (local.get $param) - (br $out2) + (then + (br $out2) + ) ) (local.set $param (i32.const 2)) (br $loop2) @@ -252,7 +296,9 @@ (local.set $param (i32.const 1)) (if (local.get $param) - (br $out1) + (then + (br $out1) + ) ) (br $loop1) ) @@ -261,7 +307,9 @@ (block $out2 (if (local.get $param) - (br $out2) + (then + (br $out2) + ) ) (local.set $param (i32.const 2)) (br $loop2) @@ -274,12 +322,16 @@ (loop $loop1 (if (local.get $x) - (br $out) + (then + (br $out) + ) ) (loop $loop2 (if (local.get $x) - (br $out) + (then + (br $out) + ) ) (local.set $x (i32.const 1)) (br $loop2) @@ -296,12 +348,16 @@ (loop $loop1 (if (local.get $x) - (br $out) + (then + (br $out) + ) ) (loop $loop2 (if (local.get $x) - (br $out) + (then + (br $out) + ) ) (local.set $x (i32.const 1)) (br_if $loop2 (i32.const 3)) ;; add fallthrough @@ -320,8 +376,10 @@ (i32.eqz (global.get $global$0) ) - (return - (local.get $result) ;; we eventually reach here + (then + (return + (local.get $result) ;; we eventually reach here + ) ) ) (global.set $global$0 @@ -352,8 +410,10 @@ (i32.eqz (global.get $global$0) ) - (return - (i32.const 12345) + (then + (return + (i32.const 12345) + ) ) ) (global.set $global$0 @@ -363,10 +423,12 @@ (i32.eqz (local.get $var$0) ;; check $0 here. this will get a phi var ) - (br_if $label$1 - (i32.eqz - (local.tee $var$0 ;; set $0 to 1. here the two diverge. for the phi, we'll get a set here and above - (i32.const 1) + (then + (br_if $label$1 + (i32.eqz + (local.tee $var$0 ;; set $0 to 1. here the two diverge. for the phi, we'll get a set here and above + (i32.const 1) + ) ) ) ) diff --git a/test/passes/ssa_fuzz-exec_enable-threads.txt b/test/passes/ssa_fuzz-exec_enable-threads.txt index f9d49d5bbaa..04d6ef59a6e 100644 --- a/test/passes/ssa_fuzz-exec_enable-threads.txt +++ b/test/passes/ssa_fuzz-exec_enable-threads.txt @@ -21,102 +21,120 @@ (block $label$1 (result i32) (if (result i32) (i32.const 0) - (unreachable) - (block $label$4 (result i32) - (loop $label$5 - (block $label$6 - (block $label$7 - (local.set $8 - (if (result i32) - (local.get $10) - (select - (loop $label$9 (result i32) - (if (result i32) - (local.tee $4 - (i32.const 16384) + (then + (unreachable) + ) + (else + (block $label$4 (result i32) + (loop $label$5 + (block $label$6 + (block $label$7 + (local.set $8 + (if (result i32) + (local.get $10) + (then + (select + (loop $label$9 (result i32) + (if (result i32) + (local.tee $4 + (i32.const 16384) + ) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) + ) ) - (i32.const 1) - (i32.const 0) - ) - ) - (br_if $label$4 - (i32.const 0) - (local.tee $var$1 - (local.tee $5 - (block $label$12 (result i32) - (br_if $label$5 - (br $label$6) + (br_if $label$4 + (i32.const 0) + (local.tee $var$1 + (local.tee $5 + (block $label$12 (result i32) + (br_if $label$5 + (br $label$6) + ) + (unreachable) + ) ) - (unreachable) ) ) + (i32.const 1) ) ) - (i32.const 1) - ) - (block (result i32) - (loop $label$15 - (if - (i32.const 0) - (return - (local.get $11) + (else + (loop $label$15 + (if + (i32.const 0) + (then + (return + (local.get $11) + ) + ) ) - ) - (if - (local.tee $var$1 - (local.tee $6 - (local.tee $11 + (if + (local.tee $var$1 + (local.tee $6 + (local.tee $11 + (i32.const 0) + ) + ) + ) + (then + (br_if $label$15 (i32.const 0) ) ) ) (br_if $label$15 - (i32.const 0) - ) - ) - (br_if $label$15 - (i32.eqz - (local.tee $7 - (local.tee $11 - (local.tee $10 - (i32.const 129) + (i32.eqz + (local.tee $7 + (local.tee $11 + (local.tee $10 + (i32.const 129) + ) ) ) ) ) ) + (i32.const -5742806) ) - (i32.const -5742806) ) ) ) - ) - (br_if $label$6 - (if (result i32) - (local.get $var$1) - (unreachable) - (block $label$25 (result i32) - (local.set $9 - (block $label$26 (result f64) - (drop - (br_if $label$4 - (br_if $label$25 - (br $label$5) - (i32.const 0) + (br_if $label$6 + (if (result i32) + (local.get $var$1) + (then + (unreachable) + ) + (else + (block $label$25 (result i32) + (local.set $9 + (block $label$26 (result f64) + (drop + (br_if $label$4 + (br_if $label$25 + (br $label$5) + (i32.const 0) + ) + (i32.const 0) + ) ) - (i32.const 0) + (f64.const 1) ) ) - (f64.const 1) + (i32.const 0) ) ) - (i32.const 0) ) ) ) ) + (local.get $4) ) - (local.get $4) ) ) ) diff --git a/test/passes/ssa_fuzz-exec_enable-threads.wast b/test/passes/ssa_fuzz-exec_enable-threads.wast index 5917a3eb360..7dd2fcc7374 100644 --- a/test/passes/ssa_fuzz-exec_enable-threads.wast +++ b/test/passes/ssa_fuzz-exec_enable-threads.wast @@ -12,98 +12,118 @@ (block $label$1 (result i32) (if (result i32) (i32.const 0) - (unreachable) - (block $label$4 (result i32) - (loop $label$5 - (block $label$6 - (block $label$7 - (local.set $var$0 - (if (result i32) - (local.get $var$2) - (select - (loop $label$9 (result i32) - (if (result i32) - (local.tee $var$2 - (i32.const 16384) + (then + (unreachable) + ) + (else + (block $label$4 (result i32) + (loop $label$5 + (block $label$6 + (block $label$7 + (local.set $var$0 + (if (result i32) + (local.get $var$2) + (then + (select + (loop $label$9 (result i32) + (if (result i32) + (local.tee $var$2 + (i32.const 16384) + ) + (then + (i32.const 1) + ) + (else + (i32.const 0) + ) + ) ) - (i32.const 1) - (i32.const 0) - ) - ) - (br_if $label$4 - (i32.const 0) - (local.tee $var$1 - (local.tee $var$2 - (block $label$12 (result i32) - (br_if $label$5 - (br $label$6) + (br_if $label$4 + (i32.const 0) + (local.tee $var$1 + (local.tee $var$2 + (block $label$12 (result i32) + (br_if $label$5 + (br $label$6) + ) + (unreachable) + ) ) - (unreachable) ) ) + (i32.const 1) ) ) - (i32.const 1) - ) - (block (result i32) - (loop $label$15 - (if - (i32.const 0) - (return - (local.get $var$2) - ) - ) - (if - (local.tee $var$1 - (local.tee $var$2 + (else + (block (result i32) + (loop $label$15 + (if (i32.const 0) + (then + (return + (local.get $var$2) + ) + ) ) - ) - (block - (br_if $label$15 - (i32.const 0) + (if + (local.tee $var$1 + (local.tee $var$2 + (i32.const 0) + ) + ) + (then + (block + (br_if $label$15 + (i32.const 0) + ) + ) + ) ) - ) - ) - (br_if $label$15 - (i32.eqz - (local.tee $var$2 - (i32.const 129) + (br_if $label$15 + (i32.eqz + (local.tee $var$2 + (i32.const 129) + ) + ) ) ) + (i32.const -5742806) ) ) - (i32.const -5742806) ) ) ) - ) - (br_if $label$6 - (if (result i32) - (local.get $var$1) - (unreachable) - (block $label$25 (result i32) - (local.set $var$3 - (block $label$26 (result f64) - (drop - (br_if $label$4 - (br_if $label$25 - (br $label$5) - (i32.const 0) + (br_if $label$6 + (if (result i32) + (local.get $var$1) + (then + (unreachable) + ) + (else + (block $label$25 (result i32) + (local.set $var$3 + (block $label$26 (result f64) + (drop + (br_if $label$4 + (br_if $label$25 + (br $label$5) + (i32.const 0) + ) + (i32.const 0) + ) ) - (i32.const 0) + (f64.const 1) ) ) - (f64.const 1) + (i32.const 0) ) ) - (i32.const 0) ) ) ) ) + (local.get $var$2) ) - (local.get $var$2) ) ) ) diff --git a/test/passes/stack-check_enable-mutable-globals.txt b/test/passes/stack-check_enable-mutable-globals.txt index a2d7f374de9..43e352bdbad 100644 --- a/test/passes/stack-check_enable-mutable-globals.txt +++ b/test/passes/stack-check_enable-mutable-globals.txt @@ -22,7 +22,9 @@ (global.get $__stack_limit) ) ) - (unreachable) + (then + (unreachable) + ) ) (global.set $sp (local.get $0) diff --git a/test/passes/trap-mode-clamp.txt b/test/passes/trap-mode-clamp.txt index e41b4e0e30b..27512712e2a 100644 --- a/test/passes/trap-mode-clamp.txt +++ b/test/passes/trap-mode-clamp.txt @@ -110,21 +110,33 @@ (local.get $0) (local.get $0) ) - (i32.const -2147483648) - (if (result i32) - (f32.ge - (local.get $0) - (f32.const 2147483648) - ) + (then (i32.const -2147483648) + ) + (else (if (result i32) - (f32.le + (f32.ge (local.get $0) - (f32.const -2147483648) + (f32.const 2147483648) ) - (i32.const -2147483648) - (i32.trunc_f32_s - (local.get $0) + (then + (i32.const -2147483648) + ) + (else + (if (result i32) + (f32.le + (local.get $0) + (f32.const -2147483648) + ) + (then + (i32.const -2147483648) + ) + (else + (i32.trunc_f32_s + (local.get $0) + ) + ) + ) ) ) ) @@ -136,21 +148,33 @@ (local.get $0) (local.get $0) ) - (i64.const -9223372036854775808) - (if (result i64) - (f32.ge - (local.get $0) - (f32.const 9223372036854775808) - ) + (then (i64.const -9223372036854775808) + ) + (else (if (result i64) - (f32.le + (f32.ge (local.get $0) - (f32.const -9223372036854775808) + (f32.const 9223372036854775808) ) - (i64.const -9223372036854775808) - (i64.trunc_f32_s - (local.get $0) + (then + (i64.const -9223372036854775808) + ) + (else + (if (result i64) + (f32.le + (local.get $0) + (f32.const -9223372036854775808) + ) + (then + (i64.const -9223372036854775808) + ) + (else + (i64.trunc_f32_s + (local.get $0) + ) + ) + ) ) ) ) @@ -162,21 +186,33 @@ (local.get $0) (local.get $0) ) - (i32.const 0) - (if (result i32) - (f32.ge - (local.get $0) - (f32.const 4294967296) - ) + (then (i32.const 0) + ) + (else (if (result i32) - (f32.le + (f32.ge (local.get $0) - (f32.const -1) + (f32.const 4294967296) ) - (i32.const 0) - (i32.trunc_f32_u - (local.get $0) + (then + (i32.const 0) + ) + (else + (if (result i32) + (f32.le + (local.get $0) + (f32.const -1) + ) + (then + (i32.const 0) + ) + (else + (i32.trunc_f32_u + (local.get $0) + ) + ) + ) ) ) ) @@ -188,21 +224,33 @@ (local.get $0) (local.get $0) ) - (i64.const 0) - (if (result i64) - (f32.ge - (local.get $0) - (f32.const 18446744073709551615) - ) + (then (i64.const 0) + ) + (else (if (result i64) - (f32.le + (f32.ge (local.get $0) - (f32.const -1) + (f32.const 18446744073709551615) ) - (i64.const 0) - (i64.trunc_f32_u - (local.get $0) + (then + (i64.const 0) + ) + (else + (if (result i64) + (f32.le + (local.get $0) + (f32.const -1) + ) + (then + (i64.const 0) + ) + (else + (i64.trunc_f32_u + (local.get $0) + ) + ) + ) ) ) ) @@ -214,21 +262,33 @@ (local.get $0) (local.get $0) ) - (i32.const -2147483648) - (if (result i32) - (f64.ge - (local.get $0) - (f64.const 2147483648) - ) + (then (i32.const -2147483648) + ) + (else (if (result i32) - (f64.le + (f64.ge (local.get $0) - (f64.const -2147483649) + (f64.const 2147483648) ) - (i32.const -2147483648) - (i32.trunc_f64_s - (local.get $0) + (then + (i32.const -2147483648) + ) + (else + (if (result i32) + (f64.le + (local.get $0) + (f64.const -2147483649) + ) + (then + (i32.const -2147483648) + ) + (else + (i32.trunc_f64_s + (local.get $0) + ) + ) + ) ) ) ) @@ -240,21 +300,33 @@ (local.get $0) (local.get $0) ) - (i64.const -9223372036854775808) - (if (result i64) - (f64.ge - (local.get $0) - (f64.const 9223372036854775808) - ) + (then (i64.const -9223372036854775808) + ) + (else (if (result i64) - (f64.le + (f64.ge (local.get $0) - (f64.const -9223372036854775808) + (f64.const 9223372036854775808) ) - (i64.const -9223372036854775808) - (i64.trunc_f64_s - (local.get $0) + (then + (i64.const -9223372036854775808) + ) + (else + (if (result i64) + (f64.le + (local.get $0) + (f64.const -9223372036854775808) + ) + (then + (i64.const -9223372036854775808) + ) + (else + (i64.trunc_f64_s + (local.get $0) + ) + ) + ) ) ) ) @@ -266,21 +338,33 @@ (local.get $0) (local.get $0) ) - (i32.const 0) - (if (result i32) - (f64.ge - (local.get $0) - (f64.const 4294967296) - ) + (then (i32.const 0) + ) + (else (if (result i32) - (f64.le + (f64.ge (local.get $0) - (f64.const -1) + (f64.const 4294967296) ) - (i32.const 0) - (i32.trunc_f64_u - (local.get $0) + (then + (i32.const 0) + ) + (else + (if (result i32) + (f64.le + (local.get $0) + (f64.const -1) + ) + (then + (i32.const 0) + ) + (else + (i32.trunc_f64_u + (local.get $0) + ) + ) + ) ) ) ) @@ -292,21 +376,33 @@ (local.get $0) (local.get $0) ) - (i64.const 0) - (if (result i64) - (f64.ge - (local.get $0) - (f64.const 18446744073709551615) - ) + (then (i64.const 0) + ) + (else (if (result i64) - (f64.le + (f64.ge (local.get $0) - (f64.const -1) + (f64.const 18446744073709551615) ) - (i64.const 0) - (i64.trunc_f64_u - (local.get $0) + (then + (i64.const 0) + ) + (else + (if (result i64) + (f64.le + (local.get $0) + (f64.const -1) + ) + (then + (i64.const 0) + ) + (else + (i64.trunc_f64_u + (local.get $0) + ) + ) + ) ) ) ) @@ -317,22 +413,30 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (if (result i32) - (i32.and - (i32.eq - (local.get $0) - (i32.const -2147483648) + (then + (i32.const 0) + ) + (else + (if (result i32) + (i32.and + (i32.eq + (local.get $0) + (i32.const -2147483648) + ) + (i32.eq + (local.get $1) + (i32.const -1) + ) ) - (i32.eq - (local.get $1) - (i32.const -1) + (then + (i32.const 0) + ) + (else + (i32.div_s + (local.get $0) + (local.get $1) + ) ) - ) - (i32.const 0) - (i32.div_s - (local.get $0) - (local.get $1) ) ) ) @@ -342,10 +446,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.rem_s - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.rem_s + (local.get $0) + (local.get $1) + ) ) ) ) @@ -354,10 +462,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.div_u - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.div_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -366,10 +478,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.rem_u - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.rem_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -378,22 +494,30 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (if (result i64) - (i32.and - (i64.eq - (local.get $0) - (i64.const -9223372036854775808) + (then + (i64.const 0) + ) + (else + (if (result i64) + (i32.and + (i64.eq + (local.get $0) + (i64.const -9223372036854775808) + ) + (i64.eq + (local.get $1) + (i64.const -1) + ) ) - (i64.eq - (local.get $1) - (i64.const -1) + (then + (i64.const 0) + ) + (else + (i64.div_s + (local.get $0) + (local.get $1) + ) ) - ) - (i64.const 0) - (i64.div_s - (local.get $0) - (local.get $1) ) ) ) @@ -403,10 +527,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.rem_s - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.rem_s + (local.get $0) + (local.get $1) + ) ) ) ) @@ -415,10 +543,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.div_u - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.div_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -427,10 +559,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.rem_u - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.rem_u + (local.get $0) + (local.get $1) + ) ) ) ) diff --git a/test/passes/trap-mode-js.txt b/test/passes/trap-mode-js.txt index 39cb28de6d4..b43d7e9503c 100644 --- a/test/passes/trap-mode-js.txt +++ b/test/passes/trap-mode-js.txt @@ -114,21 +114,33 @@ (local.get $0) (local.get $0) ) - (i64.const -9223372036854775808) - (if (result i64) - (f32.ge - (local.get $0) - (f32.const 9223372036854775808) - ) + (then (i64.const -9223372036854775808) + ) + (else (if (result i64) - (f32.le + (f32.ge (local.get $0) - (f32.const -9223372036854775808) + (f32.const 9223372036854775808) ) - (i64.const -9223372036854775808) - (i64.trunc_f32_s - (local.get $0) + (then + (i64.const -9223372036854775808) + ) + (else + (if (result i64) + (f32.le + (local.get $0) + (f32.const -9223372036854775808) + ) + (then + (i64.const -9223372036854775808) + ) + (else + (i64.trunc_f32_s + (local.get $0) + ) + ) + ) ) ) ) @@ -140,21 +152,33 @@ (local.get $0) (local.get $0) ) - (i64.const 0) - (if (result i64) - (f32.ge - (local.get $0) - (f32.const 18446744073709551615) - ) + (then (i64.const 0) + ) + (else (if (result i64) - (f32.le + (f32.ge (local.get $0) - (f32.const -1) + (f32.const 18446744073709551615) ) - (i64.const 0) - (i64.trunc_f32_u - (local.get $0) + (then + (i64.const 0) + ) + (else + (if (result i64) + (f32.le + (local.get $0) + (f32.const -1) + ) + (then + (i64.const 0) + ) + (else + (i64.trunc_f32_u + (local.get $0) + ) + ) + ) ) ) ) @@ -166,21 +190,33 @@ (local.get $0) (local.get $0) ) - (i64.const -9223372036854775808) - (if (result i64) - (f64.ge - (local.get $0) - (f64.const 9223372036854775808) - ) + (then (i64.const -9223372036854775808) + ) + (else (if (result i64) - (f64.le + (f64.ge (local.get $0) - (f64.const -9223372036854775808) + (f64.const 9223372036854775808) ) - (i64.const -9223372036854775808) - (i64.trunc_f64_s - (local.get $0) + (then + (i64.const -9223372036854775808) + ) + (else + (if (result i64) + (f64.le + (local.get $0) + (f64.const -9223372036854775808) + ) + (then + (i64.const -9223372036854775808) + ) + (else + (i64.trunc_f64_s + (local.get $0) + ) + ) + ) ) ) ) @@ -192,21 +228,33 @@ (local.get $0) (local.get $0) ) - (i64.const 0) - (if (result i64) - (f64.ge - (local.get $0) - (f64.const 18446744073709551615) - ) + (then (i64.const 0) + ) + (else (if (result i64) - (f64.le + (f64.ge (local.get $0) - (f64.const -1) + (f64.const 18446744073709551615) ) - (i64.const 0) - (i64.trunc_f64_u - (local.get $0) + (then + (i64.const 0) + ) + (else + (if (result i64) + (f64.le + (local.get $0) + (f64.const -1) + ) + (then + (i64.const 0) + ) + (else + (i64.trunc_f64_u + (local.get $0) + ) + ) + ) ) ) ) @@ -217,22 +265,30 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (if (result i32) - (i32.and - (i32.eq - (local.get $0) - (i32.const -2147483648) + (then + (i32.const 0) + ) + (else + (if (result i32) + (i32.and + (i32.eq + (local.get $0) + (i32.const -2147483648) + ) + (i32.eq + (local.get $1) + (i32.const -1) + ) ) - (i32.eq - (local.get $1) - (i32.const -1) + (then + (i32.const 0) + ) + (else + (i32.div_s + (local.get $0) + (local.get $1) + ) ) - ) - (i32.const 0) - (i32.div_s - (local.get $0) - (local.get $1) ) ) ) @@ -242,10 +298,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.rem_s - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.rem_s + (local.get $0) + (local.get $1) + ) ) ) ) @@ -254,10 +314,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.div_u - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.div_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -266,10 +330,14 @@ (i32.eqz (local.get $1) ) - (i32.const 0) - (i32.rem_u - (local.get $0) - (local.get $1) + (then + (i32.const 0) + ) + (else + (i32.rem_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -278,22 +346,30 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (if (result i64) - (i32.and - (i64.eq - (local.get $0) - (i64.const -9223372036854775808) + (then + (i64.const 0) + ) + (else + (if (result i64) + (i32.and + (i64.eq + (local.get $0) + (i64.const -9223372036854775808) + ) + (i64.eq + (local.get $1) + (i64.const -1) + ) ) - (i64.eq - (local.get $1) - (i64.const -1) + (then + (i64.const 0) + ) + (else + (i64.div_s + (local.get $0) + (local.get $1) + ) ) - ) - (i64.const 0) - (i64.div_s - (local.get $0) - (local.get $1) ) ) ) @@ -303,10 +379,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.rem_s - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.rem_s + (local.get $0) + (local.get $1) + ) ) ) ) @@ -315,10 +395,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.div_u - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.div_u + (local.get $0) + (local.get $1) + ) ) ) ) @@ -327,10 +411,14 @@ (i64.eqz (local.get $1) ) - (i64.const 0) - (i64.rem_u - (local.get $0) - (local.get $1) + (then + (i64.const 0) + ) + (else + (i64.rem_u + (local.get $0) + (local.get $1) + ) ) ) ) diff --git a/test/reduce/destructive.wast b/test/reduce/destructive.wast index 2670fccf94b..743141de68c 100644 --- a/test/reduce/destructive.wast +++ b/test/reduce/destructive.wast @@ -2,7 +2,9 @@ (export "x" (func $x)) (func $x (param $x i32) (result i32) (if (i32.eq (local.get $x) (i32.const 98658746)) - (unreachable) ;; this can be removed destructively, since we do not sent this param + (then + (unreachable) ;; this can be removed destructively, since we do not sent this param + ) ) (i32.const 100) ) diff --git a/test/spec/exception-handling-old.wast b/test/spec/exception-handling-old.wast index 48fbe838991..75bfe70e8aa 100644 --- a/test/spec/exception-handling-old.wast +++ b/test/spec/exception-handling-old.wast @@ -605,8 +605,12 @@ (throw $e-i32 (if (result i32) (i32.const 0) - (pop i32) ;; pop is within an if true body - (i32.const 3) + (then + (pop i32) ;; pop is within an if true body + ) + (else + (i32.const 3) + ) ) ) ) diff --git a/test/spec/old_br_if.wast b/test/spec/old_br_if.wast index 44aeffbe7a9..9ed24f15349 100644 --- a/test/spec/old_br_if.wast +++ b/test/spec/old_br_if.wast @@ -37,10 +37,10 @@ ) (func (export "as-if-then") (param i32 i32) - (block (if (local.get 0) (br_if 1 (local.get 1)) (call $dummy))) + (block (if (local.get 0) (then (br_if 1 (local.get 1)) )(else (call $dummy)))) ) (func (export "as-if-else") (param i32 i32) - (block (if (local.get 0) (call $dummy) (br_if 1 (local.get 1)))) + (block (if (local.get 0) (then (call $dummy) )(else (br_if 1 (local.get 1))))) ) (func (export "nested-block-value") (param i32) (result i32) diff --git a/test/spec/old_call.wast b/test/spec/old_call.wast index 00bd97397bf..ed2cd286bb3 100644 --- a/test/spec/old_call.wast +++ b/test/spec/old_call.wast @@ -46,41 +46,61 @@ (func $fac (export "fac") (param i64) (result i64) (if i64 (i64.eqz (local.get 0)) - (i64.const 1) - (i64.mul (local.get 0) (call $fac (i64.sub (local.get 0) (i64.const 1)))) + (then + (i64.const 1) + ) + (else + (i64.mul (local.get 0) (call $fac (i64.sub (local.get 0) (i64.const 1)))) + ) ) ) (func $fac-acc (export "fac-acc") (param i64 i64) (result i64) (if i64 (i64.eqz (local.get 0)) - (local.get 1) - (call $fac-acc - (i64.sub (local.get 0) (i64.const 1)) - (i64.mul (local.get 0) (local.get 1)) + (then + (local.get 1) + ) + (else + (call $fac-acc + (i64.sub (local.get 0) (i64.const 1)) + (i64.mul (local.get 0) (local.get 1)) + ) ) ) ) (func $fib (export "fib") (param i64) (result i64) (if i64 (i64.le_u (local.get 0) (i64.const 1)) - (i64.const 1) - (i64.add - (call $fib (i64.sub (local.get 0) (i64.const 2))) - (call $fib (i64.sub (local.get 0) (i64.const 1))) + (then + (i64.const 1) + ) + (else + (i64.add + (call $fib (i64.sub (local.get 0) (i64.const 2))) + (call $fib (i64.sub (local.get 0) (i64.const 1))) + ) ) ) ) (func $even (export "even") (param i64) (result i32) (if i32 (i64.eqz (local.get 0)) - (i32.const 44) - (call $odd (i64.sub (local.get 0) (i64.const 1))) + (then + (i32.const 44) + ) + (else + (call $odd (i64.sub (local.get 0) (i64.const 1))) + ) ) ) (func $odd (export "odd") (param i64) (result i32) (if i32 (i64.eqz (local.get 0)) - (i32.const 99) - (call $even (i64.sub (local.get 0) (i64.const 1))) + (then + (i32.const 99) + ) + (else + (call $even (i64.sub (local.get 0) (i64.const 1))) + ) ) ) diff --git a/test/spec/old_call_indirect.wast b/test/spec/old_call_indirect.wast index 41f4316f658..00ecd08633c 100644 --- a/test/spec/old_call_indirect.wast +++ b/test/spec/old_call_indirect.wast @@ -103,12 +103,16 @@ (func $fac (export "fac") (type $over-i64) (if i64 (i64.eqz (local.get 0)) - (i64.const 1) - (i64.mul - (local.get 0) - (call_indirect (type $over-i64) - (i64.sub (local.get 0) (i64.const 1)) - (i32.const 12) + (then + (i64.const 1) + ) + (else + (i64.mul + (local.get 0) + (call_indirect (type $over-i64) + (i64.sub (local.get 0) (i64.const 1)) + (i32.const 12) + ) ) ) ) @@ -116,15 +120,19 @@ (func $fib (export "fib") (type $over-i64) (if i64 (i64.le_u (local.get 0) (i64.const 1)) - (i64.const 1) - (i64.add - (call_indirect (type $over-i64) - (i64.sub (local.get 0) (i64.const 2)) - (i32.const 13) - ) - (call_indirect (type $over-i64) - (i64.sub (local.get 0) (i64.const 1)) - (i32.const 13) + (then + (i64.const 1) + ) + (else + (i64.add + (call_indirect (type $over-i64) + (i64.sub (local.get 0) (i64.const 2)) + (i32.const 13) + ) + (call_indirect (type $over-i64) + (i64.sub (local.get 0) (i64.const 1)) + (i32.const 13) + ) ) ) ) @@ -132,19 +140,27 @@ (func $even (export "even") (param i32) (result i32) (if i32 (i32.eqz (local.get 0)) - (i32.const 44) - (call_indirect (type $over-i32) - (i32.sub (local.get 0) (i32.const 1)) - (i32.const 15) + (then + (i32.const 44) + ) + (else + (call_indirect (type $over-i32) + (i32.sub (local.get 0) (i32.const 1)) + (i32.const 15) + ) ) ) ) (func $odd (export "odd") (param i32) (result i32) (if i32 (i32.eqz (local.get 0)) - (i32.const 99) - (call_indirect (type $over-i32) - (i32.sub (local.get 0) (i32.const 1)) - (i32.const 14) + (then + (i32.const 99) + ) + (else + (call_indirect (type $over-i32) + (i32.sub (local.get 0) (i32.const 1)) + (i32.const 14) + ) ) ) ) diff --git a/test/spec/old_float_exprs.wast b/test/spec/old_float_exprs.wast index 854e21a6243..c6e900f0399 100644 --- a/test/spec/old_float_exprs.wast +++ b/test/spec/old_float_exprs.wast @@ -897,15 +897,15 @@ ;; Test that x>> 0 < i64toi32_i32$1 >>> 0) + 0 | 0; i64toi32_i32$5 = $0$hi - i64toi32_i32$5 | 0; i64toi32_i32$5 = $0(i64toi32_i32$3 - i64toi32_i32$1 | 0 | 0, i64toi32_i32$5 | 0) | 0; i64toi32_i32$3 = i64toi32_i32$HIGH_BITS; - $8 = i64toi32_i32$5; - $8$hi = i64toi32_i32$3; + $6 = i64toi32_i32$5; + $6$hi = i64toi32_i32$3; i64toi32_i32$3 = $0$hi; - i64toi32_i32$5 = $8$hi; - i64toi32_i32$5 = __wasm_i64_mul($0_1 | 0, i64toi32_i32$3 | 0, $8 | 0, i64toi32_i32$5 | 0) | 0; + i64toi32_i32$5 = $6$hi; + i64toi32_i32$5 = __wasm_i64_mul($0_1 | 0, $0$hi | 0, $6 | 0, i64toi32_i32$5 | 0) | 0; i64toi32_i32$3 = i64toi32_i32$HIGH_BITS; - $12 = i64toi32_i32$5; - $12$hi = i64toi32_i32$3; + $8 = i64toi32_i32$5; + $8$hi = i64toi32_i32$3; } - i64toi32_i32$3 = $12$hi; - i64toi32_i32$5 = $12; + i64toi32_i32$3 = $8$hi; + i64toi32_i32$5 = $8; i64toi32_i32$HIGH_BITS = i64toi32_i32$3; return i64toi32_i32$5 | 0; } @@ -51,33 +48,30 @@ function asmFunc(imports) { function fac_rec_named(n, n$hi) { n = n | 0; n$hi = n$hi | 0; - var i64toi32_i32$3 = 0, i64toi32_i32$5 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $12 = 0, $12$hi = 0, $8 = 0, $8$hi = 0; - i64toi32_i32$2 = n; + var i64toi32_i32$3 = 0, i64toi32_i32$5 = 0, i64toi32_i32$1 = 0, $8 = 0, $8$hi = 0, $6 = 0, $6$hi = 0; i64toi32_i32$1 = 0; i64toi32_i32$3 = 0; - if ((i64toi32_i32$2 | 0) == (i64toi32_i32$3 | 0) & (n$hi | 0) == (i64toi32_i32$1 | 0) | 0) { - i64toi32_i32$2 = 0; - $12 = 1; - $12$hi = i64toi32_i32$2; + if ((n | 0) == (i64toi32_i32$3 | 0) & (n$hi | 0) == (i64toi32_i32$1 | 0) | 0) { + $8 = 1; + $8$hi = 0; } else { - i64toi32_i32$2 = n$hi; i64toi32_i32$3 = n; i64toi32_i32$1 = 1; i64toi32_i32$5 = (i64toi32_i32$3 >>> 0 < i64toi32_i32$1 >>> 0) + 0 | 0; i64toi32_i32$5 = n$hi - i64toi32_i32$5 | 0; i64toi32_i32$5 = fac_rec_named(i64toi32_i32$3 - i64toi32_i32$1 | 0 | 0, i64toi32_i32$5 | 0) | 0; i64toi32_i32$3 = i64toi32_i32$HIGH_BITS; - $8 = i64toi32_i32$5; - $8$hi = i64toi32_i32$3; + $6 = i64toi32_i32$5; + $6$hi = i64toi32_i32$3; i64toi32_i32$3 = n$hi; - i64toi32_i32$5 = $8$hi; - i64toi32_i32$5 = __wasm_i64_mul(n | 0, i64toi32_i32$3 | 0, $8 | 0, i64toi32_i32$5 | 0) | 0; + i64toi32_i32$5 = $6$hi; + i64toi32_i32$5 = __wasm_i64_mul(n | 0, n$hi | 0, $6 | 0, i64toi32_i32$5 | 0) | 0; i64toi32_i32$3 = i64toi32_i32$HIGH_BITS; - $12 = i64toi32_i32$5; - $12$hi = i64toi32_i32$3; + $8 = i64toi32_i32$5; + $8$hi = i64toi32_i32$3; } - i64toi32_i32$3 = $12$hi; - i64toi32_i32$5 = $12; + i64toi32_i32$3 = $8$hi; + i64toi32_i32$5 = $8; i64toi32_i32$HIGH_BITS = i64toi32_i32$3; return i64toi32_i32$5 | 0; } diff --git a/test/wasm2js/forward.2asm.js b/test/wasm2js/forward.2asm.js index dab073477b9..053f0f99306 100644 --- a/test/wasm2js/forward.2asm.js +++ b/test/wasm2js/forward.2asm.js @@ -12,24 +12,24 @@ function asmFunc(imports) { var Math_sqrt = Math.sqrt; function even(n) { n = n | 0; - var $10 = 0; + var $6 = 0; if ((n | 0) == (0 | 0)) { - $10 = 1 + $6 = 1 } else { - $10 = odd(n - 1 | 0 | 0) | 0 + $6 = odd(n - 1 | 0 | 0) | 0 } - return $10 | 0; + return $6 | 0; } function odd(n) { n = n | 0; - var $10 = 0; + var $6 = 0; if ((n | 0) == (0 | 0)) { - $10 = 0 + $6 = 0 } else { - $10 = even(n - 1 | 0 | 0) | 0 + $6 = even(n - 1 | 0 | 0) | 0 } - return $10 | 0; + return $6 | 0; } return { diff --git a/test/wasm2js/if_unreachable.wast b/test/wasm2js/if_unreachable.wast index 11b41d16eb1..65cd4e119ef 100644 --- a/test/wasm2js/if_unreachable.wast +++ b/test/wasm2js/if_unreachable.wast @@ -7,13 +7,17 @@ (i32.const 0) (i32.const 48) ) - (block $label$2 - (br_if $label$2 - (i32.const 0) + (then + (block $label$2 + (br_if $label$2 + (i32.const 0) + ) + (unreachable) ) + ) + (else (unreachable) ) - (unreachable) ) (unreachable) ) diff --git a/test/wasm2js/stack-modified.wast b/test/wasm2js/stack-modified.wast index b3ede238037..1ba9f30a878 100644 --- a/test/wasm2js/stack-modified.wast +++ b/test/wasm2js/stack-modified.wast @@ -21,18 +21,22 @@ (local.get $var$1) (i64.const 0) ) - (br $label$1) - (block $label$5 - (local.set $var$2 - (i64.mul - (local.get $var$1) - (local.get $var$2) + (then + (br $label$1) + ) + (else + (block $label$5 + (local.set $var$2 + (i64.mul + (local.get $var$1) + (local.get $var$2) + ) ) - ) - (local.set $var$1 - (i64.sub - (local.get $var$1) - (i64.const 1) + (local.set $var$1 + (i64.sub + (local.get $var$1) + (i64.const 1) + ) ) ) ) @@ -58,18 +62,22 @@ (local.get $var$1) (i64.const 0) ) - (br $label$1) - (block - (local.set $var$2 - (i64.mul - (local.get $var$1) - (local.get $var$2) + (then + (br $label$1) + ) + (else + (block + (local.set $var$2 + (i64.mul + (local.get $var$1) + (local.get $var$2) + ) ) - ) - (local.set $var$1 - (i64.sub - (local.get $var$1) - (i64.const 1) + (local.set $var$1 + (i64.sub + (local.get $var$1) + (i64.const 1) + ) ) ) ) @@ -95,18 +103,22 @@ (local.get $var$1) (i64.const 0) ) - (br $label$1) - (block - (local.set $var$2 - (i64.mul - (local.get $var$1) - (local.get $var$2) + (then + (br $label$1) + ) + (else + (block + (local.set $var$2 + (i64.mul + (local.get $var$1) + (local.get $var$2) + ) ) - ) - (local.set $var$1 - (i64.sub - (local.get $var$1) - (i64.const 1) + (local.set $var$1 + (i64.sub + (local.get $var$1) + (i64.const 1) + ) ) ) ) @@ -132,18 +144,22 @@ (local.get $var$1) (i64.const 0) ) - (br $label$1) - (block - (local.set $var$2 - (i64.mul - (local.get $var$1) - (local.get $var$2) + (then + (br $label$1) + ) + (else + (block + (local.set $var$2 + (i64.mul + (local.get $var$1) + (local.get $var$2) + ) ) - ) - (local.set $var$1 - (i64.sub - (local.get $var$1) - (i64.const 1) + (local.set $var$1 + (i64.sub + (local.get $var$1) + (i64.const 1) + ) ) ) ) @@ -169,18 +185,22 @@ (local.get $var$1) (i64.const 0) ) - (br $label$1) - (block - (local.set $var$2 - (i64.mul - (local.get $var$1) - (local.get $var$2) + (then + (br $label$1) + ) + (else + (block + (local.set $var$2 + (i64.mul + (local.get $var$1) + (local.get $var$2) + ) ) - ) - (local.set $var$1 - (i64.sub - (local.get $var$1) - (i64.const 1) + (local.set $var$1 + (i64.sub + (local.get $var$1) + (i64.const 1) + ) ) ) ) diff --git a/test/wasm2js/unreachable-get-cycle.wast b/test/wasm2js/unreachable-get-cycle.wast index 6fc714a3990..3a25fea722d 100644 --- a/test/wasm2js/unreachable-get-cycle.wast +++ b/test/wasm2js/unreachable-get-cycle.wast @@ -10,25 +10,33 @@ ) (i32.const 0) ) - (loop $label$3 - (block $label$4 - (f32.store offset=22 align=2 - (i32.const 0) - (local.get $2) - ) - (drop - (local.tee $2 - (if (result f32) - (i32.const -19666) - (local.get $2) - (unreachable) + (then + (loop $label$3 + (block $label$4 + (f32.store offset=22 align=2 + (i32.const 0) + (local.get $2) + ) + (drop + (local.tee $2 + (if (result f32) + (i32.const -19666) + (then + (local.get $2) + ) + (else + (unreachable) + ) + ) ) ) ) + (br $label$3) ) - (br $label$3) ) - (i64.const 1) + (else + (i64.const 1) + ) ) ) ) diff --git a/test/wasm2js/unreachable-later.wast b/test/wasm2js/unreachable-later.wast index 0af55221255..49a7cdb8574 100644 --- a/test/wasm2js/unreachable-later.wast +++ b/test/wasm2js/unreachable-later.wast @@ -5,14 +5,18 @@ (func $0 (; 0 ;) (type $0) (param $0 i32) (result i32) (if (global.get $global$0) - (return - (local.get $0) + (then + (return + (local.get $0) + ) ) ) (if (global.get $global$0) - (return - (local.get $0) + (then + (return + (local.get $0) + ) ) ) (global.set $global$0 @@ -29,8 +33,10 @@ (block $label$4 (result i32) (if (global.get $global$0) - (return - (local.get $0) + (then + (return + (local.get $0) + ) ) ) (drop @@ -38,48 +44,70 @@ (block $label$6 (result i32) (if (global.get $global$0) - (return - (local.get $0) + (then + (return + (local.get $0) + ) ) ) (i32.const 65445) ) - (block (result f32) - (if - (global.get $global$0) - (return - (local.get $0) + (then + (block (result f32) + (if + (global.get $global$0) + (then + (return + (local.get $0) + ) + ) ) + (f32.const 0) ) - (f32.const 0) ) - (f32.const 1) + (else + (f32.const 1) + ) ) ) (if (global.get $global$0) - (return - (local.get $0) + (then + (return + (local.get $0) + ) ) ) (i32.const 1) ) - (i32.const 32) - (i32.const 0) + (then + (i32.const 32) + ) + (else + (i32.const 0) + ) ) ) ) (i32.const 1) ) ) - (i32.const 0) - (i32.const 1) + (then + (i32.const 0) + ) + (else + (i32.const 1) + ) + ) + ) + (then + (return + (i32.const -255) ) ) - (return - (i32.const -255) + (else + (unreachable) ) - (unreachable) ) ) ) From d312604d46ff3e1e14228394a2a4536b71483520 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 4 Jan 2024 14:50:29 -0800 Subject: [PATCH 027/553] [Parser] Parse br_if correctly (#6202) The new text parser and IRBuilder were previously not differentiating between `br` and `br_if`. Handle `br_if` correctly by popping and assigning a condition. --- scripts/gen-s-parser.py | 4 +- src/gen-s-parser.inc | 8 +- src/parser/contexts.h | 6 +- src/parser/parsers.h | 7 +- src/wasm-ir-builder.h | 2 +- src/wasm-s-parser.h | 2 +- src/wasm/wasm-ir-builder.cpp | 11 +- src/wasm/wasm-s-parser.cpp | 4 +- test/lit/wat-kitchen-sink.wast | 336 ++++++++++++++++++++------------- 9 files changed, 234 insertions(+), 146 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index f716302d042..9d6e58481ff 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -24,8 +24,8 @@ ("if", "makeIf(s)"), ("then", "makeThenOrElse(s)"), ("else", "makeThenOrElse(s)"), - ("br", "makeBreak(s)"), - ("br_if", "makeBreak(s)"), + ("br", "makeBreak(s, false)"), + ("br_if", "makeBreak(s, true)"), ("br_table", "makeBreakTable(s)"), ("return", "makeReturn(s)"), ("call", "makeCall(s, /*isReturn=*/false)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 2c284d56180..cef0a6b926b 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -102,12 +102,12 @@ switch (buf[0]) { case 'r': { switch (buf[2]) { case '\0': - if (op == "br"sv) { return makeBreak(s); } + if (op == "br"sv) { return makeBreak(s, false); } goto parse_error; case '_': { switch (buf[3]) { case 'i': - if (op == "br_if"sv) { return makeBreak(s); } + if (op == "br_if"sv) { return makeBreak(s, true); } goto parse_error; case 'o': { switch (buf[6]) { @@ -3749,7 +3749,7 @@ switch (buf[0]) { switch (buf[2]) { case '\0': if (op == "br"sv) { - CHECK_ERR(makeBreak(ctx, pos)); + CHECK_ERR(makeBreak(ctx, pos, false)); return Ok{}; } goto parse_error; @@ -3757,7 +3757,7 @@ switch (buf[0]) { switch (buf[3]) { case 'i': if (op == "br_if"sv) { - CHECK_ERR(makeBreak(ctx, pos)); + CHECK_ERR(makeBreak(ctx, pos, true)); return Ok{}; } goto parse_error; diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 1cefb288da3..f489a2c056c 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -411,7 +411,7 @@ struct NullInstrParserCtx { Result<> makeCallIndirect(Index, TableIdxT*, TypeUseT, bool) { return Ok{}; } - Result<> makeBreak(Index, LabelIdxT) { return Ok{}; } + Result<> makeBreak(Index, LabelIdxT, bool) { return Ok{}; } Result<> makeSwitch(Index, const std::vector&, LabelIdxT) { return Ok{}; } @@ -1586,8 +1586,8 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeCallIndirect(*t, type, isReturn)); } - Result<> makeBreak(Index pos, Index label) { - return withLoc(pos, irBuilder.makeBreak(label)); + Result<> makeBreak(Index pos, Index label, bool isConditional) { + return withLoc(pos, irBuilder.makeBreak(label, isConditional)); } Result<> diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 60100703600..28110a628e2 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -104,7 +104,7 @@ template Result<> makeMemoryFill(Ctx&, Index); template Result<> makePop(Ctx&, Index); template Result<> makeCall(Ctx&, Index, bool isReturn); template Result<> makeCallIndirect(Ctx&, Index, bool isReturn); -template Result<> makeBreak(Ctx&, Index); +template Result<> makeBreak(Ctx&, Index, bool isConditional); template Result<> makeBreakTable(Ctx&, Index); template Result<> makeReturn(Ctx&, Index); template Result<> makeRefNull(Ctx&, Index); @@ -1432,10 +1432,11 @@ Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { return ctx.makeCallIndirect(pos, table.getPtr(), *type, isReturn); } -template Result<> makeBreak(Ctx& ctx, Index pos) { +template +Result<> makeBreak(Ctx& ctx, Index pos, bool isConditional) { auto label = labelidx(ctx); CHECK_ERR(label); - return ctx.makeBreak(pos, *label); + return ctx.makeBreak(pos, *label, isConditional); } template Result<> makeBreakTable(Ctx& ctx, Index pos) { diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 5add042a63b..4b54680141d 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -87,7 +87,7 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeBlock(Name label, Type type); [[nodiscard]] Result<> makeIf(Name label, Type type); [[nodiscard]] Result<> makeLoop(Name label, Type type); - [[nodiscard]] Result<> makeBreak(Index label); + [[nodiscard]] Result<> makeBreak(Index label, bool isConditional); [[nodiscard]] Result<> makeSwitch(const std::vector& labels, Index defaultLabel); // Unlike Builder::makeCall, this assumes the function already exists. diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 7921378de4d..849632ceb2d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -270,7 +270,7 @@ class SExpressionWasmBuilder { } enum class LabelType { Break, Exception }; Name getLabel(Element& s, LabelType labelType = LabelType::Break); - Expression* makeBreak(Element& s); + Expression* makeBreak(Element& s, bool isConditional); Expression* makeBreakTable(Element& s); Expression* makeReturn(Element& s); Expression* makeRefNull(Element& s); diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 43a989c6e0f..e8a2a238638 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -430,6 +430,11 @@ Result IRBuilder::getBranchValue(Name labelName, } Result<> IRBuilder::visitBreak(Break* curr, std::optional label) { + if (curr->condition) { + auto cond = pop(); + CHECK_ERR(cond); + curr->condition = *cond; + } auto value = getBranchValue(curr->name, label); CHECK_ERR(value); curr->value = *value; @@ -961,13 +966,15 @@ Result<> IRBuilder::makeLoop(Name label, Type type) { return visitLoopStart(loop); } -Result<> IRBuilder::makeBreak(Index label) { +Result<> IRBuilder::makeBreak(Index label, bool isConditional) { auto name = getLabelName(label); CHECK_ERR(name); Break curr; curr.name = *name; + // Use a dummy condition value if we need to pop a condition. + curr.condition = isConditional ? &curr : nullptr; CHECK_ERR(visitBreak(&curr, label)); - push(builder.makeBreak(curr.name, curr.value)); + push(builder.makeBreak(curr.name, curr.value, curr.condition)); return Ok{}; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 9270a19b0b1..9dbfc88c2d3 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2580,7 +2580,7 @@ Name SExpressionWasmBuilder::getLabel(Element& s, LabelType labelType) { } } -Expression* SExpressionWasmBuilder::makeBreak(Element& s) { +Expression* SExpressionWasmBuilder::makeBreak(Element& s, bool isConditional) { auto ret = allocator.alloc(); size_t i = 1; ret->name = getLabel(*s[i]); @@ -2588,7 +2588,7 @@ Expression* SExpressionWasmBuilder::makeBreak(Element& s) { if (i == s.size()) { return ret; } - if (elementStartsWith(s, BR_IF)) { + if (isConditional) { if (i + 1 < s.size()) { ret->value = parseExpression(s[i]); i++; diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 19915b13040..1a6eaa14e9a 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -46,127 +46,131 @@ ;; CHECK: (type $a0 (array i32)) - ;; CHECK: (type $17 (func (param i32 i32 i32))) + ;; CHECK: (type $17 (func (result i64 f32))) - ;; CHECK: (type $18 (func (param v128 i32) (result v128))) + ;; CHECK: (type $18 (func (param i32 i32 i32))) + + ;; CHECK: (type $19 (func (param v128 i32) (result v128))) ;; CHECK: (type $packed-i16 (array (mut i16))) ;; CHECK: (type $any-array (array (mut anyref))) - ;; CHECK: (type $21 (func (param stringref))) + ;; CHECK: (type $22 (func (param stringref))) + + ;; CHECK: (type $23 (func (param stringref stringref) (result i32))) - ;; CHECK: (type $22 (func (param stringref stringref) (result i32))) + ;; CHECK: (type $24 (func (param i32 i64) (result f32))) - ;; CHECK: (type $23 (func (param i32 i64) (result f32))) + ;; CHECK: (type $25 (func (param i64 v128) (result v128))) - ;; CHECK: (type $24 (func (param i64 v128) (result v128))) + ;; CHECK: (type $26 (func (param i64 v128))) - ;; CHECK: (type $25 (func (param i64 v128))) + ;; CHECK: (type $27 (func (param i32 i32))) - ;; CHECK: (type $26 (func (param i32 i32))) + ;; CHECK: (type $28 (func (result i64))) - ;; CHECK: (type $27 (func (param i32 i32 f64 f64))) + ;; CHECK: (type $29 (func (param i32 i32 f64 f64))) - ;; CHECK: (type $28 (func (param i64))) + ;; CHECK: (type $30 (func (param i64))) - ;; CHECK: (type $29 (func (param v128) (result i32))) + ;; CHECK: (type $31 (func (param v128) (result i32))) - ;; CHECK: (type $30 (func (param v128 v128) (result v128))) + ;; CHECK: (type $32 (func (param v128 v128) (result v128))) - ;; CHECK: (type $31 (func (param v128 v128 v128) (result v128))) + ;; CHECK: (type $33 (func (param v128 v128 v128) (result v128))) - ;; CHECK: (type $32 (func (param i32 i32 i64 i64))) + ;; CHECK: (type $34 (func (param i32 i32 i64 i64))) - ;; CHECK: (type $33 (func (param i32) (result i32))) + ;; CHECK: (type $35 (func (param i32) (result i32))) - ;; CHECK: (type $34 (func (param i32 i64) (result i32 i64))) + ;; CHECK: (type $36 (func (param i32 i64) (result i32 i64))) - ;; CHECK: (type $35 (func (param i64) (result i32 i64))) + ;; CHECK: (type $37 (func (param i64) (result i32 i64))) - ;; CHECK: (type $36 (func (param i32) (result i32 i64))) + ;; CHECK: (type $38 (func (param i32) (result i32 i64))) - ;; CHECK: (type $37 (func (param anyref) (result i32))) + ;; CHECK: (type $39 (func (param anyref) (result i32))) - ;; CHECK: (type $38 (func (param eqref eqref) (result i32))) + ;; CHECK: (type $40 (func (param eqref eqref) (result i32))) - ;; CHECK: (type $39 (func (param i32) (result i31ref))) + ;; CHECK: (type $41 (func (param i32) (result i31ref))) - ;; CHECK: (type $40 (func (param i31ref))) + ;; CHECK: (type $42 (func (param i31ref))) - ;; CHECK: (type $41 (func (param i32 i64) (result (ref $pair)))) + ;; CHECK: (type $43 (func (param i32 i64) (result (ref $pair)))) - ;; CHECK: (type $42 (func (result (ref $pair)))) + ;; CHECK: (type $44 (func (result (ref $pair)))) - ;; CHECK: (type $43 (func (param (ref $pair)) (result i32))) + ;; CHECK: (type $45 (func (param (ref $pair)) (result i32))) - ;; CHECK: (type $44 (func (param (ref $pair)) (result i64))) + ;; CHECK: (type $46 (func (param (ref $pair)) (result i64))) - ;; CHECK: (type $45 (func (param (ref $pair) i32))) + ;; CHECK: (type $47 (func (param (ref $pair) i32))) - ;; CHECK: (type $46 (func (param (ref $pair) i64))) + ;; CHECK: (type $48 (func (param (ref $pair) i64))) - ;; CHECK: (type $47 (func (param i64 i32) (result (ref $a1)))) + ;; CHECK: (type $49 (func (param i64 i32) (result (ref $a1)))) - ;; CHECK: (type $48 (func (param i32) (result (ref $a1)))) + ;; CHECK: (type $50 (func (param i32) (result (ref $a1)))) - ;; CHECK: (type $49 (func (param i32 i32) (result (ref $a1)))) + ;; CHECK: (type $51 (func (param i32 i32) (result (ref $a1)))) - ;; CHECK: (type $50 (func (param (ref $a1) i32) (result i64))) + ;; CHECK: (type $52 (func (param (ref $a1) i32) (result i64))) - ;; CHECK: (type $51 (func (param (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $53 (func (param (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $52 (func (param (ref $packed-i16) i32) (result i32))) + ;; CHECK: (type $54 (func (param (ref $packed-i16) i32) (result i32))) - ;; CHECK: (type $53 (func (param (ref $a2) i32 f32))) + ;; CHECK: (type $55 (func (param (ref $a2) i32 f32))) - ;; CHECK: (type $54 (func (param arrayref) (result i32))) + ;; CHECK: (type $56 (func (param arrayref) (result i32))) - ;; CHECK: (type $55 (func (param (ref $a2) i32 (ref $a2) i32 i32))) + ;; CHECK: (type $57 (func (param (ref $a2) i32 (ref $a2) i32 i32))) - ;; CHECK: (type $56 (func (param (ref $a2) i32 f32 i32))) + ;; CHECK: (type $58 (func (param (ref $a2) i32 f32 i32))) - ;; CHECK: (type $57 (func (param (ref $a2) i32 i32 i32))) + ;; CHECK: (type $59 (func (param (ref $a2) i32 i32 i32))) - ;; CHECK: (type $58 (func (param (ref $any-array) i32 i32 i32))) + ;; CHECK: (type $60 (func (param (ref $any-array) i32 i32 i32))) - ;; CHECK: (type $59 (func (param externref))) + ;; CHECK: (type $61 (func (param externref))) - ;; CHECK: (type $60 (func (param i32 i32) (result stringref))) + ;; CHECK: (type $62 (func (param i32 i32) (result stringref))) - ;; CHECK: (type $61 (func (param (ref $packed-i8) i32 i32) (result stringref))) + ;; CHECK: (type $63 (func (param (ref $packed-i8) i32 i32) (result stringref))) - ;; CHECK: (type $62 (func (param i32) (result stringref))) + ;; CHECK: (type $64 (func (param i32) (result stringref))) - ;; CHECK: (type $63 (func (result (ref string)))) + ;; CHECK: (type $65 (func (result (ref string)))) - ;; CHECK: (type $64 (func (param stringref) (result i32))) + ;; CHECK: (type $66 (func (param stringref) (result i32))) - ;; CHECK: (type $65 (func (param stringview_wtf16) (result i32))) + ;; CHECK: (type $67 (func (param stringview_wtf16) (result i32))) - ;; CHECK: (type $66 (func (param stringref (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $68 (func (param stringref (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $67 (func (param stringref stringref) (result (ref string)))) + ;; CHECK: (type $69 (func (param stringref stringref) (result (ref string)))) - ;; CHECK: (type $68 (func (param stringref) (result stringview_wtf8))) + ;; CHECK: (type $70 (func (param stringref) (result stringview_wtf8))) - ;; CHECK: (type $69 (func (param stringref) (result (ref stringview_wtf16)))) + ;; CHECK: (type $71 (func (param stringref) (result (ref stringview_wtf16)))) - ;; CHECK: (type $70 (func (param stringref) (result stringview_iter))) + ;; CHECK: (type $72 (func (param stringref) (result stringview_iter))) - ;; CHECK: (type $71 (func (param (ref stringview_wtf8) i32 i32) (result i32))) + ;; CHECK: (type $73 (func (param (ref stringview_wtf8) i32 i32) (result i32))) - ;; CHECK: (type $72 (func (param stringview_wtf16 i32) (result i32))) + ;; CHECK: (type $74 (func (param stringview_wtf16 i32) (result i32))) - ;; CHECK: (type $73 (func (param stringview_iter) (result i32))) + ;; CHECK: (type $75 (func (param stringview_iter) (result i32))) - ;; CHECK: (type $74 (func (param stringview_iter i32) (result i32))) + ;; CHECK: (type $76 (func (param stringview_iter i32) (result i32))) - ;; CHECK: (type $75 (func (param (ref stringview_iter) i32) (result i32))) + ;; CHECK: (type $77 (func (param (ref stringview_iter) i32) (result i32))) - ;; CHECK: (type $76 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) + ;; CHECK: (type $78 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) - ;; CHECK: (type $77 (func (param stringview_iter i32) (result (ref string)))) + ;; CHECK: (type $79 (func (param stringview_iter i32) (result (ref string)))) ;; CHECK: (type $s2 (struct (field i32))) (type $s2 (struct i32)) @@ -212,7 +216,7 @@ ;; imported memories (memory (export "mem") (export "mem2") (import "" "mem") 0) - ;; CHECK: (type $88 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) + ;; CHECK: (type $90 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) ;; CHECK: (import "" "mem" (memory $mimport$0 0)) @@ -856,7 +860,7 @@ drop ) - ;; CHECK: (func $locals (type $26) (param $0 i32) (param $x i32) + ;; CHECK: (func $locals (type $27) (param $0 i32) (param $x i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (drop @@ -2522,6 +2526,82 @@ br 0 ) + ;; CHECK: (func $br_if (type $void) + ;; CHECK-NEXT: (block $l + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if + block $l + i32.const 0 + br_if $l + end + ) + + ;; CHECK: (func $br_if-index (type $void) + ;; CHECK-NEXT: (block $label + ;; CHECK-NEXT: (br_if $label + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if-index + block + i32.const 0 + br_if 0 + end + ) + + ;; CHECK: (func $br_if-return (type $void) + ;; CHECK-NEXT: (block $label + ;; CHECK-NEXT: (br_if $label + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if-return + i32.const 0 + br_if 0 + ) + + ;; CHECK: (func $br_if-value (type $28) (result i64) + ;; CHECK-NEXT: (block $l (result i64) + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if-value (result i64) + block $l (result i64) + i64.const 0 + i32.const 1 + br_if $l + end + ) + + ;; CHECK: (func $br_if-multivalue (type $17) (result i64 f32) + ;; CHECK-NEXT: (block $l (type $17) (result i64 f32) + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if-multivalue (result i64 f32) + block $l (result i64 f32) + i64.const 0 + f32.const 1 + i32.const 2 + br_if $l + end + ) + ;; CHECK: (func $br-table (type $void) ;; CHECK-NEXT: (block $a ;; CHECK-NEXT: (block $b @@ -2631,7 +2711,7 @@ ) - ;; CHECK: (func $binary (type $27) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) + ;; CHECK: (func $binary (type $29) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $0) @@ -2656,7 +2736,7 @@ drop ) - ;; CHECK: (func $unary (type $28) (param $0 i64) + ;; CHECK: (func $unary (type $30) (param $0 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $0) @@ -2669,7 +2749,7 @@ drop ) - ;; CHECK: (func $select (type $17) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $select (type $18) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $0) @@ -2951,7 +3031,7 @@ atomic.fence ) - ;; CHECK: (func $simd-extract (type $29) (param $0 v128) (result i32) + ;; CHECK: (func $simd-extract (type $31) (param $0 v128) (result i32) ;; CHECK-NEXT: (i32x4.extract_lane 3 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2961,7 +3041,7 @@ i32x4.extract_lane 3 ) - ;; CHECK: (func $simd-replace (type $18) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-replace (type $19) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i32x4.replace_lane 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2973,7 +3053,7 @@ i32x4.replace_lane 2 ) - ;; CHECK: (func $simd-shuffle (type $30) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK: (func $simd-shuffle (type $32) (param $0 v128) (param $1 v128) (result v128) ;; CHECK-NEXT: (i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2985,7 +3065,7 @@ i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ) - ;; CHECK: (func $simd-ternary (type $31) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK: (func $simd-ternary (type $33) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) ;; CHECK-NEXT: (v128.bitselect ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2999,7 +3079,7 @@ v128.bitselect ) - ;; CHECK: (func $simd-shift (type $18) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-shift (type $19) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i8x16.shl ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3054,7 +3134,7 @@ v128.store64_lane 5 align=4 0 ) - ;; CHECK: (func $memory-init (type $17) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $memory-init (type $18) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (memory.init $mem-i32 $passive ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3095,7 +3175,7 @@ data.drop $passive ) - ;; CHECK: (func $memory-copy (type $32) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) + ;; CHECK: (func $memory-copy (type $34) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) ;; CHECK-NEXT: (memory.copy $mimport$0 $mimport$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3166,7 +3246,7 @@ return ) - ;; CHECK: (func $return-one (type $33) (param $0 i32) (result i32) + ;; CHECK: (func $return-one (type $35) (param $0 i32) (result i32) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3176,7 +3256,7 @@ return ) - ;; CHECK: (func $return-two (type $34) (param $0 i32) (param $1 i64) (result i32 i64) + ;; CHECK: (func $return-two (type $36) (param $0 i32) (param $1 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (local.get $0) @@ -3190,7 +3270,7 @@ return ) - ;; CHECK: (func $return-two-first-unreachable (type $35) (param $0 i64) (result i32 i64) + ;; CHECK: (func $return-two-first-unreachable (type $37) (param $0 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (unreachable) @@ -3204,7 +3284,7 @@ return ) - ;; CHECK: (func $return-two-second-unreachable (type $36) (param $0 i32) (result i32 i64) + ;; CHECK: (func $return-two-second-unreachable (type $38) (param $0 i32) (result i32 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3221,7 +3301,7 @@ return ) - ;; CHECK: (func $ref-is-null (type $37) (param $0 anyref) (result i32) + ;; CHECK: (func $ref-is-null (type $39) (param $0 anyref) (result i32) ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3242,7 +3322,7 @@ (func $ref-func ref.func $ref-func drop - ref.func 135 + ref.func 140 drop ) @@ -3265,7 +3345,7 @@ throw $tag-pair ) - ;; CHECK: (func $ref-eq (type $38) (param $0 eqref) (param $1 eqref) (result i32) + ;; CHECK: (func $ref-eq (type $40) (param $0 eqref) (param $1 eqref) (result i32) ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3442,7 +3522,7 @@ table.copy 2 $funcs ) - ;; CHECK: (func $i31-new (type $39) (param $0 i32) (result i31ref) + ;; CHECK: (func $i31-new (type $41) (param $0 i32) (result i31ref) ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3452,7 +3532,7 @@ ref.i31 ) - ;; CHECK: (func $i31-get (type $40) (param $0 i31ref) + ;; CHECK: (func $i31-get (type $42) (param $0 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i31.get_s ;; CHECK-NEXT: (local.get $0) @@ -3671,7 +3751,7 @@ drop ) - ;; CHECK: (func $struct-new (type $41) (param $0 i32) (param $1 i64) (result (ref $pair)) + ;; CHECK: (func $struct-new (type $43) (param $0 i32) (param $1 i64) (result (ref $pair)) ;; CHECK-NEXT: (struct.new $pair ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3683,14 +3763,14 @@ struct.new $pair ) - ;; CHECK: (func $struct-new-default (type $42) (result (ref $pair)) + ;; CHECK: (func $struct-new-default (type $44) (result (ref $pair)) ;; CHECK-NEXT: (struct.new_default $pair) ;; CHECK-NEXT: ) (func $struct-new-default (result (ref $pair)) struct.new_default 14 ) - ;; CHECK: (func $struct-get-0 (type $43) (param $0 (ref $pair)) (result i32) + ;; CHECK: (func $struct-get-0 (type $45) (param $0 (ref $pair)) (result i32) ;; CHECK-NEXT: (struct.get $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3700,7 +3780,7 @@ struct.get 14 0 ) - ;; CHECK: (func $struct-get-1 (type $44) (param $0 (ref $pair)) (result i64) + ;; CHECK: (func $struct-get-1 (type $46) (param $0 (ref $pair)) (result i64) ;; CHECK-NEXT: (struct.get $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3710,7 +3790,7 @@ struct.get $pair 1 ) - ;; CHECK: (func $struct-set-0 (type $45) (param $0 (ref $pair)) (param $1 i32) + ;; CHECK: (func $struct-set-0 (type $47) (param $0 (ref $pair)) (param $1 i32) ;; CHECK-NEXT: (struct.set $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3722,7 +3802,7 @@ struct.set $pair 0 ) - ;; CHECK: (func $struct-set-1 (type $46) (param $0 (ref $pair)) (param $1 i64) + ;; CHECK: (func $struct-set-1 (type $48) (param $0 (ref $pair)) (param $1 i64) ;; CHECK-NEXT: (struct.set $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3734,7 +3814,7 @@ struct.set 14 1 ) - ;; CHECK: (func $array-new (type $47) (param $0 i64) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new (type $49) (param $0 i64) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3746,7 +3826,7 @@ array.new $a1 ) - ;; CHECK: (func $array-new-default (type $48) (param $0 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-default (type $50) (param $0 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_default $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3756,7 +3836,7 @@ array.new_default 11 ) - ;; CHECK: (func $array-new-data (type $49) (param $0 i32) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-data (type $51) (param $0 i32) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_data $a1 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3790,7 +3870,7 @@ drop ) - ;; CHECK: (func $array-get (type $50) (param $0 (ref $a1)) (param $1 i32) (result i64) + ;; CHECK: (func $array-get (type $52) (param $0 (ref $a1)) (param $1 i32) (result i64) ;; CHECK-NEXT: (array.get $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3802,7 +3882,7 @@ array.get $a1 ) - ;; CHECK: (func $array-get-s (type $51) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-s (type $53) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_s $packed-i8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3814,7 +3894,7 @@ array.get_s 15 ) - ;; CHECK: (func $array-get-u (type $52) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-u (type $54) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_u $packed-i16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3826,7 +3906,7 @@ array.get_u $packed-i16 ) - ;; CHECK: (func $array-set (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) + ;; CHECK: (func $array-set (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) ;; CHECK-NEXT: (array.set $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3840,7 +3920,7 @@ array.set $a2 ) - ;; CHECK: (func $array-len (type $54) (param $0 arrayref) (result i32) + ;; CHECK: (func $array-len (type $56) (param $0 arrayref) (result i32) ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3850,7 +3930,7 @@ array.len ) - ;; CHECK: (func $array-copy (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) + ;; CHECK: (func $array-copy (type $57) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) ;; CHECK-NEXT: (array.copy $a2 $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3868,7 +3948,7 @@ array.copy $a2 $a2 ) - ;; CHECK: (func $array-fill (type $56) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) + ;; CHECK: (func $array-fill (type $58) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) ;; CHECK-NEXT: (array.fill $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3884,7 +3964,7 @@ array.fill $a2 ) - ;; CHECK: (func $array-init-data (type $57) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-data (type $59) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_data $a2 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3900,7 +3980,7 @@ array.init_data $a2 0 ) - ;; CHECK: (func $array-init-elem (type $58) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-elem (type $60) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_elem $any-array $passive-2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3929,7 +4009,7 @@ drop ) - ;; CHECK: (func $any-convert-extern (type $59) (param $0 externref) + ;; CHECK: (func $any-convert-extern (type $61) (param $0 externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.internalize ;; CHECK-NEXT: (local.get $0) @@ -3955,7 +4035,7 @@ drop ) - ;; CHECK: (func $string-new (type $60) (param $0 i32) (param $1 i32) (result stringref) + ;; CHECK: (func $string-new (type $62) (param $0 i32) (param $1 i32) (result stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_utf8_try ;; CHECK-NEXT: (local.get $0) @@ -3997,7 +4077,7 @@ string.new_wtf16 ) - ;; CHECK: (func $string-new-gc (type $61) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) + ;; CHECK: (func $string-new-gc (type $63) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) ;; CHECK-NEXT: (string.new_utf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4011,7 +4091,7 @@ string.new_utf8_array ) - ;; CHECK: (func $string-new-code-point (type $62) (param $0 i32) (result stringref) + ;; CHECK: (func $string-new-code-point (type $64) (param $0 i32) (result stringref) ;; CHECK-NEXT: (string.from_code_point ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4021,7 +4101,7 @@ string.from_code_point ) - ;; CHECK: (func $string-const (type $63) (result (ref string)) + ;; CHECK: (func $string-const (type $65) (result (ref string)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.const "foobar") ;; CHECK-NEXT: ) @@ -4033,7 +4113,7 @@ string.const "\00\00\00" ) - ;; CHECK: (func $string-measure (type $21) (param $0 stringref) + ;; CHECK: (func $string-measure (type $22) (param $0 stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.measure_wtf8 ;; CHECK-NEXT: (local.get $0) @@ -4070,7 +4150,7 @@ drop ) - ;; CHECK: (func $string-hash (type $64) (param $0 stringref) (result i32) + ;; CHECK: (func $string-hash (type $66) (param $0 stringref) (result i32) ;; CHECK-NEXT: (string.hash ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4080,7 +4160,7 @@ string.hash ) - ;; CHECK: (func $stringview-length (type $65) (param $0 stringview_wtf16) (result i32) + ;; CHECK: (func $stringview-length (type $67) (param $0 stringview_wtf16) (result i32) ;; CHECK-NEXT: (stringview_wtf16.length ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4090,7 +4170,7 @@ stringview_wtf16.length ) - ;; CHECK: (func $string-encode (type $21) (param $0 stringref) + ;; CHECK: (func $string-encode (type $22) (param $0 stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.encode_wtf8 ;; CHECK-NEXT: (local.get $0) @@ -4135,7 +4215,7 @@ drop ) - ;; CHECK: (func $string-encode-gc (type $66) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) + ;; CHECK: (func $string-encode-gc (type $68) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) ;; CHECK-NEXT: (string.encode_wtf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4149,7 +4229,7 @@ string.encode_wtf8_array ) - ;; CHECK: (func $string-concat (type $67) (param $0 stringref) (param $1 stringref) (result (ref string)) + ;; CHECK: (func $string-concat (type $69) (param $0 stringref) (param $1 stringref) (result (ref string)) ;; CHECK-NEXT: (string.concat ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4161,7 +4241,7 @@ string.concat ) - ;; CHECK: (func $string-eq (type $22) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK: (func $string-eq (type $23) (param $0 stringref) (param $1 stringref) (result i32) ;; CHECK-NEXT: (string.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4173,7 +4253,7 @@ string.eq ) - ;; CHECK: (func $string-compare (type $22) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK: (func $string-compare (type $23) (param $0 stringref) (param $1 stringref) (result i32) ;; CHECK-NEXT: (string.compare ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4185,7 +4265,7 @@ string.compare ) - ;; CHECK: (func $string-as-wtf8 (type $68) (param $0 stringref) (result stringview_wtf8) + ;; CHECK: (func $string-as-wtf8 (type $70) (param $0 stringref) (result stringview_wtf8) ;; CHECK-NEXT: (string.as_wtf8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4195,7 +4275,7 @@ string.as_wtf8 ) - ;; CHECK: (func $string-as-wtf16 (type $69) (param $0 stringref) (result (ref stringview_wtf16)) + ;; CHECK: (func $string-as-wtf16 (type $71) (param $0 stringref) (result (ref stringview_wtf16)) ;; CHECK-NEXT: (string.as_wtf16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4205,7 +4285,7 @@ string.as_wtf16 ) - ;; CHECK: (func $string-as-iter (type $70) (param $0 stringref) (result stringview_iter) + ;; CHECK: (func $string-as-iter (type $72) (param $0 stringref) (result stringview_iter) ;; CHECK-NEXT: (string.as_iter ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4215,7 +4295,7 @@ string.as_iter ) - ;; CHECK: (func $string-advance (type $71) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK: (func $string-advance (type $73) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf8.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4229,7 +4309,7 @@ stringview_wtf8.advance ) - ;; CHECK: (func $string-get (type $72) (param $0 stringview_wtf16) (param $1 i32) (result i32) + ;; CHECK: (func $string-get (type $74) (param $0 stringview_wtf16) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf16.get_codeunit ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4241,7 +4321,7 @@ stringview_wtf16.get_codeunit ) - ;; CHECK: (func $string-iter-next (type $73) (param $0 stringview_iter) (result i32) + ;; CHECK: (func $string-iter-next (type $75) (param $0 stringview_iter) (result i32) ;; CHECK-NEXT: (stringview_iter.next ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4251,7 +4331,7 @@ stringview_iter.next ) - ;; CHECK: (func $string-iter-advance (type $74) (param $0 stringview_iter) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-advance (type $76) (param $0 stringview_iter) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4263,7 +4343,7 @@ stringview_iter.advance ) - ;; CHECK: (func $string-iter-rewind (type $75) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-rewind (type $77) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.rewind ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4275,7 +4355,7 @@ stringview_iter.rewind ) - ;; CHECK: (func $string-slice (type $76) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) + ;; CHECK: (func $string-slice (type $78) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (stringview_wtf8.slice ;; CHECK-NEXT: (local.get $0) @@ -4304,7 +4384,7 @@ drop ) - ;; CHECK: (func $string-iter-slice (type $77) (param $0 stringview_iter) (param $1 i32) (result (ref string)) + ;; CHECK: (func $string-iter-slice (type $79) (param $0 stringview_iter) (param $1 i32) (result (ref string)) ;; CHECK-NEXT: (stringview_iter.slice ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4316,7 +4396,7 @@ stringview_iter.slice ) - ;; CHECK: (func $call (type $23) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $call (type $24) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (call $call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4328,7 +4408,7 @@ call $call ) - ;; CHECK: (func $return_call (type $23) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $return_call (type $24) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (return_call $return_call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4369,7 +4449,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $25) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4431,7 +4511,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $25) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4503,7 +4583,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $26) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4562,7 +4642,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $26) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4603,7 +4683,7 @@ ) ) - ;; CHECK: (func $use-types (type $88) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) + ;; CHECK: (func $use-types (type $90) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-types From bdafd1116f2fd56ef8a86b3b1a18f3670e4004ed Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 5 Jan 2024 09:22:02 -0800 Subject: [PATCH 028/553] [NFC] Add some const annotations (#6203) --- src/literal.h | 6 +++--- src/wasm-interpreter.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/literal.h b/src/literal.h index b484fc3b8ed..971cc8b3e0e 100644 --- a/src/literal.h +++ b/src/literal.h @@ -698,7 +698,7 @@ class Literals : public SmallVector { } Literals(size_t initialSize) : SmallVector(initialSize) {} - Type getType() { + Type getType() const { if (empty()) { return Type::none; } @@ -711,8 +711,8 @@ class Literals : public SmallVector { } return Type(types); } - bool isNone() { return size() == 0; } - bool isConcrete() { return size() != 0; } + bool isNone() const { return size() == 0; } + bool isConcrete() const { return size() != 0; } }; std::ostream& operator<<(std::ostream& o, wasm::Literal literal); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index eb0a1274abc..eeca7c3ccde 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -80,7 +80,7 @@ class Flow { return builder.makeConstantExpression(values); } - bool breaking() { return breakTo.is(); } + bool breaking() const { return breakTo.is(); } void clearIf(Name target) { if (breakTo == target) { From 436d6399d2e915490f980f7f8193e84dc7ed215f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 5 Jan 2024 16:35:45 -0800 Subject: [PATCH 029/553] Rename CMake vars for modified intrinsics file (#6204) The intrinsics file changed in #6201 and somehow CMake doesn't automatically update itself, and needs a manual step for people with existing checkouts (a new fresh checkout always works). To avoid annoyance for existing checkouts, rename the vars, which forces CMake to recompute the contents. --- src/passes/CMakeLists.txt | 14 ++++++++++---- src/passes/WasmIntrinsics.cpp.in | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 1c8418b2474..182f4a92181 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -2,12 +2,18 @@ file(READ wasm-intrinsics.wat WASM_INTRINSICS_WAT HEX) string(REGEX MATCHALL "([A-Fa-f0-9][A-Fa-f0-9])" SEPARATED_HEX ${WASM_INTRINSICS_WAT}) -set(WASM_INTRINSICS_SIZE 1) +# WASM_INTRINSICS_EMBED_2 and WASM_INTRINSICS_SIZE_2 should be renamed each time +# the content of the wat file changes. This is not strictly necessary, as CMake +# should use the fresh contents each time, but even just re-running CMake +# manually is not enough in practice (one needs to also erase the CMake temp +# files, or use a fresh build dir). Renaming the vars keeps things working +# smoothly for people with existing checkouts. +set(WASM_INTRINSICS_SIZE_2 1) foreach (hex IN LISTS SEPARATED_HEX) - string(APPEND WASM_INTRINSICS_EMBED "0x${hex},") - math(EXPR WASM_INTRINSICS_SIZE "${WASM_INTRINSICS_SIZE}+1") + string(APPEND WASM_INTRINSICS_EMBED_2 "0x${hex},") + math(EXPR WASM_INTRINSICS_SIZE_2 "${WASM_INTRINSICS_SIZE_2}+1") endforeach () -string(APPEND WASM_INTRINSICS_EMBED "0x00") +string(APPEND WASM_INTRINSICS_EMBED_2 "0x00") configure_file(WasmIntrinsics.cpp.in WasmIntrinsics.cpp @ONLY) diff --git a/src/passes/WasmIntrinsics.cpp.in b/src/passes/WasmIntrinsics.cpp.in index 46216842dcb..c750c56dd58 100644 --- a/src/passes/WasmIntrinsics.cpp.in +++ b/src/passes/WasmIntrinsics.cpp.in @@ -1,7 +1,7 @@ #include "passes/intrinsics-module.h" -static const char theModule[@WASM_INTRINSICS_SIZE@] = { -@WASM_INTRINSICS_EMBED@ +static const char theModule[@WASM_INTRINSICS_SIZE_2@] = { +@WASM_INTRINSICS_EMBED_2@ }; namespace wasm { From c3b2f245fe27b933a97e732b12bdf1eb1a0f39b7 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 5 Jan 2024 17:54:40 -0800 Subject: [PATCH 030/553] Fix branches to loops in IRBuilder (#6205) Since branches to loops go to the beginnings of the loops, they should send values matching the input types for the loops (which are always none because we don't support loop input types). IRBuilder was previously using the output types of loops to determine what values the branches should carry, which was incorrect. Fix it. --- src/wasm/wasm-ir-builder.cpp | 13 +++-- test/lit/wat-kitchen-sink.wast | 101 +++++++++++++++++++++++---------- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index e8a2a238638..dc80d6af557 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -414,15 +414,18 @@ Result IRBuilder::getBranchValue(Name labelName, } auto scope = getScope(*label); CHECK_ERR(scope); - std::vector values((*scope)->getResultType().size()); - for (size_t i = 0, size = values.size(); i < size; ++i) { + // Loops would receive their input type rather than their output type, if we + // supported that. + size_t numValues = (*scope)->getLoop() ? 0 : (*scope)->getResultType().size(); + std::vector values(numValues); + for (size_t i = 0; i < numValues; ++i) { auto val = pop(); CHECK_ERR(val); - values[size - 1 - i] = *val; + values[numValues - 1 - i] = *val; } - if (values.size() == 0) { + if (numValues == 0) { return nullptr; - } else if (values.size() == 1) { + } else if (numValues == 1) { return values[0]; } else { return builder.makeTupleMake(values); diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 1a6eaa14e9a..b0de467af8e 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -46,29 +46,29 @@ ;; CHECK: (type $a0 (array i32)) - ;; CHECK: (type $17 (func (result i64 f32))) + ;; CHECK: (type $17 (func (result i64))) - ;; CHECK: (type $18 (func (param i32 i32 i32))) + ;; CHECK: (type $18 (func (result i64 f32))) - ;; CHECK: (type $19 (func (param v128 i32) (result v128))) + ;; CHECK: (type $19 (func (param i32 i32 i32))) + + ;; CHECK: (type $20 (func (param v128 i32) (result v128))) ;; CHECK: (type $packed-i16 (array (mut i16))) ;; CHECK: (type $any-array (array (mut anyref))) - ;; CHECK: (type $22 (func (param stringref))) - - ;; CHECK: (type $23 (func (param stringref stringref) (result i32))) + ;; CHECK: (type $23 (func (param stringref))) - ;; CHECK: (type $24 (func (param i32 i64) (result f32))) + ;; CHECK: (type $24 (func (param stringref stringref) (result i32))) - ;; CHECK: (type $25 (func (param i64 v128) (result v128))) + ;; CHECK: (type $25 (func (param i32 i64) (result f32))) - ;; CHECK: (type $26 (func (param i64 v128))) + ;; CHECK: (type $26 (func (param i64 v128) (result v128))) - ;; CHECK: (type $27 (func (param i32 i32))) + ;; CHECK: (type $27 (func (param i64 v128))) - ;; CHECK: (type $28 (func (result i64))) + ;; CHECK: (type $28 (func (param i32 i32))) ;; CHECK: (type $29 (func (param i32 i32 f64 f64))) @@ -860,7 +860,7 @@ drop ) - ;; CHECK: (func $locals (type $27) (param $0 i32) (param $x i32) + ;; CHECK: (func $locals (type $28) (param $0 i32) (param $x i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (drop @@ -2566,7 +2566,7 @@ br_if 0 ) - ;; CHECK: (func $br_if-value (type $28) (result i64) + ;; CHECK: (func $br_if-value (type $17) (result i64) ;; CHECK-NEXT: (block $l (result i64) ;; CHECK-NEXT: (br_if $l ;; CHECK-NEXT: (i64.const 0) @@ -2582,8 +2582,8 @@ end ) - ;; CHECK: (func $br_if-multivalue (type $17) (result i64 f32) - ;; CHECK-NEXT: (block $l (type $17) (result i64 f32) + ;; CHECK: (func $br_if-multivalue (type $18) (result i64 f32) + ;; CHECK-NEXT: (block $l (type $18) (result i64 f32) ;; CHECK-NEXT: (br_if $l ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (i64.const 0) @@ -2602,6 +2602,26 @@ end ) + ;; CHECK: (func $br_if-loop (type $17) (result i64) + ;; CHECK-NEXT: (local $scratch i64) + ;; CHECK-NEXT: (loop $l (result i64) + ;; CHECK-NEXT: (local.set $scratch + ;; CHECK-NEXT: (i64.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $l + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $scratch) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br_if-loop (result i64) + loop $l (result i64) + i64.const 42 + i32.const 0 + br_if $l + end + ) + ;; CHECK: (func $br-table (type $void) ;; CHECK-NEXT: (block $a ;; CHECK-NEXT: (block $b @@ -2710,6 +2730,27 @@ end ) + ;; CHECK: (func $br-table-loop (type $1) (result i32) + ;; CHECK-NEXT: (loop $a (result i32) + ;; CHECK-NEXT: (loop $b (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_table $a $b + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-table-loop (result i32) + loop $a (result i32) + loop $b (result i32) + i32.const 42 + i32.const 0 + br_table $a $b + end + end + ) ;; CHECK: (func $binary (type $29) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop @@ -2749,7 +2790,7 @@ drop ) - ;; CHECK: (func $select (type $18) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $select (type $19) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (local.get $0) @@ -3041,7 +3082,7 @@ i32x4.extract_lane 3 ) - ;; CHECK: (func $simd-replace (type $19) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-replace (type $20) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i32x4.replace_lane 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3079,7 +3120,7 @@ v128.bitselect ) - ;; CHECK: (func $simd-shift (type $19) (param $0 v128) (param $1 i32) (result v128) + ;; CHECK: (func $simd-shift (type $20) (param $0 v128) (param $1 i32) (result v128) ;; CHECK-NEXT: (i8x16.shl ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3134,7 +3175,7 @@ v128.store64_lane 5 align=4 0 ) - ;; CHECK: (func $memory-init (type $18) (param $0 i32) (param $1 i32) (param $2 i32) + ;; CHECK: (func $memory-init (type $19) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (memory.init $mem-i32 $passive ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3322,7 +3363,7 @@ (func $ref-func ref.func $ref-func drop - ref.func 140 + ref.func 142 drop ) @@ -4113,7 +4154,7 @@ string.const "\00\00\00" ) - ;; CHECK: (func $string-measure (type $22) (param $0 stringref) + ;; CHECK: (func $string-measure (type $23) (param $0 stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.measure_wtf8 ;; CHECK-NEXT: (local.get $0) @@ -4170,7 +4211,7 @@ stringview_wtf16.length ) - ;; CHECK: (func $string-encode (type $22) (param $0 stringref) + ;; CHECK: (func $string-encode (type $23) (param $0 stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.encode_wtf8 ;; CHECK-NEXT: (local.get $0) @@ -4241,7 +4282,7 @@ string.concat ) - ;; CHECK: (func $string-eq (type $23) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK: (func $string-eq (type $24) (param $0 stringref) (param $1 stringref) (result i32) ;; CHECK-NEXT: (string.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4253,7 +4294,7 @@ string.eq ) - ;; CHECK: (func $string-compare (type $23) (param $0 stringref) (param $1 stringref) (result i32) + ;; CHECK: (func $string-compare (type $24) (param $0 stringref) (param $1 stringref) (result i32) ;; CHECK-NEXT: (string.compare ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4396,7 +4437,7 @@ stringview_iter.slice ) - ;; CHECK: (func $call (type $24) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $call (type $25) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (call $call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4408,7 +4449,7 @@ call $call ) - ;; CHECK: (func $return_call (type $24) (param $0 i32) (param $1 i64) (result f32) + ;; CHECK: (func $return_call (type $25) (param $0 i32) (param $1 i64) (result f32) ;; CHECK-NEXT: (return_call $return_call ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4449,7 +4490,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $26) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4511,7 +4552,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $26) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4583,7 +4624,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $26) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $27) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4642,7 +4683,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $26) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $27) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) From 82057de7666b84424f8d2bd90e941762e4e14f0e Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sat, 6 Jan 2024 09:06:49 -0800 Subject: [PATCH 031/553] Fix cmake dependency on wasm-intrinsics.wat (#6206) I think this is a nicer/better way to do #6204. --- src/passes/CMakeLists.txt | 13 +++---------- src/passes/WasmIntrinsics.cpp.in | 4 ++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 182f4a92181..9ab9f0247e1 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -1,19 +1,12 @@ file(READ wasm-intrinsics.wat WASM_INTRINSICS_WAT HEX) +set(CMAKE_CONFIGURE_DEPENDS wasm-intrinsics.wat) string(REGEX MATCHALL "([A-Fa-f0-9][A-Fa-f0-9])" SEPARATED_HEX ${WASM_INTRINSICS_WAT}) -# WASM_INTRINSICS_EMBED_2 and WASM_INTRINSICS_SIZE_2 should be renamed each time -# the content of the wat file changes. This is not strictly necessary, as CMake -# should use the fresh contents each time, but even just re-running CMake -# manually is not enough in practice (one needs to also erase the CMake temp -# files, or use a fresh build dir). Renaming the vars keeps things working -# smoothly for people with existing checkouts. -set(WASM_INTRINSICS_SIZE_2 1) foreach (hex IN LISTS SEPARATED_HEX) - string(APPEND WASM_INTRINSICS_EMBED_2 "0x${hex},") - math(EXPR WASM_INTRINSICS_SIZE_2 "${WASM_INTRINSICS_SIZE_2}+1") + string(APPEND WASM_INTRINSICS_EMBED "0x${hex},") endforeach () -string(APPEND WASM_INTRINSICS_EMBED_2 "0x00") +string(APPEND WASM_INTRINSICS_EMBED "0x00") configure_file(WasmIntrinsics.cpp.in WasmIntrinsics.cpp @ONLY) diff --git a/src/passes/WasmIntrinsics.cpp.in b/src/passes/WasmIntrinsics.cpp.in index c750c56dd58..2eaaec43988 100644 --- a/src/passes/WasmIntrinsics.cpp.in +++ b/src/passes/WasmIntrinsics.cpp.in @@ -1,7 +1,7 @@ #include "passes/intrinsics-module.h" -static const char theModule[@WASM_INTRINSICS_SIZE_2@] = { -@WASM_INTRINSICS_EMBED_2@ +static const char theModule[] = { +@WASM_INTRINSICS_EMBED@ }; namespace wasm { From cc0fab918aed3643abdc3566ade3f70f06d1d954 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 8 Jan 2024 11:46:30 -0800 Subject: [PATCH 032/553] Fix incorrect wat in tests (#6207) The new wat parser is much more strict than the legacy wat parser; the latter accepts all sorts of things that the spec does not allow. To ease an eventual transition to using the new wat parser by default, update the tests to use the standard text format in many places where they previously did not. We do not yet have a way to prevent new errors from being introduced into the test suite, but at least there will now be many fewer errors when it comes time to make the switch. --- test/ctor-eval/bad-indirect-call.wast | 2 +- test/ctor-eval/bad-indirect-call2.wast | 2 +- test/ctor-eval/basics-flatten.wast | 6 +-- test/ctor-eval/basics.wast | 6 +-- test/ctor-eval/imported-global.wast | 2 +- test/ctor-eval/indirect-call3.wast | 2 +- test/ctor-eval/just_some.wast | 6 +-- test/ctor-eval/partial-locals-tee.wast | 2 +- test/ctor-eval/partial-locals.wast | 2 +- test/ctor-eval/partial-return.wast | 2 +- test/ctor-eval/partial.wast | 4 +- test/ctor-eval/unsafe_call.wast | 2 +- test/ctor-eval/unsafe_store.wast | 2 +- test/ctor-eval/unsafe_store2.wast | 2 +- test/ctor-eval/unsafe_store3.wast | 2 +- test/lit/basic/atomics.wast | 2 +- test/lit/basic/atomics64.wast | 2 +- test/lit/basic/multi-table.wast | 2 +- test/lit/basic/reference-types.wast | 2 +- test/lit/basic/simd.wast | 4 +- test/lit/if-then-else.wast | 4 +- test/lit/merge/renamings.wat | 4 +- test/lit/merge/renamings.wat.second | 4 +- test/lit/passes/Oz.wast | 2 +- test/lit/passes/alignment-lowering.wast | 12 ++--- test/lit/passes/alignment-lowering64.wast | 12 ++--- test/lit/passes/coalesce-locals-learning.wast | 3 +- test/lit/passes/coalesce-locals.wast | 9 ++-- test/lit/passes/dae-gc-refine-return.wast | 8 ++-- test/lit/passes/directize_all-features.wast | 4 +- test/lit/passes/flatten_all-features.wast | 6 +-- ...tten_simplify-locals-nonesting_dfo_O3.wast | 2 - test/lit/passes/gufa-refs.wast | 2 - test/lit/passes/instrument-memory.wast | 46 +++++++++--------- test/lit/passes/instrument-memory64.wast | 46 +++++++++--------- test/lit/passes/multi-memory-lowering.wast | 4 +- test/lit/passes/outlining.wast | 16 +++---- test/lit/passes/poppify.wast | 22 ++++----- ...e-unused-module-elements_all-features.wast | 47 +++++++------------ test/lit/passes/stack-check-memory64.wast | 12 ++--- test/lit/passes/stack-ir-non-nullable.wast | 1 - test/lit/passes/unsubtyping-casts.wast | 6 +-- test/lit/passes/unsubtyping.wast | 28 +++++------ test/lit/passes/vacuum_all-features.wast | 9 ++-- test/metadce/segments.wast | 2 +- test/metadce/segments.wast.dced | 2 +- test/metadce/table.wast | 3 +- test/passes/Oz_fuzz-exec_all-features.wast | 4 +- ...function-elimination_optimize-level=1.wast | 12 ++--- ...function-elimination_optimize-level=2.wast | 12 ++--- test/passes/fuzz-exec_all-features.wast | 2 - test/passes/merge-locals_all-features.wast | 32 ++++++------- .../optimize-instructions_fuzz-exec.wast | 40 ++++++++-------- test/passes/precompute_all-features.txt | 2 +- test/passes/precompute_all-features.wast | 3 +- test/passes/remove-imports.wast | 8 ++-- .../remove-unused-names_code-folding.wast | 20 ++++---- ...function-module-elements_all-features.wast | 24 +++++----- test/passes/simplify-locals_all-features.wast | 20 ++++---- ...l-features_disable-exception-handling.wast | 20 ++++---- test/passes/ssa-nomerge_enable-simd.wast | 2 +- test/passes/ssa_enable-threads.wast | 3 +- 62 files changed, 274 insertions(+), 302 deletions(-) diff --git a/test/ctor-eval/bad-indirect-call.wast b/test/ctor-eval/bad-indirect-call.wast index 29a09fe2e29..9ef091ad3c3 100644 --- a/test/ctor-eval/bad-indirect-call.wast +++ b/test/ctor-eval/bad-indirect-call.wast @@ -4,7 +4,7 @@ (data (i32.const 10) "waka waka waka waka waka") (table 1 1 funcref) (elem (i32.const 0) $call-indirect) - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (call_indirect (type $v) (i32.const 1)) ;; unsafe to call, out of range (i32.store8 (i32.const 20) (i32.const 120)) diff --git a/test/ctor-eval/bad-indirect-call2.wast b/test/ctor-eval/bad-indirect-call2.wast index 8999af145a6..60d73b7fc4a 100644 --- a/test/ctor-eval/bad-indirect-call2.wast +++ b/test/ctor-eval/bad-indirect-call2.wast @@ -5,7 +5,7 @@ (import "env" "_abort" (func $_abort)) (table 2 2 funcref) (elem (i32.const 0) $_abort $call-indirect) - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (call_indirect (type $v) (i32.const 0)) ;; unsafe to call, imported (i32.store8 (i32.const 20) (i32.const 120)) diff --git a/test/ctor-eval/basics-flatten.wast b/test/ctor-eval/basics-flatten.wast index 3584bc9fa56..f53b772f047 100644 --- a/test/ctor-eval/basics-flatten.wast +++ b/test/ctor-eval/basics-flatten.wast @@ -7,9 +7,9 @@ (data (i32.const 20) "waka waka waka") (table 1 1 funcref) (elem (i32.const 0) $call-indirect) - (export "test1" $test1) - (export "test2" $test2) - (export "test3" $test3) + (export "test1" (func $test1)) + (export "test2" (func $test2)) + (export "test3" (func $test3)) (func $test1 (drop (i32.const 0)) ;; no work at all, really (call $safe-to-call) ;; safe to call diff --git a/test/ctor-eval/basics.wast b/test/ctor-eval/basics.wast index 5f9add08fc7..ff138de24ac 100644 --- a/test/ctor-eval/basics.wast +++ b/test/ctor-eval/basics.wast @@ -4,9 +4,9 @@ (data (i32.const 10) "waka waka waka waka waka") (table 1 1 funcref) (elem (i32.const 0) $call-indirect) - (export "test1" $test1) - (export "test2" $test2) - (export "test3" $test3) + (export "test1" (func $test1)) + (export "test2" (func $test2)) + (export "test3" (func $test3)) (func $test1 (drop (i32.const 0)) ;; no work at all, really (call $safe-to-call) ;; safe to call diff --git a/test/ctor-eval/imported-global.wast b/test/ctor-eval/imported-global.wast index 20e56d2d1e1..1c14a311497 100644 --- a/test/ctor-eval/imported-global.wast +++ b/test/ctor-eval/imported-global.wast @@ -3,7 +3,7 @@ (data (i32.const 10) "waka waka waka waka waka") ;; imports must not be used (import "env" "tempDoublePtr" (global $tempDoublePtr i32)) - (export "test1" $test1) + (export "test1" (func $test1)) (global $mine (mut i32) (global.get $tempDoublePtr)) ;; BAD, if used (func $test1 (i32.store8 (i32.const 13) (i32.const 115)) ;; we never get here. diff --git a/test/ctor-eval/indirect-call3.wast b/test/ctor-eval/indirect-call3.wast index 9c88e0f786b..0c18c01d577 100644 --- a/test/ctor-eval/indirect-call3.wast +++ b/test/ctor-eval/indirect-call3.wast @@ -5,7 +5,7 @@ (import "env" "_abort" (func $_abort)) (table 2 2 funcref) (elem (i32.const 0) $_abort $call-indirect) - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (call_indirect (type $v) (i32.const 1)) ;; safe to call (i32.store8 (i32.const 20) (i32.const 120)) diff --git a/test/ctor-eval/just_some.wast b/test/ctor-eval/just_some.wast index 64aa18d27fa..661688eff6c 100644 --- a/test/ctor-eval/just_some.wast +++ b/test/ctor-eval/just_some.wast @@ -1,9 +1,9 @@ (module (memory 256 256) (data (i32.const 10) "waka waka waka waka waka") - (export "test1" $test1) - (export "test2" $test2) - (export "test3" $test3) + (export "test1" (func $test1)) + (export "test2" (func $test2)) + (export "test3" (func $test3)) (func $test1 (i32.store8 (i32.const 12) (i32.const 115)) ;; a safe store, should alter memory ) diff --git a/test/ctor-eval/partial-locals-tee.wast b/test/ctor-eval/partial-locals-tee.wast index 37dac176a2a..651234790e1 100644 --- a/test/ctor-eval/partial-locals-tee.wast +++ b/test/ctor-eval/partial-locals-tee.wast @@ -4,7 +4,7 @@ (memory 256 256) (data (i32.const 10) "_________________") - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (local $temp i32) diff --git a/test/ctor-eval/partial-locals.wast b/test/ctor-eval/partial-locals.wast index b0304c2eab6..4a58274c899 100644 --- a/test/ctor-eval/partial-locals.wast +++ b/test/ctor-eval/partial-locals.wast @@ -4,7 +4,7 @@ (memory 256 256) (data (i32.const 10) "_________________") - (export "test1" $test1) + (export "test1" (func $test1)) (global $sp (mut i32) (i32.const 100)) diff --git a/test/ctor-eval/partial-return.wast b/test/ctor-eval/partial-return.wast index e74c59cb871..95529ea173d 100644 --- a/test/ctor-eval/partial-return.wast +++ b/test/ctor-eval/partial-return.wast @@ -4,7 +4,7 @@ (memory 256 256) (data (i32.const 10) "_________________") - (export "test1" $test1) + (export "test1" (func $test1)) (export "memory" (memory $0)) (func $test1 diff --git a/test/ctor-eval/partial.wast b/test/ctor-eval/partial.wast index bbff880e703..e1d033bdab1 100644 --- a/test/ctor-eval/partial.wast +++ b/test/ctor-eval/partial.wast @@ -4,12 +4,12 @@ (memory 256 256) (data (i32.const 10) "_________________") - (export "test1" $test1) + (export "test1" (func $test1)) ;; Use the function in an additional export. We should still get the same ;; results if we call this one, so it should point to identical contents as ;; earlier - (export "keepalive" $test1) + (export "keepalive" (func $test1)) (func $test1 ;; A safe store, should alter memory diff --git a/test/ctor-eval/unsafe_call.wast b/test/ctor-eval/unsafe_call.wast index a3dff7c1942..86543cbf458 100644 --- a/test/ctor-eval/unsafe_call.wast +++ b/test/ctor-eval/unsafe_call.wast @@ -1,7 +1,7 @@ (module (memory 256 256) (data (i32.const 10) "waka waka waka waka waka") - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (call $unsafe-to-call) ;; unsafe to call (i32.store (i32.const 12) (i32.const 115)) ;; a safe store, should alter memory diff --git a/test/ctor-eval/unsafe_store.wast b/test/ctor-eval/unsafe_store.wast index 296363b35c7..9b011180620 100644 --- a/test/ctor-eval/unsafe_store.wast +++ b/test/ctor-eval/unsafe_store.wast @@ -1,7 +1,7 @@ (module (memory 256 256) (data (i32.const 10) "waka waka waka waka waka") - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (i32.store8 (i32.const 9) (i32.const 109)) ;; before first segment ) diff --git a/test/ctor-eval/unsafe_store2.wast b/test/ctor-eval/unsafe_store2.wast index 5272c833377..7c25eee672f 100644 --- a/test/ctor-eval/unsafe_store2.wast +++ b/test/ctor-eval/unsafe_store2.wast @@ -1,7 +1,7 @@ (module (memory 256 256) (data (i32.const 10) "waka waka waka waka waka") - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (i32.store8 (i32.const 34) (i32.const 109)) ;; after last segment ) diff --git a/test/ctor-eval/unsafe_store3.wast b/test/ctor-eval/unsafe_store3.wast index b8e7c662a59..64e7a28c4d4 100644 --- a/test/ctor-eval/unsafe_store3.wast +++ b/test/ctor-eval/unsafe_store3.wast @@ -1,7 +1,7 @@ (module (memory 256 256) (data (i32.const 10) "waka waka waka waka waka") - (export "test1" $test1) + (export "test1" (func $test1)) (func $test1 (i32.store16 (i32.const 33) (i32.const 109)) ;; after last segment due to size of type ) diff --git a/test/lit/basic/atomics.wast b/test/lit/basic/atomics.wast index e73d6b6111d..44786b31d60 100644 --- a/test/lit/basic/atomics.wast +++ b/test/lit/basic/atomics.wast @@ -546,7 +546,7 @@ ) ) (drop - (memory.atomic.wait64 align=8 offset=16 + (memory.atomic.wait64 offset=16 align=8 (local.get $0) (local.get $1) (local.get $1) diff --git a/test/lit/basic/atomics64.wast b/test/lit/basic/atomics64.wast index 255ecc033c3..016515a910c 100644 --- a/test/lit/basic/atomics64.wast +++ b/test/lit/basic/atomics64.wast @@ -558,7 +558,7 @@ ) ) (drop - (memory.atomic.wait64 align=8 offset=16 + (memory.atomic.wait64 offset=16 align=8 (local.get $0) (local.get $1) (local.get $1) diff --git a/test/lit/basic/multi-table.wast b/test/lit/basic/multi-table.wast index b856f8494c5..3a464dca194 100644 --- a/test/lit/basic/multi-table.wast +++ b/test/lit/basic/multi-table.wast @@ -83,7 +83,7 @@ ;; table. ;; CHECK-TEXT: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) ;; CHECK-BIN: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) - (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) $f $h) + (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) ;; CHECK-TEXT: (func $f (type $none_=>_none) ;; CHECK-TEXT-NEXT: (drop diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast index 94d4f352557..75d5f313f0c 100644 --- a/test/lit/basic/reference-types.wast +++ b/test/lit/basic/reference-types.wast @@ -174,7 +174,7 @@ (import "env" "import_func" (func $import_func (param eqref) (result funcref))) (import "env" "import_global" (global $import_global eqref)) - (export "export_func" (func $import_func (param eqref) (result funcref))) + (export "export_func" (func $import_func)) (export "export_global" (global $import_global)) ;; Test global initializer expressions diff --git a/test/lit/basic/simd.wast b/test/lit/basic/simd.wast index 483caefca2f..af771e659db 100644 --- a/test/lit/basic/simd.wast +++ b/test/lit/basic/simd.wast @@ -1738,7 +1738,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128) - (v128.load64_lane align=1 offset=32 0 + (v128.load64_lane offset=32 align=1 0 (local.get $0) (local.get $1) ) @@ -1871,7 +1871,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128) - (v128.store64_lane align=1 offset=32 0 + (v128.store64_lane offset=32 align=1 0 (local.get $0) (local.get $1) ) diff --git a/test/lit/if-then-else.wast b/test/lit/if-then-else.wast index 9d13cea9226..7fa59fad0e5 100644 --- a/test/lit/if-then-else.wast +++ b/test/lit/if-then-else.wast @@ -30,14 +30,14 @@ ;; CHECK-NEXT: ) (func $test (param i32) (result i32) (if - (local.get $0) + (local.get 0) (then) (else (return (i32.const 0)) ) ) (if - (local.get $0) + (local.get 0) (then (return (i32.const 1) diff --git a/test/lit/merge/renamings.wat b/test/lit/merge/renamings.wat index bb49b7ab77f..6d4de5c65f0 100644 --- a/test/lit/merge/renamings.wat +++ b/test/lit/merge/renamings.wat @@ -72,12 +72,12 @@ ;; CHECK: (table $other 70 80 funcref) ;; CHECK: (elem $foo func $foo $bar) - (elem $foo (ref null func) $foo $bar) + (elem $foo func $foo $bar) ;; This elem has a conflict in second.wat, and so second.wat's $bar ;; will be renamed. ;; CHECK: (elem $bar func $bar $foo) - (elem $bar (ref null func) $bar $foo) + (elem $bar func $bar $foo) ;; CHECK: (elem $other func $foo_3 $other) diff --git a/test/lit/merge/renamings.wat.second b/test/lit/merge/renamings.wat.second index 5c3c5d29961..f3489e62052 100644 --- a/test/lit/merge/renamings.wat.second +++ b/test/lit/merge/renamings.wat.second @@ -20,9 +20,9 @@ (table $other 70 80 funcref) - (elem $other (ref null func) $foo $other) + (elem $other func $foo $other) - (elem $bar (ref null func) $other $foo) + (elem $bar func $other $foo) (global $other i32 (i32.const 3)) diff --git a/test/lit/passes/Oz.wast b/test/lit/passes/Oz.wast index 42295ec2308..8c1db3083b7 100644 --- a/test/lit/passes/Oz.wast +++ b/test/lit/passes/Oz.wast @@ -48,7 +48,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $basics (export "localcse") (param $x i32) ($param $y i32) (result i32) ;; -O3 does localcse + (func $basics (export "localcse") (param $x i32) (param $y i32) (result i32) ;; -O3 does localcse (local $x2 i32) (local $y2 i32) (local.set $x2 diff --git a/test/lit/passes/alignment-lowering.wast b/test/lit/passes/alignment-lowering.wast index 0bcbbf3dfbc..164229e0725 100644 --- a/test/lit/passes/alignment-lowering.wast +++ b/test/lit/passes/alignment-lowering.wast @@ -982,7 +982,7 @@ (drop (i64.load align=1 (i32.const 12))) (drop (i64.load align=2 (i32.const 16))) (drop (i64.load align=4 (i32.const 20))) - (drop (i64.load align=1 offset=3 (i32.const 20))) + (drop (i64.load offset=3 align=1 (i32.const 20))) (drop (i64.load16_s align=1 (i32.const 28))) (drop (i64.load32_s align=1 (i32.const 32))) (drop (i64.load16_u align=1 (i32.const 40))) @@ -1088,7 +1088,7 @@ (func $f32-load (drop (f32.load align=1 (i32.const 12))) (drop (f32.load align=2 (i32.const 16))) - (drop (f32.load align=1 offset=3 (i32.const 20))) + (drop (f32.load offset=3 align=1 (i32.const 20))) ) ;; CHECK: (func $f64-load ;; CHECK-NEXT: (local $0 i32) @@ -1344,7 +1344,7 @@ (drop (f64.load align=1 (i32.const 12))) (drop (f64.load align=2 (i32.const 16))) (drop (f64.load align=4 (i32.const 20))) - (drop (f64.load align=1 offset=3 (i32.const 20))) + (drop (f64.load offset=3 align=1 (i32.const 20))) ) ;; CHECK: (func $i64-store ;; CHECK-NEXT: (local $0 i32) @@ -1670,7 +1670,7 @@ (i64.store align=1 (i32.const 12) (i64.const 100)) (i64.store align=2 (i32.const 16) (i64.const 200)) (i64.store align=4 (i32.const 20) (i64.const 300)) - (i64.store align=1 offset=3 (i32.const 24) (i64.const 400)) + (i64.store offset=3 align=1 (i32.const 24) (i64.const 400)) (i64.store16 align=1 (i32.const 20) (i64.const 600)) (i64.store32 align=1 (i32.const 20) (i64.const 700)) ) @@ -1776,7 +1776,7 @@ (func $f32-store (f32.store align=1 (i32.const 12) (f32.const 100)) (f32.store align=2 (i32.const 16) (f32.const 200)) - (f32.store align=1 offset=3 (i32.const 24) (f32.const 400)) + (f32.store offset=3 align=1 (i32.const 24) (f32.const 400)) ) ;; CHECK: (func $f64-store ;; CHECK-NEXT: (local $0 i32) @@ -2050,6 +2050,6 @@ (f64.store align=1 (i32.const 12) (f64.const 100)) (f64.store align=2 (i32.const 16) (f64.const 200)) (f64.store align=4 (i32.const 20) (f64.const 300)) - (f64.store align=1 offset=3 (i32.const 24) (f64.const 400)) + (f64.store offset=3 align=1 (i32.const 24) (f64.const 400)) ) ) diff --git a/test/lit/passes/alignment-lowering64.wast b/test/lit/passes/alignment-lowering64.wast index de49269112f..1a4f0557126 100644 --- a/test/lit/passes/alignment-lowering64.wast +++ b/test/lit/passes/alignment-lowering64.wast @@ -982,7 +982,7 @@ (drop (i64.load align=1 (i64.const 12))) (drop (i64.load align=2 (i64.const 16))) (drop (i64.load align=4 (i64.const 20))) - (drop (i64.load align=1 offset=3 (i64.const 20))) + (drop (i64.load offset=3 align=1 (i64.const 20))) (drop (i64.load16_s align=1 (i64.const 28))) (drop (i64.load32_s align=1 (i64.const 32))) (drop (i64.load16_u align=1 (i64.const 40))) @@ -1088,7 +1088,7 @@ (func $f32-load (drop (f32.load align=1 (i64.const 12))) (drop (f32.load align=2 (i64.const 16))) - (drop (f32.load align=1 offset=3 (i64.const 20))) + (drop (f32.load offset=3 align=1 (i64.const 20))) ) ;; CHECK: (func $f64-load ;; CHECK-NEXT: (local $0 i64) @@ -1344,7 +1344,7 @@ (drop (f64.load align=1 (i64.const 12))) (drop (f64.load align=2 (i64.const 16))) (drop (f64.load align=4 (i64.const 20))) - (drop (f64.load align=1 offset=3 (i64.const 20))) + (drop (f64.load offset=3 align=1 (i64.const 20))) ) ;; CHECK: (func $i64-store ;; CHECK-NEXT: (local $0 i64) @@ -1670,7 +1670,7 @@ (i64.store align=1 (i64.const 12) (i64.const 100)) (i64.store align=2 (i64.const 16) (i64.const 200)) (i64.store align=4 (i64.const 20) (i64.const 300)) - (i64.store align=1 offset=3 (i64.const 24) (i64.const 400)) + (i64.store offset=3 align=1 (i64.const 24) (i64.const 400)) (i64.store16 align=1 (i64.const 20) (i64.const 600)) (i64.store32 align=1 (i64.const 20) (i64.const 700)) ) @@ -1776,7 +1776,7 @@ (func $f32-store (f32.store align=1 (i64.const 12) (f32.const 100)) (f32.store align=2 (i64.const 16) (f32.const 200)) - (f32.store align=1 offset=3 (i64.const 24) (f32.const 400)) + (f32.store offset=3 align=1 (i64.const 24) (f32.const 400)) ) ;; CHECK: (func $f64-store ;; CHECK-NEXT: (local $0 i64) @@ -2050,6 +2050,6 @@ (f64.store align=1 (i64.const 12) (f64.const 100)) (f64.store align=2 (i64.const 16) (f64.const 200)) (f64.store align=4 (i64.const 20) (f64.const 300)) - (f64.store align=1 offset=3 (i64.const 24) (f64.const 400)) + (f64.store offset=3 align=1 (i64.const 24) (f64.const 400)) ) ) diff --git a/test/lit/passes/coalesce-locals-learning.wast b/test/lit/passes/coalesce-locals-learning.wast index aa20e87c5a2..5451c68cd26 100644 --- a/test/lit/passes/coalesce-locals-learning.wast +++ b/test/lit/passes/coalesce-locals-learning.wast @@ -18,9 +18,8 @@ (type $3 (func (param i32 f32))) ;; CHECK: (type $4 (func (param i32))) (type $4 (func (param i32))) - (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) ;; CHECK: (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) - + (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) ;; CHECK: (memory $0 10) ;; CHECK: (func $nothing-to-do diff --git a/test/lit/passes/coalesce-locals.wast b/test/lit/passes/coalesce-locals.wast index 9666c02fa6b..38fefc17a80 100644 --- a/test/lit/passes/coalesce-locals.wast +++ b/test/lit/passes/coalesce-locals.wast @@ -23,9 +23,6 @@ (type $2 (func)) (type $3 (func (param i32 f32))) (type $4 (func (param i32))) - (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) - (import $get "env" "get" (result i32)) - (import $set "env" "set" (param i32)) ;; CHECK: (type $7 (func (param i32) (result i32))) ;; CHECK: (type $8 (func (param i32 i32))) @@ -33,11 +30,11 @@ ;; CHECK: (type $9 (func (result f64))) ;; CHECK: (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) - + (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) ;; CHECK: (import "env" "get" (func $get (result i32))) - + (import "env" "get" (func $get (result i32))) ;; CHECK: (import "env" "set" (func $set (param i32))) - + (import "env" "set" (func $set (param i32))) ;; CHECK: (memory $0 10) ;; CHECK: (func $nothing-to-do diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast index 11638b62faa..f478c2ff3a7 100644 --- a/test/lit/passes/dae-gc-refine-return.wast +++ b/test/lit/passes/dae-gc-refine-return.wast @@ -541,7 +541,7 @@ (if (local.get $y) (then - (return (struct.new ${i32_f32})) + (return (struct.new_default ${i32_f32})) ) (else (return (ref.null any)) @@ -549,7 +549,7 @@ ) ) (else - (return (struct.new ${i32_i64})) + (return (struct.new_default ${i32_i64})) ) ) ) @@ -570,12 +570,12 @@ ;; Call $update-null so it gets optimized. (Call it with various values so ;; that other opts do not inline the constants.) (drop - ($call $update-null + (call $update-null (i32.const 0) (i32.const 1) ) ) - ($call $update-null + (call $update-null (i32.const 1) (i32.const 0) ) diff --git a/test/lit/passes/directize_all-features.wast b/test/lit/passes/directize_all-features.wast index c560baf0e8c..706a86c4656 100644 --- a/test/lit/passes/directize_all-features.wast +++ b/test/lit/passes/directize_all-features.wast @@ -1325,11 +1325,11 @@ ;; CHECK: (elem $0 (table $has-set) (i32.const 1) func $foo) ;; IMMUT: (elem $0 (table $has-set) (i32.const 1) func $foo) - (elem $0 (table $has-set) (i32.const 1) $foo) + (elem $0 (table $has-set) (i32.const 1) func $foo) ;; CHECK: (elem $1 (table $no-set) (i32.const 1) func $foo) ;; IMMUT: (elem $1 (table $no-set) (i32.const 1) func $foo) - (elem $1 (table $no-set) (i32.const 1) $foo) + (elem $1 (table $no-set) (i32.const 1) func $foo) ;; CHECK: (func $foo (type $v) ;; CHECK-NEXT: (table.set $has-set diff --git a/test/lit/passes/flatten_all-features.wast b/test/lit/passes/flatten_all-features.wast index fd73326090b..aa3dc7578d8 100644 --- a/test/lit/passes/flatten_all-features.wast +++ b/test/lit/passes/flatten_all-features.wast @@ -661,8 +661,8 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a13 (result i32) - (block $x i32 - (if i32 + (block $x (result i32) + (if (result i32) (br_table $x (i32.const 2) (i32.const 0)) (then (i32.const 0) @@ -702,7 +702,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $a14 (result i32) - (block i32 + (block (result i32) (select (i32.const 0) (i32.const 1) (br_table 0 (i32.const 7) (i32.const 1)) ) diff --git a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast index 4f1aa8ec382..142fabeea14 100644 --- a/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast +++ b/test/lit/passes/flatten_simplify-locals-nonesting_dfo_O3.wast @@ -84,7 +84,6 @@ ) (i32.const 15) ) - (i64.const 1) ) ) (else @@ -182,4 +181,3 @@ (i32.const -2766) ) ) - diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index 6d997dfa547..6bf32e95bcd 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -4361,7 +4361,6 @@ (i32.const 22) (f64.const 3.14159) ) - (i32.const 11) ) ;; This write might alias both types now. (struct.set $struct 0 @@ -4433,7 +4432,6 @@ (i32.const 10) (f64.const 3.14159) ) - (i32.const 10) ) (struct.set $struct 0 (global.get $something) diff --git a/test/lit/passes/instrument-memory.wast b/test/lit/passes/instrument-memory.wast index 86053c51cea..74b1e75d42d 100644 --- a/test/lit/passes/instrument-memory.wast +++ b/test/lit/passes/instrument-memory.wast @@ -421,20 +421,20 @@ (drop (f32.load (i32.const 0))) (drop (f64.load (i32.const 0))) - (drop (i32.load8_s align=1 offset=1 (i32.const 0))) - (drop (i32.load8_u align=1 offset=2 (i32.const 0))) - (drop (i32.load16_s align=1 offset=3 (i32.const 0))) - (drop (i32.load16_u align=1 offset=4 (i32.const 0))) - (drop (i32.load align=2 offset=5 (i32.const 0))) - (drop (i64.load8_s align=1 offset=6 (i32.const 0))) - (drop (i64.load8_u align=1 offset=7 (i32.const 0))) - (drop (i64.load16_s align=1 offset=8 (i32.const 0))) - (drop (i64.load16_u align=1 offset=9 (i32.const 0))) - (drop (i64.load32_s align=2 offset=10 (i32.const 0))) - (drop (i64.load32_u align=2 offset=11 (i32.const 0))) - (drop (i64.load align=2 offset=12 (i32.const 0))) - (drop (f32.load align=2 offset=13 (i32.const 0))) - (drop (f64.load align=2 offset=14 (i32.const 0))) + (drop (i32.load8_s offset=1 align=1 (i32.const 0))) + (drop (i32.load8_u offset=2 align=1 (i32.const 0))) + (drop (i32.load16_s offset=3 align=1 (i32.const 0))) + (drop (i32.load16_u offset=4 align=1 (i32.const 0))) + (drop (i32.load offset=5 align=2 (i32.const 0))) + (drop (i64.load8_s offset=6 align=1 (i32.const 0))) + (drop (i64.load8_u offset=7 align=1 (i32.const 0))) + (drop (i64.load16_s offset=8 align=1 (i32.const 0))) + (drop (i64.load16_u offset=9 align=1 (i32.const 0))) + (drop (i64.load32_s offset=10 align=2 (i32.const 0))) + (drop (i64.load32_u offset=11 align=2 (i32.const 0))) + (drop (i64.load offset=12 align=2 (i32.const 0))) + (drop (f32.load offset=13 align=2 (i32.const 0))) + (drop (f64.load offset=14 align=2 (i32.const 0))) ) ;; CHECK: (func $B @@ -666,14 +666,14 @@ (f32.store (i32.const 0) (f32.const 8)) (f64.store (i32.const 0) (f64.const 9)) - (i32.store8 align=1 offset=1 (i32.const 0) (i32.const 1)) - (i32.store16 align=1 offset=2 (i32.const 0) (i32.const 2)) - (i32.store align=2 offset=3 (i32.const 0) (i32.const 3)) - (i64.store8 align=1 offset=4 (i32.const 0) (i64.const 4)) - (i64.store16 align=2 offset=5 (i32.const 0) (i64.const 5)) - (i64.store32 align=2 offset=6 (i32.const 0) (i64.const 6)) - (i64.store align=2 offset=7 (i32.const 0) (i64.const 7)) - (f32.store align=2 offset=8 (i32.const 0) (f32.const 8)) - (f64.store align=2 offset=9 (i32.const 0) (f64.const 9)) + (i32.store8 offset=1 align=1 (i32.const 0) (i32.const 1)) + (i32.store16 offset=2 align=1 (i32.const 0) (i32.const 2)) + (i32.store offset=3 align=2 (i32.const 0) (i32.const 3)) + (i64.store8 offset=4 align=1 (i32.const 0) (i64.const 4)) + (i64.store16 offset=5 align=2 (i32.const 0) (i64.const 5)) + (i64.store32 offset=6 align=2 (i32.const 0) (i64.const 6)) + (i64.store offset=7 align=2 (i32.const 0) (i64.const 7)) + (f32.store offset=8 align=2 (i32.const 0) (f32.const 8)) + (f64.store offset=9 align=2 (i32.const 0) (f64.const 9)) ) ) diff --git a/test/lit/passes/instrument-memory64.wast b/test/lit/passes/instrument-memory64.wast index 832777a45ad..1f3be75d57c 100644 --- a/test/lit/passes/instrument-memory64.wast +++ b/test/lit/passes/instrument-memory64.wast @@ -421,20 +421,20 @@ (drop (f32.load (i64.const 0))) (drop (f64.load (i64.const 0))) - (drop (i32.load8_s align=1 offset=1 (i64.const 0))) - (drop (i32.load8_u align=1 offset=2 (i64.const 0))) - (drop (i32.load16_s align=1 offset=3 (i64.const 0))) - (drop (i32.load16_u align=1 offset=4 (i64.const 0))) - (drop (i32.load align=2 offset=5 (i64.const 0))) - (drop (i64.load8_s align=1 offset=6 (i64.const 0))) - (drop (i64.load8_u align=1 offset=7 (i64.const 0))) - (drop (i64.load16_s align=1 offset=8 (i64.const 0))) - (drop (i64.load16_u align=1 offset=9 (i64.const 0))) - (drop (i64.load32_s align=2 offset=10 (i64.const 0))) - (drop (i64.load32_u align=2 offset=11 (i64.const 0))) - (drop (i64.load align=2 offset=12 (i64.const 0))) - (drop (f32.load align=2 offset=13 (i64.const 0))) - (drop (f64.load align=2 offset=14 (i64.const 0))) + (drop (i32.load8_s offset=1 align=1 (i64.const 0))) + (drop (i32.load8_u offset=2 align=1 (i64.const 0))) + (drop (i32.load16_s offset=3 align=1 (i64.const 0))) + (drop (i32.load16_u offset=4 align=1 (i64.const 0))) + (drop (i32.load offset=5 align=2 (i64.const 0))) + (drop (i64.load8_s offset=6 align=1 (i64.const 0))) + (drop (i64.load8_u offset=7 align=1 (i64.const 0))) + (drop (i64.load16_s offset=8 align=1 (i64.const 0))) + (drop (i64.load16_u offset=9 align=1 (i64.const 0))) + (drop (i64.load32_s offset=10 align=2 (i64.const 0))) + (drop (i64.load32_u offset=11 align=2 (i64.const 0))) + (drop (i64.load offset=12 align=2 (i64.const 0))) + (drop (f32.load offset=13 align=2 (i64.const 0))) + (drop (f64.load offset=14 align=2 (i64.const 0))) ) ;; CHECK: (func $B @@ -666,14 +666,14 @@ (f32.store (i64.const 0) (f32.const 8)) (f64.store (i64.const 0) (f64.const 9)) - (i32.store8 align=1 offset=1 (i64.const 0) (i32.const 1)) - (i32.store16 align=1 offset=2 (i64.const 0) (i32.const 2)) - (i32.store align=2 offset=3 (i64.const 0) (i32.const 3)) - (i64.store8 align=1 offset=4 (i64.const 0) (i64.const 4)) - (i64.store16 align=2 offset=5 (i64.const 0) (i64.const 5)) - (i64.store32 align=2 offset=6 (i64.const 0) (i64.const 6)) - (i64.store align=2 offset=7 (i64.const 0) (i64.const 7)) - (f32.store align=2 offset=8 (i64.const 0) (f32.const 8)) - (f64.store align=2 offset=9 (i64.const 0) (f64.const 9)) + (i32.store8 offset=1 align=1 (i64.const 0) (i32.const 1)) + (i32.store16 offset=2 align=1 (i64.const 0) (i32.const 2)) + (i32.store offset=3 align=2 (i64.const 0) (i32.const 3)) + (i64.store8 offset=4 align=1 (i64.const 0) (i64.const 4)) + (i64.store16 offset=5 align=2 (i64.const 0) (i64.const 5)) + (i64.store32 offset=6 align=2 (i64.const 0) (i64.const 6)) + (i64.store offset=7 align=2 (i64.const 0) (i64.const 7)) + (f32.store offset=8 align=2 (i64.const 0) (f32.const 8)) + (f64.store offset=9 align=2 (i64.const 0) (f64.const 9)) ) ) diff --git a/test/lit/passes/multi-memory-lowering.wast b/test/lit/passes/multi-memory-lowering.wast index 7508a5627ca..9b7f5363503 100644 --- a/test/lit/passes/multi-memory-lowering.wast +++ b/test/lit/passes/multi-memory-lowering.wast @@ -373,7 +373,7 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128) - (v128.load16_lane $memory2 align=1 offset=32 0 + (v128.load16_lane $memory2 offset=32 align=1 0 (local.get $0) (local.get $1) ) @@ -417,7 +417,7 @@ ;; BOUNDS-NEXT: ) ;; BOUNDS-NEXT: ) (func $v128.load32_zero (param $0 i32) (result v128) - (v128.load32_zero $memory3 align=1 offset=16 + (v128.load32_zero $memory3 offset=16 align=1 (local.get $0) ) ) diff --git a/test/lit/passes/outlining.wast b/test/lit/passes/outlining.wast index ee6dd5d90bf..6e298b5fddf 100644 --- a/test/lit/passes/outlining.wast +++ b/test/lit/passes/outlining.wast @@ -731,12 +731,12 @@ ;; Test outlining works with call_indirect ;; 0 results, 2 params, 3 operands (module - (table funcref) + (table 1 1 funcref) ;; CHECK: (type $0 (func)) ;; CHECK: (type $1 (func (param i32 i32))) - ;; CHECK: (table $0 0 funcref) + ;; CHECK: (table $0 1 1 funcref) ;; CHECK: (func $outline$ (type $0) ;; CHECK-NEXT: (call_indirect $0 (type $1) @@ -769,10 +769,10 @@ ;; Test outlining works with call_indirect ;; 0 results, 0 params, 1 operand (module - (table funcref) + (table 1 1 funcref) ;; CHECK: (type $0 (func)) - ;; CHECK: (table $0 0 funcref) + ;; CHECK: (table $0 1 1 funcref) ;; CHECK: (func $outline$ (type $0) ;; CHECK-NEXT: (call_indirect $0 (type $0) @@ -797,12 +797,12 @@ ;; Test outlining works with call_indirect ;; 1 result, 0 params, 1 operand (module - (table funcref) + (table 1 1 funcref) ;; CHECK: (type $0 (func)) ;; CHECK: (type $1 (func (result i32))) - ;; CHECK: (table $0 0 funcref) + ;; CHECK: (table $0 1 1 funcref) ;; CHECK: (func $outline$ (type $0) ;; CHECK-NEXT: (drop @@ -835,12 +835,12 @@ ;; Test outlining works with call_indirect ;; 2 results, 0 params, 1 operand (module - (table funcref) + (table 1 1 funcref) ;; CHECK: (type $0 (func)) ;; CHECK: (type $1 (func (result i32 i32))) - ;; CHECK: (table $0 0 funcref) + ;; CHECK: (table $0 1 1 funcref) ;; CHECK: (func $outline$ (type $0) ;; CHECK-NEXT: (tuple.drop 2 diff --git a/test/lit/passes/poppify.wast b/test/lit/passes/poppify.wast index 93a0353e364..b8323b717d4 100644 --- a/test/lit/passes/poppify.wast +++ b/test/lit/passes/poppify.wast @@ -64,7 +64,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) (func $block (result i32) - (block i32 + (block (result i32) (nop) (i32.const 0) ) @@ -80,9 +80,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $nested (result i32) - (block $block i32 - (block $block0 i32 - (block $block1 i32 + (block $block (result i32) + (block $block0 (result i32) + (block $block1 (result i32) (i32.const 0) ) ) @@ -93,9 +93,9 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) (func $nested-nonames (result i32) - (block i32 - (block i32 - (block i32 + (block (result i32) + (block (result i32) + (block (result i32) (i32.const 0) ) ) @@ -160,7 +160,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $block-br (result i32) - (block $l i32 + (block $l (result i32) (nop) (br $l (i32.const 0) @@ -211,7 +211,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $if-else (result i32) - (if i32 + (if (result i32) (i32.const 0) (then (i32.const 1) @@ -238,7 +238,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $try-catch (result i32) - (try i32 + (try (result i32) (do (throw $e (i32.const 0) @@ -272,7 +272,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $try-delegate (result i32) - (try $l0 i32 + (try $l0 (result i32) (do (try (do diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast index c964d8c28a9..23f01878734 100644 --- a/test/lit/passes/remove-unused-module-elements_all-features.wast +++ b/test/lit/passes/remove-unused-module-elements_all-features.wast @@ -35,9 +35,9 @@ (type $2-dupe (func (param i32) (result i32))) (type $2-thrupe (func (param i32) (result i32))) (export "memory" (memory $0)) - (export "exported" $exported) - (export "other1" $other1) - (export "other2" $other2) + (export "exported" (func $exported)) + (export "other1" (func $other1)) + (export "other2" (func $other2)) (table 1 1 funcref) (elem (i32.const 0) $called_indirect) ;; CHECK: (func $start (type $0) @@ -237,11 +237,10 @@ ;; CHECK: (import "env" "memory" (memory $0 256)) (import "env" "memory" (memory $0 256)) (import "env" "table" (table 0 funcref)) - (export "user" $user) ;; CHECK: (import "env" "table" (table $timport$0 0 funcref)) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load @@ -262,9 +261,8 @@ ;; CHECK: (memory $0 23 256 shared) (memory $0 23 256 shared) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (i32.store ;; CHECK-NEXT: (i32.const 0) @@ -280,9 +278,8 @@ ;; CHECK: (memory $0 23 256 shared) (memory $0 23 256 shared) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (i32.atomic.rmw.add ;; CHECK-NEXT: (i32.const 0) @@ -298,9 +295,8 @@ ;; CHECK: (memory $0 23 256 shared) (memory $0 23 256 shared) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u ;; CHECK-NEXT: (i32.const 0) @@ -317,9 +313,8 @@ ;; CHECK: (memory $0 23 256 shared) (memory $0 23 256 shared) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i64) @@ -348,9 +343,8 @@ ;; CHECK: (memory $0 23 256 shared) (memory $0 23 256 shared) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (memory.atomic.notify ;; CHECK-NEXT: (i32.const 0) @@ -364,13 +358,12 @@ (module ;; atomic.fence and data.drop do not use a memory, so should not keep the memory alive. (memory $0 1 1 shared) (data "") - (export "fake-user" $user) ;; CHECK: (type $0 (func)) ;; CHECK: (data $0 "") ;; CHECK: (export "fake-user" (func $user)) - + (export "fake-user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (atomic.fence) ;; CHECK-NEXT: (data.drop $0) @@ -389,9 +382,8 @@ (memory $1 23 256) (memory $unused 1 1) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.grow $0 @@ -414,9 +406,8 @@ ;; CHECK: (memory $0 23 256) (memory $0 23 256) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) (result i32) ;; CHECK-NEXT: (memory.size) ;; CHECK-NEXT: ) @@ -432,9 +423,8 @@ ;; CHECK: (memory $1 1 1) (memory $1 1 1) (memory $unused 1 1) - (export "user" $user) ;; CHECK: (export "user" (func $user)) - + (export "user" (func $user)) ;; CHECK: (func $user (type $0) ;; CHECK-NEXT: (memory.copy $0 $1 ;; CHECK-NEXT: (i32.const 0) @@ -620,17 +610,17 @@ (table $defined-used 6 6 funcref) ;; CHECK: (elem $active1 (table $written) (i32.const 0) func $0) - (elem $active1 (table $written) (i32.const 0) $0) + (elem $active1 (table $written) (i32.const 0) func $0) ;; This empty active segment doesn't keep the unwritten table alive. - (elem $active2 (table $unwritten) (i32.const 0)) + (elem $active2 (table $unwritten) (i32.const 0) func) - (elem $active3 (table $defined-unused) (i32.const 0) $0) + (elem $active3 (table $defined-unused) (i32.const 0) func $0) ;; CHECK: (elem $active4 (table $defined-used) (i32.const 0) func $0) - (elem $active4 (table $defined-used) (i32.const 0) $0) + (elem $active4 (table $defined-used) (i32.const 0) func $0) - (elem $active5 (table $defined-used) (i32.const 0)) + (elem $active5 (table $defined-used) (i32.const 0) func) ;; CHECK: (func $0 (type $0) (param $var$0 f64) (result f64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.get $defined-used @@ -748,7 +738,6 @@ (array.new_elem $array 1 (i32.const 0) (i32.const 0) - (i32.const 0) ) ) ) diff --git a/test/lit/passes/stack-check-memory64.wast b/test/lit/passes/stack-check-memory64.wast index 137b156de2f..807e733e7e4 100644 --- a/test/lit/passes/stack-check-memory64.wast +++ b/test/lit/passes/stack-check-memory64.wast @@ -4,7 +4,7 @@ ;; RUN: foreach %s %t wasm-opt --stack-check --enable-memory64 -S -o - | filecheck %s (module - (memory i64 (data)) + (memory i64 0 0) ;; CHECK: (type $0 (func (result i64))) ;; CHECK: (type $1 (func (param i64 i64))) @@ -15,9 +15,7 @@ ;; CHECK: (global $__stack_limit (mut i64) (i64.const 0)) - ;; CHECK: (memory $0 i64 0 65536) - - ;; CHECK: (data $0 (i64.const 0) "") + ;; CHECK: (memory $0 i64 0 0) ;; CHECK: (export "use_stack" (func $use_stack)) @@ -64,7 +62,7 @@ ;; CHECK-NEXT: ) (module ;; if the global names are taken we should not crash - (memory i64 (data)) + (memory i64 0 0) ;; CHECK: (type $0 (func (result i64))) ;; CHECK: (type $1 (func (param i64 i64))) @@ -79,9 +77,7 @@ ;; CHECK: (global $__stack_limit_3 (mut i64) (i64.const 0)) - ;; CHECK: (memory $0 i64 0 65536) - - ;; CHECK: (data $0 (i64.const 0) "") + ;; CHECK: (memory $0 i64 0 0) ;; CHECK: (export "use_stack" (func $0)) (export "use_stack" (func $0)) diff --git a/test/lit/passes/stack-ir-non-nullable.wast b/test/lit/passes/stack-ir-non-nullable.wast index 62d75d61f04..99bad942387 100644 --- a/test/lit/passes/stack-ir-non-nullable.wast +++ b/test/lit/passes/stack-ir-non-nullable.wast @@ -535,7 +535,6 @@ (if (i32.eqz (local.get $temp) - (i32.const 0) ) (then (local.set $temp diff --git a/test/lit/passes/unsubtyping-casts.wast b/test/lit/passes/unsubtyping-casts.wast index 8019efcd8d1..c1993e8b431 100644 --- a/test/lit/passes/unsubtyping-casts.wast +++ b/test/lit/passes/unsubtyping-casts.wast @@ -424,21 +424,21 @@ (local $l (ref null $topA)) (local.set $l ;; Require $botA <: $topA. - (struct.new $botA) + (struct.new_default $botA) ) (drop ;; Now the cast requires $midA <: $topA so that a $botA value appearing in ;; the $topA location would still pass the cast to $midA. This will ;; transitively require $botB <: $topB. (ref.cast (ref $midA) - (struct.new $topA) + (struct.new_default $topA) ) ) (drop ;; Same as before, but now for the B types. This requires $botC <: $topC, but ;; only after the previous cast has already been analyzed. (ref.cast (ref $midB) - (struct.new $topB) + (struct.new_default $topB) ) ) (drop diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index 38549504e8e..ad74ab736a2 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -468,8 +468,8 @@ ;; CHECK: (type $2 (func (param (ref $super)))) - ;; CHECK: (table $t 0 funcref) - (table $t funcref) + ;; CHECK: (table $t 1 1 funcref) + (table $t 1 1 funcref) ;; CHECK: (func $call-indirect (type $2) (param $0 (ref $super)) ;; CHECK-NEXT: (call_indirect $t (type $2) @@ -497,8 +497,8 @@ ;; CHECK: (type $3 (func (result (ref $super)))) - ;; CHECK: (table $t 0 funcref) - (table $t funcref) + ;; CHECK: (table $t 1 1 funcref) + (table $t 1 1 funcref) ;; CHECK: (func $return-call-indirect (type $3) (result (ref $super)) ;; CHECK-NEXT: (return_call_indirect $t (type $2) @@ -521,8 +521,8 @@ (type $super (sub (func))) (type $sub (sub $super (func))) - ;; CHECK: (table $t 0 (ref null $super)) - (table $t (ref null $super) 1 1) + ;; CHECK: (table $t 1 1 (ref null $super)) + (table $t 1 1 (ref null $super)) ;; CHECK: (func $call-indirect-table (type $sub) ;; CHECK-NEXT: (call_indirect $t (type $sub) @@ -739,8 +739,8 @@ ;; CHECK: (type $2 (func)) - ;; CHECK: (table $t 0 (ref null $super)) - (table $t (ref null $super) 1 1) + ;; CHECK: (table $t 1 1 (ref null $super)) + (table $t 1 1 (ref null $super)) ;; CHECK: (func $table-set (type $2) ;; CHECK-NEXT: (table.set $t @@ -766,8 +766,8 @@ ;; CHECK: (type $2 (func)) - ;; CHECK: (table $t 0 (ref null $super)) - (table $t (ref null $super) 1 1) + ;; CHECK: (table $t 1 1 (ref null $super)) + (table $t 1 1 (ref null $super)) ;; CHECK: (func $table-fill (type $2) ;; CHECK-NEXT: (table.fill $t @@ -795,11 +795,11 @@ ;; CHECK: (type $sub (sub $super (struct ))) (type $sub (sub $super (struct))) - ;; CHECK: (table $super 0 (ref null $super)) - (table $super (ref null $super) 1 1) + ;; CHECK: (table $super 1 1 (ref null $super)) + (table $super 1 1 (ref null $super)) - ;; CHECK: (table $sub 0 (ref null $sub)) - (table $sub (ref null $sub) 1 1) + ;; CHECK: (table $sub 1 1 (ref null $sub)) + (table $sub 1 1 (ref null $sub)) ;; CHECK: (func $table-copy (type $0) ;; CHECK-NEXT: (table.copy $super $sub diff --git a/test/lit/passes/vacuum_all-features.wast b/test/lit/passes/vacuum_all-features.wast index e4b183663eb..5dbbb9386e4 100644 --- a/test/lit/passes/vacuum_all-features.wast +++ b/test/lit/passes/vacuum_all-features.wast @@ -16,13 +16,12 @@ (type $3 (func (result i32))) ;; CHECK: (type $4 (func (param i32 f64 i32 i32))) (type $4 (func (param i32 f64 i32 i32))) - (import $int "env" "int" (result i32)) ;; CHECK: (type $5 (func (param i32) (result i32))) ;; CHECK: (type $6 (func (result f64))) ;; CHECK: (import "env" "int" (func $int (type $3) (result i32))) - + (import "env" "int" (func $int (result i32))) ;; CHECK: (global $Int i32 (i32.const 0)) (global $Int i32 (i32.const 0)) ;; CHECK: (memory $0 256 256) @@ -1148,7 +1147,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $_deflate (param i32) (result i32) - (call $_deflate (local.get $0)) + (call $_deflate (local.get 0)) ) ;; CHECK: (func $_deflateInit2_ (type $0) (param $0 i32) (result i32) ;; CHECK-NEXT: (call $_deflateInit2_ @@ -1156,7 +1155,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $_deflateInit2_ (param i32) (result i32) - (call $_deflateInit2_ (local.get $0)) + (call $_deflateInit2_ (local.get 0)) ) ;; CHECK: (func $_deflateEnd (type $0) (param $0 i32) (result i32) ;; CHECK-NEXT: (call $_deflateEnd @@ -1164,7 +1163,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $_deflateEnd (param i32) (result i32) - (call $_deflateEnd (local.get $0)) + (call $_deflateEnd (local.get 0)) ) ;; CHECK: (func $compress (type $1) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-NEXT: (local $3 i32) diff --git a/test/metadce/segments.wast b/test/metadce/segments.wast index 96e0088e8d3..261c4e16405 100644 --- a/test/metadce/segments.wast +++ b/test/metadce/segments.wast @@ -2,7 +2,7 @@ (import "env" "g1" (global $g1 i32)) (import "env" "g2" (global $g2 i32)) - (table $tbl funcref) + (table $tbl 1 funcref) (elem (offset (global.get $g1)) funcref (ref.func $f)) (memory 3) diff --git a/test/metadce/segments.wast.dced b/test/metadce/segments.wast.dced index 2989ad60a10..a5694e863ac 100644 --- a/test/metadce/segments.wast.dced +++ b/test/metadce/segments.wast.dced @@ -4,7 +4,7 @@ (import "env" "g2" (global $g2 i32)) (memory $0 3) (data $0 (global.get $g2) "xxx") - (table $tbl 0 funcref) + (table $tbl 1 funcref) (elem $0 (global.get $g1) $f) (export "f" (func $f)) (func $f (type $0) (param $0 i32) diff --git a/test/metadce/table.wast b/test/metadce/table.wast index d1ee93ae47a..5b226b60fc9 100644 --- a/test/metadce/table.wast +++ b/test/metadce/table.wast @@ -6,7 +6,7 @@ (table $table-unused 10 funcref) ;; An active element segment, which is always used. - (elem $elem (table $table-used) (i32.const 0) $func) + (elem $elem (table $table-used) (i32.const 0) func $func) (elem $passive-elem-used $func) @@ -27,4 +27,3 @@ ) ) ) - diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 1d2b106b7ee..3893ddccd58 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -79,7 +79,7 @@ (struct.new_default $struct) ) (drop - (block $block (result ($ref $struct)) + (block $block (result (ref $struct)) (drop (block $extendedblock (result (ref $extendedstruct)) (drop @@ -348,7 +348,7 @@ (struct.new_default $struct) ) (drop - (block $block (result ($ref $struct)) + (block $block (result (ref $struct)) (drop (block $extendedblock (result (ref $extendedstruct)) (drop diff --git a/test/passes/duplicate-function-elimination_optimize-level=1.wast b/test/passes/duplicate-function-elimination_optimize-level=1.wast index 5b42a6ba5bd..1097f6715bf 100644 --- a/test/passes/duplicate-function-elimination_optimize-level=1.wast +++ b/test/passes/duplicate-function-elimination_optimize-level=1.wast @@ -52,8 +52,8 @@ (memory 0) (start $other) (type $0 (func)) - (export "keep2" $keep2) - (export "other" $other) + (export "keep2" (func $keep2)) + (export "other" (func $other)) (table 3 3 funcref) (elem (i32.const 0) $keep2 $other $caller) (func $keep2 (type $0) @@ -437,8 +437,8 @@ (module (memory 0) (type $FUNCSIG$v (func)) - (import $i "env" "i") - (import $j "env" "j") + (import "env" "i" (func $i)) + (import "env" "j" (func $j)) (func $erase (type $FUNCSIG$v) (call $i) ) @@ -449,8 +449,8 @@ (module (memory 0) (type $FUNCSIG$v (func)) - (import $i "env" "i") - (import $j "env" "j") + (import "env" "i" (func $i)) + (import "env" "j" (func $j)) (func $keep2 (type $FUNCSIG$v) (call $i) ) diff --git a/test/passes/duplicate-function-elimination_optimize-level=2.wast b/test/passes/duplicate-function-elimination_optimize-level=2.wast index 5b42a6ba5bd..1097f6715bf 100644 --- a/test/passes/duplicate-function-elimination_optimize-level=2.wast +++ b/test/passes/duplicate-function-elimination_optimize-level=2.wast @@ -52,8 +52,8 @@ (memory 0) (start $other) (type $0 (func)) - (export "keep2" $keep2) - (export "other" $other) + (export "keep2" (func $keep2)) + (export "other" (func $other)) (table 3 3 funcref) (elem (i32.const 0) $keep2 $other $caller) (func $keep2 (type $0) @@ -437,8 +437,8 @@ (module (memory 0) (type $FUNCSIG$v (func)) - (import $i "env" "i") - (import $j "env" "j") + (import "env" "i" (func $i)) + (import "env" "j" (func $j)) (func $erase (type $FUNCSIG$v) (call $i) ) @@ -449,8 +449,8 @@ (module (memory 0) (type $FUNCSIG$v (func)) - (import $i "env" "i") - (import $j "env" "j") + (import "env" "i" (func $i)) + (import "env" "j" (func $j)) (func $keep2 (type $FUNCSIG$v) (call $i) ) diff --git a/test/passes/fuzz-exec_all-features.wast b/test/passes/fuzz-exec_all-features.wast index bab6afb79e1..9250ad3eccd 100644 --- a/test/passes/fuzz-exec_all-features.wast +++ b/test/passes/fuzz-exec_all-features.wast @@ -36,13 +36,11 @@ (func $unaligned_load (export "unaligned_load") (result i32) (i32.atomic.load (i32.const 1) ;; unaligned ptr - (i32.const 1) ) ) (func $unaligned_load_offset (export "unaligned_load_offset") (result i32) (i32.atomic.load offset=1 ;; unaligned with offset (i32.const 0) - (i32.const 1) ) ) (func $aligned_for_size (export "aligned_for_size") (result i32) diff --git a/test/passes/merge-locals_all-features.wast b/test/passes/merge-locals_all-features.wast index b1d3aa9b7cc..0eff2bcb7b7 100644 --- a/test/passes/merge-locals_all-features.wast +++ b/test/passes/merge-locals_all-features.wast @@ -1,6 +1,6 @@ (module (global $global$0 (mut i32) (i32.const 10)) - (func $test (param $x $i32) (param $y i32) (result i32) + (func $test (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -16,7 +16,7 @@ ) (local.get $y) ;; turn this into $x ) - (func $test2 (param $x $i32) (param $y i32) (result i32) + (func $test2 (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -32,7 +32,7 @@ ) (local.get $x) ) - (func $test-multiple (param $x $i32) (param $y i32) (result i32) + (func $test-multiple (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -49,7 +49,7 @@ (drop (local.get $y)) ;; turn this into $x (local.get $y) ;; turn this into $x ) - (func $test-just-some (param $x $i32) (param $y i32) (result i32) + (func $test-just-some (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -67,7 +67,7 @@ (local.set $y (i32.const 200)) (local.get $y) ;; but not this one! ) - (func $test-just-some2 (param $x $i32) (param $y i32) (result i32) + (func $test-just-some2 (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -92,7 +92,7 @@ ) (i32.const 500) ) - (func $test-just-some3 (param $x $i32) (param $y i32) (result i32) + (func $test-just-some3 (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -117,7 +117,7 @@ ) (local.get $y) ;; but not this one! ) - (func $silly-self (param $x $i32) (param $y i32) (result i32) + (func $silly-self (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -133,7 +133,7 @@ ) (local.get $y) ;; turn this into $x ) - (func $silly-multi (param $x $i32) (param $y i32) (result i32) + (func $silly-multi (param $x i32) (param $y i32) (result i32) (drop (if (result i32) (local.tee $x @@ -179,7 +179,7 @@ (local.get $var$1) ;; can't be changed to $var$2, as it changes ) ) - (func $reverse (param $x $i32) (param $y i32) + (func $reverse (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -201,7 +201,7 @@ ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-end (param $x $i32) (param $y i32) + (func $reverse-end (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -216,7 +216,7 @@ ) ) ) - (func $reverse-lone-end-2 (param $x $i32) (param $y i32) + (func $reverse-lone-end-2 (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -233,7 +233,7 @@ (local.set $y (i32.const 200)) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-undo (param $x $i32) (param $y i32) + (func $reverse-undo (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -256,7 +256,7 @@ ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-undo2 (param $x $i32) (param $y i32) + (func $reverse-undo2 (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -279,7 +279,7 @@ ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-undo3-conditional (param $x $i32) (param $y i32) + (func $reverse-undo3-conditional (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -306,7 +306,7 @@ ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-undo3-conditional-b (param $x $i32) (param $y i32) + (func $reverse-undo3-conditional-b (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x @@ -333,7 +333,7 @@ ) (drop (local.get $y)) ;; cannot this into $x, since this $y has multiple sources ) - (func $reverse-undo3-conditional-c (param $x $i32) (param $y i32) + (func $reverse-undo3-conditional-c (param $x i32) (param $y i32) (drop (if (result i32) (local.tee $x diff --git a/test/passes/optimize-instructions_fuzz-exec.wast b/test/passes/optimize-instructions_fuzz-exec.wast index f047e3ac2b8..927ca5c06fd 100644 --- a/test/passes/optimize-instructions_fuzz-exec.wast +++ b/test/passes/optimize-instructions_fuzz-exec.wast @@ -4,57 +4,57 @@ (func $test32 (export "test32") (call $logf32 (f32.add - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.sub - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.mul - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.div - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.copysign - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.min - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.max - (f32.const -nan:0xffff82) + (f32.const -nan:0x7fff82) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) @@ -122,13 +122,13 @@ (f32.add (f32.const 0) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.add - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) (f32.neg (f32.const 0) ) @@ -138,13 +138,13 @@ (f32.add (f32.const -0) (f32.neg - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) ) ) ) (call $logf32 (f32.add - (f32.const -nan:0xfff622) + (f32.const -nan:0x7ff622) (f32.neg (f32.const -0) ) @@ -154,13 +154,13 @@ (f32.add (f32.const 0) (f32.neg - (f32.const nan:0xfff622) + (f32.const nan:0x7ff622) ) ) ) (call $logf32 (f32.add - (f32.const nan:0xfff622) + (f32.const nan:0x7ff622) (f32.neg (f32.const 0) ) diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt index 3f5908ef053..8021136f2d6 100644 --- a/test/passes/precompute_all-features.txt +++ b/test/passes/precompute_all-features.txt @@ -8,7 +8,7 @@ (type $6 (func (result externref))) (global $global i32 (i32.const 1)) (global $global-mut (mut i32) (i32.const 2)) - (memory $0 6 65536) + (memory $m 512 512) (data $0 (i32.const 0) "hello!") (elem declare func $dummy) (func $x (type $0) (param $x i32) diff --git a/test/passes/precompute_all-features.wast b/test/passes/precompute_all-features.wast index 633787fad48..f6ad267f26b 100644 --- a/test/passes/precompute_all-features.wast +++ b/test/passes/precompute_all-features.wast @@ -1,5 +1,6 @@ (module - (memory (data "hello!") 512 512) + (memory $m 512 512) + (data (memory $m) (i32.const 0) "hello!") (type $0 (func (param i32))) (global $global i32 (i32.const 1)) (global $global-mut (mut i32) (i32.const 2)) diff --git a/test/passes/remove-imports.wast b/test/passes/remove-imports.wast index a96a438f588..77c16e99152 100644 --- a/test/passes/remove-imports.wast +++ b/test/passes/remove-imports.wast @@ -3,10 +3,10 @@ (type $FUNCSIG$v (func)) (type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$d (func (result f64))) - (import $waka "somewhere" "waka") - (import $waka-ret "somewhere" "waka-ret" (result i32)) - (import $waka-ret-d "somewhere" "waka-ret-d" (result f64)) - (import $waka-sneaky "somewhere" "waka-sneaky") + (import "somewhere" "waka" (func $waka)) + (import "somewhere" "waka-ret" (func $waka-ret (result i32))) + (import "somewhere" "waka-ret-d" (func $waka-ret-d (result f64))) + (import "somewhere" "waka-sneaky" (func $waka-sneaky)) (import "env" "memBase" (global i32)) (import "env" "table" (table $table 1 1 funcref)) (elem (i32.const 0) $waka-sneaky) diff --git a/test/passes/remove-unused-names_code-folding.wast b/test/passes/remove-unused-names_code-folding.wast index 642bbdf7c09..6fba5ddde16 100644 --- a/test/passes/remove-unused-names_code-folding.wast +++ b/test/passes/remove-unused-names_code-folding.wast @@ -429,13 +429,13 @@ (if (local.get $x) (then (block - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) (else (block - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) @@ -443,13 +443,13 @@ (if (local.get $x) (then (block - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) (else (block - (br_if $out2 (local.get $y i32)) + (br_if $out2 (local.get $y)) (nop) ) ) @@ -460,14 +460,14 @@ (then (block (nop) - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) (else (block (nop) - (br_if $out2 (local.get $y i32)) + (br_if $out2 (local.get $y)) (nop) ) ) @@ -477,13 +477,13 @@ (if (local.get $x) (then (block $left - (br_if $left (local.get $y i32)) + (br_if $left (local.get $y)) (nop) ) ) (else (block - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) @@ -491,13 +491,13 @@ (if (local.get $x) (then (block - (br_if $out (local.get $y i32)) + (br_if $out (local.get $y)) (nop) ) ) (else (block $right - (br_if $right (local.get $y i32)) + (br_if $right (local.get $y)) (nop) ) ) diff --git a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast index 5ed444ca244..2917b23a048 100644 --- a/test/passes/remove-unused-nonfunction-module-elements_all-features.wast +++ b/test/passes/remove-unused-nonfunction-module-elements_all-features.wast @@ -9,9 +9,9 @@ (type $2-dupe (func (param i32) (result i32))) (type $2-thrupe (func (param i32) (result i32))) (export "memory" (memory $0)) - (export "exported" $exported) - (export "other1" $other1) - (export "other2" $other2) + (export "exported" (func $exported)) + (export "other1" (func $other1)) + (export "other2" (func $other2)) (table 1 1 funcref) (elem (i32.const 0) $called_indirect) (func $start (type $0) @@ -94,7 +94,7 @@ (type $0 (func)) (import "env" "memory" (memory $0 256)) (import "env" "table" (table 0 funcref)) - (export "user" $user) + (export "user" (func $user)) (func $user (drop (i32.load (i32.const 0))) (call_indirect (type $0) (i32.const 0)) @@ -102,28 +102,28 @@ ) (module ;; more use checks (memory $0 23 256 shared) - (export "user" $user) + (export "user" (func $user)) (func $user (i32.store (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks (memory $0 23 256 shared) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (i32.atomic.rmw.add (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks (memory $0 23 256 shared) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (i32.atomic.rmw8.cmpxchg_u (i32.const 0) (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks (memory $0 23 256 shared) - (export "user" $user) + (export "user" (func $user)) (func $user (local $0 i32) (local $1 i64) @@ -138,28 +138,28 @@ ) (module ;; more use checks (memory $0 23 256 shared) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (memory.atomic.notify (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks (memory $0 23 256) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (memory.grow (i32.const 0)) ) ) (module ;; more use checks (import "env" "memory" (memory $0 256)) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (memory.grow (i32.const 0)) ) ) (module ;; more use checks (memory $0 23 256) - (export "user" $user) + (export "user" (func $user)) (func $user (result i32) (memory.size) ) diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast index b302a317ded..e51abda5ca2 100644 --- a/test/passes/simplify-locals_all-features.wast +++ b/test/passes/simplify-locals_all-features.wast @@ -7,11 +7,11 @@ (type $4 (func (param i32))) (type $5 (func (param i32) (result i32))) (type $6 (func (param i32 i32 i32 i32 i32 i32))) - (import $waka "env" "waka") - (import $waka_int "env" "waka_int" (result i32)) - (import $_i64Subtract "env" "i64sub" (param i32 i32 i32 i32) (result i32)) - (import $___udivmoddi4 "env" "moddi" (param i32 i32 i32 i32 i32) (result i32)) - (import $lp "env" "lp" (param i32 i32) (result i32)) + (import "env" "waka" (func $waka)) + (import "env" "waka_int" (func $waka_int (result i32))) + (import "env" "i64sub" (func $_i64Subtract (param i32 i32 i32 i32) (result i32))) + (import "env" "moddi" (func $___udivmoddi4 (param i32 i32 i32 i32 i32) (result i32))) + (import "env" "lp" (func $lp (param i32 i32) (result i32))) (import "fuzzing-support" "log-f32" (func $fimport$0 (param f32))) (global $global$0 (mut i32) (i32.const 10)) (func $contrast ;; check for tee and structure sinking @@ -1710,7 +1710,7 @@ (func $memory-init-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1733,7 +1733,7 @@ (func $memory-copy-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1756,7 +1756,7 @@ (func $memory-fill-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1779,7 +1779,7 @@ (func $data-drop-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1792,7 +1792,7 @@ (func $data-drop-memory-init (local $x i32) (local.set $x - (block i32 + (block (result i32) (memory.init 0 (i32.const 0) (i32.const 0) (i32.const 5)) (i32.const 0) ) diff --git a/test/passes/simplify-locals_all-features_disable-exception-handling.wast b/test/passes/simplify-locals_all-features_disable-exception-handling.wast index 9cb4bf748bd..9fa89ea20e9 100644 --- a/test/passes/simplify-locals_all-features_disable-exception-handling.wast +++ b/test/passes/simplify-locals_all-features_disable-exception-handling.wast @@ -7,11 +7,11 @@ (type $4 (func (param i32))) (type $5 (func (param i32) (result i32))) (type $6 (func (param i32 i32 i32 i32 i32 i32))) - (import $waka "env" "waka") - (import $waka_int "env" "waka_int" (result i32)) - (import $_i64Subtract "env" "i64sub" (param i32 i32 i32 i32) (result i32)) - (import $___udivmoddi4 "env" "moddi" (param i32 i32 i32 i32 i32) (result i32)) - (import $lp "env" "lp" (param i32 i32) (result i32)) + (import "env" "waka" (func $waka)) + (import "env" "waka_int" (func $waka_int (result i32))) + (import "env" "i64sub" (func $_i64Subtract (param i32 i32 i32 i32) (result i32))) + (import "env" "moddi" (func $___udivmoddi4 (param i32 i32 i32 i32 i32) (result i32))) + (import "env" "lp" (func $lp (param i32 i32) (result i32))) (import "fuzzing-support" "log-f32" (func $fimport$0 (param f32))) (global $global$0 (mut i32) (i32.const 10)) (func $contrast ;; check for tee and structure sinking @@ -1710,7 +1710,7 @@ (func $memory-init-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1733,7 +1733,7 @@ (func $memory-copy-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1756,7 +1756,7 @@ (func $memory-fill-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1779,7 +1779,7 @@ (func $data-drop-store (local $x i32) (local.set $x - (block i32 + (block (result i32) (i32.store (i32.const 0) (i32.const 42)) (i32.const 0) ) @@ -1792,7 +1792,7 @@ (func $data-drop-memory-init (local $x i32) (local.set $x - (block i32 + (block (result i32) (memory.init 0 (i32.const 0) (i32.const 0) (i32.const 5)) (i32.const 0) ) diff --git a/test/passes/ssa-nomerge_enable-simd.wast b/test/passes/ssa-nomerge_enable-simd.wast index f99febe3e5d..da44b57aee6 100644 --- a/test/passes/ssa-nomerge_enable-simd.wast +++ b/test/passes/ssa-nomerge_enable-simd.wast @@ -23,7 +23,7 @@ (local $x i32) (local $y i32) (drop - (if i32 + (if (result i32) (i32.const 1) (then (local.get $x) diff --git a/test/passes/ssa_enable-threads.wast b/test/passes/ssa_enable-threads.wast index a368f3c348f..d2614b7919f 100644 --- a/test/passes/ssa_enable-threads.wast +++ b/test/passes/ssa_enable-threads.wast @@ -22,7 +22,7 @@ (local $x i32) (local $y i32) (drop - (if i32 + (if (result i32) (i32.const 1) (then (local.get $x) @@ -446,4 +446,3 @@ (i32.const -54) ) ) - From 185019919b1fa2efe8d02056827a31f4f50dd01e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 8 Jan 2024 16:03:33 -0800 Subject: [PATCH 033/553] Fix global effect computation with -O flags (#6211) We tested --generate-global-effects --vacuum and such, but not --generate-global-effects -O3 or the other -O flags. Unfortunately, our targeted testing missed a bug because of that. Specifically, we have special logic for -O flags to make sure the passes they expand into run with the proper opt and shrink levels, but that logic happened to also interfere with global effect computation. It would also interfere with allowing GUFA info or other things to be stored on the side, which we've proposed. This PR fixes that + future issues. The fix is to just allow a pass runner to execute more than once. We thought to avoid that and assert against it to keep the model "hermetic" (you create a pass runner, you run the passes, and you throw it out), which feels nice in a way, but it led to the bug here, and I'm not sure it would prevent any other ones really. It is also more code. It is simpler to allow a runner to execute more than once, and add a method to clear it. With that, the logic for -O3 execution is both simpler and does not interfere with anything but the opt and shrink level flags: we create a single runner, give it the proper options, and then keep using that runner + those options as we go, normally. --- src/pass.h | 11 +- src/passes/pass.cpp | 5 +- src/tools/optimization-options.h | 44 +++--- test/lit/passes/global-effects-O.wast | 198 ++++++++++++++++++++++++++ 4 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 test/lit/passes/global-effects-O.wast diff --git a/src/pass.h b/src/pass.h index 83f53c23ad9..2c2fa06190c 100644 --- a/src/pass.h +++ b/src/pass.h @@ -235,8 +235,9 @@ struct PassOptions { // other passes later can benefit from it. It is up to the sequence of passes // to update or discard this when necessary - in particular, when new effects // are added to a function this must be changed or we may optimize - // incorrectly (however, it is extremely rare for a pass to *add* effects; - // passes normally only remove effects). + // incorrectly. However, it is extremely rare for a pass to *add* effects; + // passes normally only remove effects. Passes that do add effects must set + // addsEffects() so the pass runner is aware of them. std::shared_ptr funcEffectsMap; // -Os is our default @@ -318,6 +319,9 @@ struct PassRunner { // Add a pass given an instance. void add(std::unique_ptr pass) { doAdd(std::move(pass)); } + // Clears away all passes that have been added. + void clear(); + // Adds the pass if there are no DWARF-related issues. There is an issue if // there is DWARF and if the pass does not support DWARF (as defined by the // pass returning true from invalidatesDWARF); otherwise, if there is no @@ -387,9 +391,6 @@ struct PassRunner { // yet) have removed DWARF. bool addedPassesRemovedDWARF = false; - // Whether this pass runner has run. A pass runner should only be run once. - bool ran = false; - void runPass(Pass* pass); void runPassOnFunction(Pass* pass, Function* func); diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index d7391a390c3..62b3683fad9 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -739,9 +739,6 @@ static void dumpWasm(Name name, Module* wasm) { } void PassRunner::run() { - assert(!ran); - ran = true; - static const int passDebug = getPassDebug(); // Emit logging information when asked for. At passDebug level 1+ we log // the main passes, while in 2 we also log nested ones. Note that for @@ -885,6 +882,8 @@ void PassRunner::doAdd(std::unique_ptr pass) { passes.emplace_back(std::move(pass)); } +void PassRunner::clear() { passes.clear(); } + // Checks that the state is valid before and after a // pass runs on a function. We run these extra checks when // pass-debug mode is enabled. diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h index 045542ac25a..0a47d9f709e 100644 --- a/src/tools/optimization-options.h +++ b/src/tools/optimization-options.h @@ -328,44 +328,46 @@ struct OptimizationOptions : public ToolOptions { bool runningPasses() { return passes.size() > 0; } void runPasses(Module& wasm) { - std::unique_ptr passRunner; + PassRunner passRunner(&wasm, passOptions); + if (debug) { + passRunner.setDebug(true); + } // Flush anything in the current pass runner, and then reset it to a fresh // state so it is ready for new things. - auto flushAndReset = [&]() { - if (passRunner) { - passRunner->run(); - } - passRunner = std::make_unique(&wasm, passOptions); - if (debug) { - passRunner->setDebug(true); - } + auto flush = [&]() { + passRunner.run(); + passRunner.clear(); }; - flushAndReset(); - for (auto& pass : passes) { if (pass.name == DEFAULT_OPT_PASSES) { // This is something like -O3 or -Oz. We must run this now, in order to // set the proper opt and shrink levels. To do that, first reset the // runner so that anything already queued is run (since we can only run // after those things). - flushAndReset(); + flush(); // -O3/-Oz etc. always set their own optimize/shrinkLevels. assert(pass.optimizeLevel); assert(pass.shrinkLevel); - passRunner->options.optimizeLevel = *pass.optimizeLevel; - passRunner->options.shrinkLevel = *pass.shrinkLevel; - // Run our optimizations now, and reset the runner so that the default - // pass options are used later (and not the temporary optimize/ - // shrinkLevels we just set). - passRunner->addDefaultOptimizationPasses(); - flushAndReset(); + // Temporarily override the default levels. + assert(passRunner.options.optimizeLevel == passOptions.optimizeLevel); + assert(passRunner.options.shrinkLevel == passOptions.shrinkLevel); + passRunner.options.optimizeLevel = *pass.optimizeLevel; + passRunner.options.shrinkLevel = *pass.shrinkLevel; + + // Run our optimizations now with the custom levels. + passRunner.addDefaultOptimizationPasses(); + flush(); + + // Restore the default optimize/shrinkLevels. + passRunner.options.optimizeLevel = passOptions.optimizeLevel; + passRunner.options.shrinkLevel = passOptions.shrinkLevel; } else { // This is a normal pass. Add it to the queue for execution. - passRunner->add(pass.name); + passRunner.add(pass.name); // Normal passes do not set their own optimize/shrinkLevels. assert(!pass.optimizeLevel); @@ -373,7 +375,7 @@ struct OptimizationOptions : public ToolOptions { } } - flushAndReset(); + flush(); } }; diff --git a/test/lit/passes/global-effects-O.wast b/test/lit/passes/global-effects-O.wast new file mode 100644 index 00000000000..c24159eace4 --- /dev/null +++ b/test/lit/passes/global-effects-O.wast @@ -0,0 +1,198 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects | filecheck %s --check-prefix CHECK_0 +;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O1 | filecheck %s --check-prefix CHECK_1 +;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O3 | filecheck %s --check-prefix CHECK_3 +;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -Os | filecheck %s --check-prefix CHECK_s +;; RUN: foreach %s %t wasm-opt -all -S -o - --generate-global-effects -O | filecheck %s --check-prefix CHECK_O + +;; Test that global effects benefit -O1 and related modes. + +(module + ;; CHECK_0: (type $0 (func)) + + ;; CHECK_0: (type $1 (func (result i32))) + + ;; CHECK_0: (export "main" (func $main)) + ;; CHECK_1: (type $0 (func)) + + ;; CHECK_1: (type $1 (func (result i32))) + + ;; CHECK_1: (export "main" (func $main)) + ;; CHECK_3: (type $0 (func)) + + ;; CHECK_3: (type $1 (func (result i32))) + + ;; CHECK_3: (export "main" (func $main)) + ;; CHECK_s: (type $0 (func)) + + ;; CHECK_s: (type $1 (func (result i32))) + + ;; CHECK_s: (export "main" (func $main)) + ;; CHECK_O: (type $0 (func)) + + ;; CHECK_O: (type $1 (func (result i32))) + + ;; CHECK_O: (export "main" (func $main)) + (export "main" (func $main)) + + ;; CHECK_0: (export "pointless-work" (func $pointless-work)) + ;; CHECK_1: (export "pointless-work" (func $pointless-work)) + ;; CHECK_3: (export "pointless-work" (func $pointless-work)) + ;; CHECK_s: (export "pointless-work" (func $pointless-work)) + ;; CHECK_O: (export "pointless-work" (func $pointless-work)) + (export "pointless-work" (func $pointless-work)) + + ;; CHECK_0: (func $main (type $0) + ;; CHECK_0-NEXT: (if + ;; CHECK_0-NEXT: (call $pointless-work) + ;; CHECK_0-NEXT: (then + ;; CHECK_0-NEXT: (drop + ;; CHECK_0-NEXT: (call $pointless-work) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_1: (func $main (type $0) + ;; CHECK_1-NEXT: (nop) + ;; CHECK_1-NEXT: ) + ;; CHECK_3: (func $main (type $0) (; has Stack IR ;) + ;; CHECK_3-NEXT: (nop) + ;; CHECK_3-NEXT: ) + ;; CHECK_s: (func $main (type $0) (; has Stack IR ;) + ;; CHECK_s-NEXT: (nop) + ;; CHECK_s-NEXT: ) + ;; CHECK_O: (func $main (type $0) (; has Stack IR ;) + ;; CHECK_O-NEXT: (nop) + ;; CHECK_O-NEXT: ) + (func $main + ;; This calls a function that does pointless work. After generating global + ;; effects we can see that it is pointless and remove this entire if (except + ;; for -O0). + (if + (call $pointless-work) + (then + (drop + (call $pointless-work) + ) + ) + ) + ) + + ;; CHECK_0: (func $pointless-work (type $1) (result i32) + ;; CHECK_0-NEXT: (local $x i32) + ;; CHECK_0-NEXT: (loop $loop + ;; CHECK_0-NEXT: (local.set $x + ;; CHECK_0-NEXT: (i32.add + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: (i32.const 1) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (if + ;; CHECK_0-NEXT: (i32.ge_u + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: (i32.const 12345678) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (then + ;; CHECK_0-NEXT: (return + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (br $loop) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_1: (func $pointless-work (type $1) (result i32) + ;; CHECK_1-NEXT: (local $0 i32) + ;; CHECK_1-NEXT: (loop $loop (result i32) + ;; CHECK_1-NEXT: (br_if $loop + ;; CHECK_1-NEXT: (i32.lt_u + ;; CHECK_1-NEXT: (local.tee $0 + ;; CHECK_1-NEXT: (i32.add + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: (i32.const 1) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (i32.const 12345678) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_3: (func $pointless-work (type $1) (; has Stack IR ;) (result i32) + ;; CHECK_3-NEXT: (local $0 i32) + ;; CHECK_3-NEXT: (loop $loop (result i32) + ;; CHECK_3-NEXT: (br_if $loop + ;; CHECK_3-NEXT: (i32.lt_u + ;; CHECK_3-NEXT: (local.tee $0 + ;; CHECK_3-NEXT: (i32.add + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: (i32.const 1) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (i32.const 12345678) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_s: (func $pointless-work (type $1) (; has Stack IR ;) (result i32) + ;; CHECK_s-NEXT: (local $0 i32) + ;; CHECK_s-NEXT: (loop $loop (result i32) + ;; CHECK_s-NEXT: (br_if $loop + ;; CHECK_s-NEXT: (i32.lt_u + ;; CHECK_s-NEXT: (local.tee $0 + ;; CHECK_s-NEXT: (i32.add + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: (i32.const 1) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (i32.const 12345678) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_O: (func $pointless-work (type $1) (; has Stack IR ;) (result i32) + ;; CHECK_O-NEXT: (local $0 i32) + ;; CHECK_O-NEXT: (loop $loop (result i32) + ;; CHECK_O-NEXT: (br_if $loop + ;; CHECK_O-NEXT: (i32.lt_u + ;; CHECK_O-NEXT: (local.tee $0 + ;; CHECK_O-NEXT: (i32.add + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: (i32.const 1) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (i32.const 12345678) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + (func $pointless-work (result i32) + (local $x i32) + ;; Some pointless work, with no side effects, that cannot be inlined. (The + ;; changes here are not important for this test.) + (loop $loop + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) + ) + (if + (i32.ge_u + (local.get $x) + (i32.const 12345678) + ) + (then + (return + (local.get $x) + ) + ) + ) + (br $loop) + ) + ) +) From 75145b78b8b9cdabd98af849821f34dee0168466 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 9 Jan 2024 13:22:50 -0800 Subject: [PATCH 034/553] [NFC] Add more const annotations + a trivial == (#6216) --- src/ir/possible-constant.h | 6 +++++- src/ir/subtypes.h | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ir/possible-constant.h b/src/ir/possible-constant.h index 21f1cfa6554..79a9973b530 100644 --- a/src/ir/possible-constant.h +++ b/src/ir/possible-constant.h @@ -48,6 +48,10 @@ struct PossibleConstantValues { public: PossibleConstantValues() : value(None()) {} + bool operator==(const PossibleConstantValues& other) const { + return value == other.value; + } + // Notes the contents of an expression and update our internal knowledge based // on it and all previous values noted. void note(Expression* expr, Module& wasm) { @@ -155,7 +159,7 @@ struct PossibleConstantValues { } // Assuming we have a single value, make an expression containing that value. - Expression* makeExpression(Module& wasm) { + Expression* makeExpression(Module& wasm) const { Builder builder(wasm); if (isConstantLiteral()) { return builder.makeConstantExpression(getConstantLiteral()); diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h index 488bb831089..8645afb9898 100644 --- a/src/ir/subtypes.h +++ b/src/ir/subtypes.h @@ -145,7 +145,8 @@ struct SubTypes { // Efficiently iterate on subtypes of a type, up to a particular depth (depth // 0 means not to traverse subtypes, etc.). The callback function receives // (type, depth). - template void iterSubTypes(HeapType type, Index depth, F func) { + template + void iterSubTypes(HeapType type, Index depth, F func) const { // Start by traversing the type itself. func(type, 0); @@ -186,7 +187,7 @@ struct SubTypes { } // As above, but iterate to the maximum depth. - template void iterSubTypes(HeapType type, F func) { + template void iterSubTypes(HeapType type, F func) const { return iterSubTypes(type, std::numeric_limits::max(), func); } From 20b1ccc05987cf28f0d7f8b413e06a6c44decf04 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 9 Jan 2024 13:40:05 -0800 Subject: [PATCH 035/553] Testing: Write out and read back in the big binary in c-api-kitchen-sink.c (#6217) --- test/example/c-api-kitchen-sink.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index d3368a6b147..f91733a8d3e 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -1526,10 +1526,28 @@ void test_core() { BinaryenModulePrint(module); // Verify it validates - assert(BinaryenModuleValidate(module)); + int valid = BinaryenModuleValidate(module); + assert(valid); + + // Verify no error occurs when writing out the code to binary. + size_t bufferSize = 10 * 1024 * 1024; + char* buffer = malloc(bufferSize); + size_t written = BinaryenModuleWrite(module, buffer, bufferSize); + // We wrote bytes, and we did not reach the end of the buffer (which would + // truncate). + assert(written > 0 && written < bufferSize); // Clean up the module, which owns all the objects we created above BinaryenModuleDispose(module); + + // See we can read the bytes and get a valid module from there. + BinaryenModuleRef readModule = BinaryenModuleRead(buffer, written); + BinaryenModuleSetFeatures(readModule, BinaryenFeatureAll()); + valid = BinaryenModuleValidate(readModule); + assert(valid); + BinaryenModuleDispose(readModule); + + free(buffer); } void test_unreachable() { From 97a61bd7c35756c25ac3637744097c1a0fc99dea Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 10 Jan 2024 08:56:39 -0800 Subject: [PATCH 036/553] [Parser] Parse remaining heap and reference types (#6218) Parse types like `exnref` and `nofunc` that we did not previously support. --- src/parser/contexts.h | 30 +++++++++++++------- src/parser/parsers.h | 50 +++++++++++++++++++++++++++------- test/lit/wat-kitchen-sink.wast | 23 ++++++++++++++-- 3 files changed, 81 insertions(+), 22 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index f489a2c056c..7e9add5a793 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -97,17 +97,22 @@ struct NullTypeParserCtx { using ElemListT = Ok; using DataStringT = Ok; - HeapTypeT makeFunc() { return Ok{}; } - HeapTypeT makeAny() { return Ok{}; } - HeapTypeT makeExtern() { return Ok{}; } - HeapTypeT makeEq() { return Ok{}; } - HeapTypeT makeI31() { return Ok{}; } + HeapTypeT makeFuncType() { return Ok{}; } + HeapTypeT makeAnyType() { return Ok{}; } + HeapTypeT makeExternType() { return Ok{}; } + HeapTypeT makeEqType() { return Ok{}; } + HeapTypeT makeI31Type() { return Ok{}; } HeapTypeT makeStructType() { return Ok{}; } HeapTypeT makeArrayType() { return Ok{}; } + HeapTypeT makeExnType() { return Ok{}; } HeapTypeT makeStringType() { return Ok{}; } HeapTypeT makeStringViewWTF8Type() { return Ok{}; } HeapTypeT makeStringViewWTF16Type() { return Ok{}; } HeapTypeT makeStringViewIterType() { return Ok{}; } + HeapTypeT makeNoneType() { return Ok{}; } + HeapTypeT makeNoextType() { return Ok{}; } + HeapTypeT makeNofuncType() { return Ok{}; } + HeapTypeT makeNoexnType() { return Ok{}; } TypeT makeI32() { return Ok{}; } TypeT makeI64() { return Ok{}; } @@ -187,17 +192,22 @@ template struct TypeParserCtx { Ctx& self() { return *static_cast(this); } - HeapTypeT makeFunc() { return HeapType::func; } - HeapTypeT makeAny() { return HeapType::any; } - HeapTypeT makeExtern() { return HeapType::ext; } - HeapTypeT makeEq() { return HeapType::eq; } - HeapTypeT makeI31() { return HeapType::i31; } + HeapTypeT makeFuncType() { return HeapType::func; } + HeapTypeT makeAnyType() { return HeapType::any; } + HeapTypeT makeExternType() { return HeapType::ext; } + HeapTypeT makeEqType() { return HeapType::eq; } + HeapTypeT makeI31Type() { return HeapType::i31; } HeapTypeT makeStructType() { return HeapType::struct_; } HeapTypeT makeArrayType() { return HeapType::array; } + HeapTypeT makeExnType() { return HeapType::exn; } HeapTypeT makeStringType() { return HeapType::string; } HeapTypeT makeStringViewWTF8Type() { return HeapType::stringview_wtf8; } HeapTypeT makeStringViewWTF16Type() { return HeapType::stringview_wtf16; } HeapTypeT makeStringViewIterType() { return HeapType::stringview_iter; } + HeapTypeT makeNoneType() { return HeapType::none; } + HeapTypeT makeNoextType() { return HeapType::noext; } + HeapTypeT makeNofuncType() { return HeapType::nofunc; } + HeapTypeT makeNoexnType() { return HeapType::noexn; } TypeT makeI32() { return Type::i32; } TypeT makeI64() { return Type::i64; } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 28110a628e2..1ae5cc08012 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -236,19 +236,19 @@ template WithPosition(Ctx& ctx, Index) -> WithPosition; // | 'extern' => extern template Result heaptype(Ctx& ctx) { if (ctx.in.takeKeyword("func"sv)) { - return ctx.makeFunc(); + return ctx.makeFuncType(); } if (ctx.in.takeKeyword("any"sv)) { - return ctx.makeAny(); + return ctx.makeAnyType(); } if (ctx.in.takeKeyword("extern"sv)) { - return ctx.makeExtern(); + return ctx.makeExternType(); } if (ctx.in.takeKeyword("eq"sv)) { - return ctx.makeEq(); + return ctx.makeEqType(); } if (ctx.in.takeKeyword("i31"sv)) { - return ctx.makeI31(); + return ctx.makeI31Type(); } if (ctx.in.takeKeyword("struct"sv)) { return ctx.makeStructType(); @@ -256,6 +256,9 @@ template Result heaptype(Ctx& ctx) { if (ctx.in.takeKeyword("array"sv)) { return ctx.makeArrayType(); } + if (ctx.in.takeKeyword("exn"sv)) { + return ctx.makeExnType(); + } if (ctx.in.takeKeyword("string"sv)) { return ctx.makeStringType(); } @@ -268,6 +271,18 @@ template Result heaptype(Ctx& ctx) { if (ctx.in.takeKeyword("stringview_iter"sv)) { return ctx.makeStringViewIterType(); } + if (ctx.in.takeKeyword("none"sv)) { + return ctx.makeNoneType(); + } + if (ctx.in.takeKeyword("noextern"sv)) { + return ctx.makeNoextType(); + } + if (ctx.in.takeKeyword("nofunc"sv)) { + return ctx.makeNofuncType(); + } + if (ctx.in.takeKeyword("noexn"sv)) { + return ctx.makeNoexnType(); + } auto type = typeidx(ctx); CHECK_ERR(type); return *type; @@ -283,19 +298,19 @@ template Result heaptype(Ctx& ctx) { // | '(' ref null? t:heaptype ')' => ref null? t template MaybeResult reftype(Ctx& ctx) { if (ctx.in.takeKeyword("funcref"sv)) { - return ctx.makeRefType(ctx.makeFunc(), Nullable); + return ctx.makeRefType(ctx.makeFuncType(), Nullable); } if (ctx.in.takeKeyword("externref"sv)) { - return ctx.makeRefType(ctx.makeExtern(), Nullable); + return ctx.makeRefType(ctx.makeExternType(), Nullable); } if (ctx.in.takeKeyword("anyref"sv)) { - return ctx.makeRefType(ctx.makeAny(), Nullable); + return ctx.makeRefType(ctx.makeAnyType(), Nullable); } if (ctx.in.takeKeyword("eqref"sv)) { - return ctx.makeRefType(ctx.makeEq(), Nullable); + return ctx.makeRefType(ctx.makeEqType(), Nullable); } if (ctx.in.takeKeyword("i31ref"sv)) { - return ctx.makeRefType(ctx.makeI31(), Nullable); + return ctx.makeRefType(ctx.makeI31Type(), Nullable); } if (ctx.in.takeKeyword("structref"sv)) { return ctx.makeRefType(ctx.makeStructType(), Nullable); @@ -303,6 +318,9 @@ template MaybeResult reftype(Ctx& ctx) { if (ctx.in.takeKeyword("arrayref"sv)) { return ctx.makeRefType(ctx.makeArrayType(), Nullable); } + if (ctx.in.takeKeyword("exnref"sv)) { + return ctx.makeRefType(ctx.makeExnType(), Nullable); + } if (ctx.in.takeKeyword("stringref"sv)) { return ctx.makeRefType(ctx.makeStringType(), Nullable); } @@ -315,6 +333,18 @@ template MaybeResult reftype(Ctx& ctx) { if (ctx.in.takeKeyword("stringview_iter"sv)) { return ctx.makeRefType(ctx.makeStringViewIterType(), Nullable); } + if (ctx.in.takeKeyword("nullref"sv)) { + return ctx.makeRefType(ctx.makeNoneType(), Nullable); + } + if (ctx.in.takeKeyword("nullexternref"sv)) { + return ctx.makeRefType(ctx.makeNoextType(), Nullable); + } + if (ctx.in.takeKeyword("nullfuncref"sv)) { + return ctx.makeRefType(ctx.makeNofuncType(), Nullable); + } + if (ctx.in.takeKeyword("nullexnref"sv)) { + return ctx.makeRefType(ctx.makeNoexnType(), Nullable); + } if (!ctx.in.takeSExprStart("ref"sv)) { return {}; diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index b0de467af8e..8c0c8fb8077 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -214,9 +214,27 @@ ;; CHECK: (type $submany (sub final $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) (type $submany (sub final $many (func (param i32 i64 f32 f64) (result anyref (ref func))))) + ;; CHECK: (type $all-types (struct (field externref) (field (ref extern)) (field funcref) (field (ref func)) (field anyref) (field (ref any)) (field eqref) (field (ref eq)) (field i31ref) (field (ref i31)) (field structref) (field (ref struct)) (field arrayref) (field (ref array)) (field exnref) (field (ref exn)) (field stringref) (field (ref string)) (field stringview_wtf8) (field (ref stringview_wtf8)) (field stringview_wtf16) (field (ref stringview_wtf16)) (field stringview_iter) (field (ref stringview_iter)) (field nullref) (field (ref none)) (field nullexternref) (field (ref noextern)) (field nullfuncref) (field (ref nofunc)) (field nullexnref) (field (ref noexn)))) + (type $all-types (struct externref (ref extern) + funcref (ref func) + anyref (ref any) + eqref (ref eq) + i31ref (ref i31) + structref (ref struct) + arrayref (ref array) + exnref (ref exn) + stringref (ref string) + stringview_wtf8 (ref stringview_wtf8) + stringview_wtf16 (ref stringview_wtf16) + stringview_iter (ref stringview_iter) + nullref (ref none) + nullexternref (ref noextern) + nullfuncref (ref nofunc) + nullexnref (ref noexn))) + ;; imported memories (memory (export "mem") (export "mem2") (import "" "mem") 0) - ;; CHECK: (type $90 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany)))) + ;; CHECK: (type $91 (func (param (ref $s0) (ref $s1) (ref $s2) (ref $s3) (ref $s4) (ref $s5) (ref $s6) (ref $s7) (ref $s8) (ref $a0) (ref $a1) (ref $a2) (ref $a3) (ref $subvoid) (ref $submany) (ref $all-types)))) ;; CHECK: (import "" "mem" (memory $mimport$0 0)) @@ -4724,7 +4742,7 @@ ) ) - ;; CHECK: (func $use-types (type $90) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) + ;; CHECK: (func $use-types (type $91) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) (param $15 (ref $all-types)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-types @@ -4743,5 +4761,6 @@ (param (ref $a3)) (param (ref $subvoid)) (param (ref $submany)) + (param (ref $all-types)) ) ) From 141f7cad3aa516db3828e619b31fe681e46a151b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 10 Jan 2024 15:02:05 -0800 Subject: [PATCH 037/553] Precompute into select arms (#6212) E.g. (i32.add (select (i32.const 100) (i32.const 200) (..condition..) ) (i32.const 50) ) ;; => (select (i32.const 150) (i32.const 250) (..condition..) ) We cannot fully precompute the select, but we can "partially precompute" it, by precomputing its arms using the parent. This may require looking several steps up the parent chain, which is an awkward operation in our simple walkers, so to do it we capture stacks of parents and operate directly on them. This is a little slower than a normal walk, so only do it when we see a promising select, and only in -O2 and above (this makes the pass 7% or so slower; not a large cost, but best to avoid it in -O1). --- src/passes/Precompute.cpp | 330 +++++++++- test/lit/passes/precompute-partial.wast | 788 ++++++++++++++++++++++++ 2 files changed, 1106 insertions(+), 12 deletions(-) create mode 100644 test/lit/passes/precompute-partial.wast diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 4178342a2dc..5baf2331f14 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -27,16 +27,19 @@ // looked at. // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "ir/effects.h" +#include "ir/iteration.h" +#include "ir/literal-utils.h" +#include "ir/local-graph.h" +#include "ir/manipulation.h" +#include "ir/properties.h" +#include "ir/utils.h" +#include "pass.h" +#include "support/insert_ordered.h" +#include "support/unique_deferring_queue.h" +#include "wasm-builder.h" +#include "wasm-interpreter.h" +#include "wasm.h" namespace wasm { @@ -210,9 +213,16 @@ struct Precompute GetValues getValues; HeapValues heapValues; + bool canPartiallyPrecompute; + void doWalkFunction(Function* func) { + // Perform partial precomputing only when the optimization level is non- + // trivial, as it is slower and less likely to help. + canPartiallyPrecompute = getPassOptions().optimizeLevel >= 2; + // Walk the function and precompute things. super::doWalkFunction(func); + partiallyPrecompute(func); if (!propagate) { return; } @@ -226,11 +236,13 @@ struct Precompute // another walk to apply them and perhaps other optimizations that are // unlocked. super::doWalkFunction(func); + // We could also try to partially precompute again, but that is a somewhat + // heavy operation, so we only do it the first time, and leave such things + // for later runs of this pass and for --converge. } // Note that in principle even more cycles could find further work here, in // very rare cases. To avoid constructing a LocalGraph again just for that - // unlikely chance, we leave such things for later runs of this pass and for - // --converge. + // unlikely chance, we leave such things for later. } template void reuseConstantNode(T* curr, Flow flow) { @@ -281,6 +293,9 @@ struct Precompute } if (flow.breaking()) { if (flow.breakTo == NONCONSTANT_FLOW) { + // This cannot be turned into a constant, but perhaps we can partially + // precompute it. + considerPartiallyPrecomputing(curr); return; } if (flow.breakTo == RETURN_FLOW) { @@ -319,6 +334,273 @@ struct Precompute } } + // If we failed to precompute a constant, perhaps we can still precompute part + // of an expression. Specifically, consider this case: + // + // (A + // (select + // (B) + // (C) + // (condition) + // ) + // ) + // + // Perhaps we can compute A(B) and A(C). If so, we can emit a better select: + // + // (select + // (constant result of A(B)) + // (constant result of A(C)) + // (condition) + // ) + // + // Note that in general for code size we want to move operations *out* of + // selects and ifs (OptimizeInstructions does that), but here we are + // computing two constants which replace three expressions, so it is + // worthwhile. + // + // To do such partial precomputing, in the main pass we note selects that look + // promising. If we find any then we do a second pass later just for that (as + // doing so requires walking up the stack in a manner that we want to avoid in + // the main pass for overhead reasons; see below). + // + // Note that selects are all we really need here: Other passes would turn an + // if into a select if the arms are simple enough, and only in those cases + // (simple arms) do we have a chance at partially precomputing. For example, + // if an arm is a constant then we can, but if it is a call then we can't.) + // However, there are cases like an if with arms with side effects that end in + // precomputable things, that are missed atm TODO + std::unordered_set partiallyPrecomputable; + + void considerPartiallyPrecomputing(Expression* curr) { + if (!canPartiallyPrecompute) { + return; + } + + if (auto* select = curr->dynCast(); - Index i = 1; - Type type = parseBlockType(s, i); - ret->ifTrue = parseExpression(s[i++]); - ret->ifFalse = parseExpression(s[i++]); - ret->condition = parseExpression(s[i]); - if (type.isConcrete()) { - ret->finalize(type); - } else { - ret->finalize(); - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeDrop(Element& s) { - auto ret = allocator.alloc(); - ret->value = parseExpression(s[1]); - if (ret->value->type.isTuple()) { - throw SParseException("expected tuple.drop, found drop", s, *s[0]); - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeMemorySize(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name memory; - if (s.size() > 1) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - if (isMemory64(memory)) { - ret->type = Type::i64; - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeMemoryGrow(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name memory; - if (s.size() > 2) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - if (isMemory64(memory)) { - ret->type = Type::i64; - } - ret->delta = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Index SExpressionWasmBuilder::getLocalIndex(Element& s) { - if (!currFunction) { - throw SParseException("local access in non-function scope", s); - } - if (s.dollared()) { - auto ret = s.str(); - if (currFunction->localIndices.count(ret) == 0) { - throw SParseException("bad local name", s); - } - return currFunction->getLocalIndex(ret); - } - // this is a numeric index - Index ret = parseIndex(s); - if (ret >= currFunction->getNumLocals()) { - throw SParseException("bad local index", s); - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeLocalGet(Element& s) { - auto ret = allocator.alloc(); - ret->index = getLocalIndex(*s[1]); - ret->type = currFunction->getLocalType(ret->index); - return ret; -} - -Expression* SExpressionWasmBuilder::makeLocalTee(Element& s) { - auto ret = allocator.alloc(); - ret->index = getLocalIndex(*s[1]); - ret->value = parseExpression(s[2]); - ret->makeTee(currFunction->getLocalType(ret->index)); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeLocalSet(Element& s) { - auto ret = allocator.alloc(); - ret->index = getLocalIndex(*s[1]); - ret->value = parseExpression(s[2]); - ret->makeSet(); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeGlobalGet(Element& s) { - auto ret = allocator.alloc(); - ret->name = getGlobalName(*s[1]); - auto* global = wasm.getGlobalOrNull(ret->name); - if (!global) { - throw SParseException("bad global.get name", s); - } - ret->type = global->type; - return ret; -} - -Expression* SExpressionWasmBuilder::makeGlobalSet(Element& s) { - auto ret = allocator.alloc(); - ret->name = getGlobalName(*s[1]); - if (wasm.getGlobalOrNull(ret->name) && - !wasm.getGlobalOrNull(ret->name)->mutable_) { - throw SParseException("global.set of immutable", s); - } - ret->value = parseExpression(s[2]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeBlock(Element& s) { - if (!currFunction) { - throw SParseException("block is unallowed outside of functions", s); - } - // special-case Block, because Block nesting (in their first element) can be - // incredibly deep - auto curr = allocator.alloc(); - auto* sp = &s; - // The information we need for the stack of blocks here is the element we are - // converting, the block we are converting it to, and whether it originally - // had a name or not (which will be useful later). - struct Info { - Element* element; - Block* block; - bool hadName; - }; - std::vector stack; - while (1) { - auto& s = *sp; - Index i = 1; - Name sName; - bool hadName = false; - if (i < s.size() && s[i]->isStr()) { - // could be a name or a type - if (s[i]->dollared() || - stringToType(s[i]->str(), true /* allowError */) == Type::none) { - sName = s[i++]->str(); - hadName = true; - } else { - sName = "block"; - } - } else { - sName = "block"; - } - stack.emplace_back(Info{sp, curr, hadName}); - curr->name = nameMapper.pushLabelName(sName); - // block signature - curr->type = parseBlockType(s, i); - if (i >= s.size()) { - break; // empty block - } - auto& first = *s[i]; - if (elementStartsWith(first, BLOCK)) { - // recurse - curr = allocator.alloc(); - if (first.startLoc) { - currFunction->debugLocations[curr] = getDebugLocation(*first.startLoc); - } - sp = &first; - continue; - } - break; - } - // we now have a stack of Blocks, with their labels, but no contents yet - for (int t = int(stack.size()) - 1; t >= 0; t--) { - auto* sp = stack[t].element; - auto* curr = stack[t].block; - auto hadName = stack[t].hadName; - auto& s = *sp; - size_t i = 1; - if (i < s.size()) { - while (i < s.size() && s[i]->isStr()) { - i++; - } - while (i < s.size() && (elementStartsWith(*s[i], RESULT) || - elementStartsWith(*s[i], TYPE))) { - i++; - } - if (t < int(stack.size()) - 1) { - // first child is one of our recursions - curr->list.push_back(stack[t + 1].block); - i++; - } - for (; i < s.size(); i++) { - curr->list.push_back(parseExpression(s[i])); - } - } - nameMapper.popLabelName(curr->name); - curr->finalize(curr->type); - // If the block never had a name, and one was not needed in practice (even - // if one did not exist, perhaps a break targeted it by index), then we can - // remove the name. Note that we only do this if it never had a name: if it - // did, we don't want to change anything; we just want to be the same as - // the code we are loading - if there was no name before, we don't want one - // now, so that we roundtrip text precisely. - if (!hadName && !BranchUtils::BranchSeeker::has(curr, curr->name)) { - curr->name = Name(); - } - } - return stack[0].block; -} - -// Similar to block, but the label is handled by the enclosing if (since there -// might not be a then or else, ick) -Expression* SExpressionWasmBuilder::makeThenOrElse(Element& s) { - if (s.size() == 2) { - return parseExpression(s[1]); - } - auto ret = allocator.alloc(); - for (size_t i = 1; i < s.size(); i++) { - ret->list.push_back(parseExpression(s[i])); - } - ret->finalize(); - return ret; -} - -static Expression* parseConst(IString s, Type type, MixedArena& allocator) { - const char* str = s.str.data(); - auto ret = allocator.alloc(); - ret->type = type; - if (type.isFloat()) { - if (s == _INFINITY) { - switch (type.getBasic()) { - case Type::f32: - ret->value = Literal(std::numeric_limits::infinity()); - break; - case Type::f64: - ret->value = Literal(std::numeric_limits::infinity()); - break; - default: - return nullptr; - } - return ret; - } - if (s == NEG_INFINITY) { - switch (type.getBasic()) { - case Type::f32: - ret->value = Literal(-std::numeric_limits::infinity()); - break; - case Type::f64: - ret->value = Literal(-std::numeric_limits::infinity()); - break; - default: - return nullptr; - } - return ret; - } - if (s == _NAN) { - switch (type.getBasic()) { - case Type::f32: - ret->value = Literal(float(std::nan(""))); - break; - case Type::f64: - ret->value = Literal(double(std::nan(""))); - break; - default: - return nullptr; - } - return ret; - } - bool negative = str[0] == '-'; - const char* positive = negative ? str + 1 : str; - if (!negative) { - if (positive[0] == '+') { - positive++; - } - } - if (positive[0] == 'n' && positive[1] == 'a' && positive[2] == 'n') { - const char* modifier = positive[3] == ':' ? positive + 4 : nullptr; - if (!(modifier ? positive[4] == '0' && positive[5] == 'x' : 1)) { - throw ParseException("bad nan input: "s + str); - } - switch (type.getBasic()) { - case Type::f32: { - uint32_t pattern; - if (modifier) { - std::istringstream istr(modifier); - istr >> std::hex >> pattern; - if (istr.fail()) { - throw ParseException("invalid f32 format: "s + str); - } - pattern |= 0x7f800000U; - } else { - pattern = 0x7fc00000U; - } - if (negative) { - pattern |= 0x80000000U; - } - if (!std::isnan(bit_cast(pattern))) { - pattern |= 1U; - } - ret->value = Literal(pattern).castToF32(); - break; - } - case Type::f64: { - uint64_t pattern; - if (modifier) { - std::istringstream istr(modifier); - istr >> std::hex >> pattern; - if (istr.fail()) { - throw ParseException("invalid f64 format: "s + str); - } - pattern |= 0x7ff0000000000000ULL; - } else { - pattern = 0x7ff8000000000000UL; - } - if (negative) { - pattern |= 0x8000000000000000ULL; - } - if (!std::isnan(bit_cast(pattern))) { - pattern |= 1ULL; - } - ret->value = Literal(pattern).castToF64(); - break; - } - default: - return nullptr; - } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - if (s == NEG_NAN) { - switch (type.getBasic()) { - case Type::f32: - ret->value = Literal(float(-std::nan(""))); - break; - case Type::f64: - ret->value = Literal(double(-std::nan(""))); - break; - default: - return nullptr; - } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - } - switch (type.getBasic()) { - case Type::i32: { - if ((str[0] == '0' && str[1] == 'x') || - (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { - bool negative = str[0] == '-'; - if (negative) { - str++; - } - std::istringstream istr(str); - uint32_t temp; - istr >> std::hex >> temp; - if (istr.fail()) { - throw ParseException("invalid i32 format: "s + str); - } - ret->value = Literal(negative ? -temp : temp); - } else { - std::istringstream istr(str[0] == '-' ? str + 1 : str); - uint32_t temp; - istr >> temp; - if (istr.fail()) { - throw ParseException("invalid i32 format: "s + str); - } - ret->value = Literal(str[0] == '-' ? -temp : temp); - } - break; - } - case Type::i64: { - if ((str[0] == '0' && str[1] == 'x') || - (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { - bool negative = str[0] == '-'; - if (negative) { - str++; - } - std::istringstream istr(str); - uint64_t temp; - istr >> std::hex >> temp; - if (istr.fail()) { - throw ParseException("invalid i64 format: "s + str); - } - ret->value = Literal(negative ? -temp : temp); - } else { - std::istringstream istr(str[0] == '-' ? str + 1 : str); - uint64_t temp; - istr >> temp; - if (istr.fail()) { - throw ParseException("invalid i64 format: "s + str); - } - ret->value = Literal(str[0] == '-' ? -temp : temp); - } - break; - } - case Type::f32: { - char* end; - ret->value = Literal(strtof(str, &end)); - break; - } - case Type::f64: { - char* end; - ret->value = Literal(strtod(str, &end)); - break; - } - case Type::v128: - WASM_UNREACHABLE("unexpected const type"); - case Type::none: - case Type::unreachable: { - return nullptr; - } - } - if (ret->value.type != type) { - throw ParseException("parsed type does not match expected type: "s + str); - } - return ret; -} - -template -static Literal makeLanes(Element& s, MixedArena& allocator, Type lane_t) { - std::array lanes; - for (size_t i = 0; i < Lanes; ++i) { - Expression* lane = parseConst(s[i + 2]->str(), lane_t, allocator); - if (lane) { - lanes[i] = lane->cast()->value; - } else { - throw SParseException("Could not parse v128 lane", s, *s[i + 2]); - } - } - return Literal(lanes); -} - -Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) { - if (type != Type::v128) { - auto ret = parseConst(s[1]->str(), type, allocator); - if (!ret) { - throw SParseException("bad const", s, *s[1]); - } - return ret; - } - - auto ret = allocator.alloc(); - Type lane_t = stringToLaneType(s[1]->str().str.data()); - size_t lanes = s.size() - 2; - switch (lanes) { - case 2: { - if (lane_t != Type::i64 && lane_t != Type::f64) { - throw SParseException("Unexpected v128 literal lane type", s); - } - ret->value = makeLanes<2>(s, allocator, lane_t); - break; - } - case 4: { - if (lane_t != Type::i32 && lane_t != Type::f32) { - throw SParseException("Unexpected v128 literal lane type", s); - } - ret->value = makeLanes<4>(s, allocator, lane_t); - break; - } - case 8: { - if (lane_t != Type::i32) { - throw SParseException("Unexpected v128 literal lane type", s); - } - ret->value = makeLanes<8>(s, allocator, lane_t); - break; - } - case 16: { - if (lane_t != Type::i32) { - throw SParseException("Unexpected v128 literal lane type", s); - } - ret->value = makeLanes<16>(s, allocator, lane_t); - break; - } - default: - throw SParseException("Unexpected number of lanes in v128 literal", s); - } - ret->finalize(); - return ret; -} - -static size_t parseMemAttributes(size_t i, - Element& s, - Address& offset, - Address& align, - bool memory64) { - // Parse "align=X" and "offset=X" arguments, bailing out on anything else. - while (!s[i]->isList()) { - const char* str = s[i]->str().str.data(); - if (strncmp(str, "align", 5) != 0 && strncmp(str, "offset", 6) != 0) { - return i; - } - const char* eq = strchr(str, '='); - if (!eq) { - throw SParseException("missing = in memory attribute", s); - } - eq++; - if (*eq == 0) { - throw SParseException("missing value in memory attribute", s); - } - char* endptr; - uint64_t value = strtoll(eq, &endptr, 10); - if (*endptr != 0) { - throw SParseException("bad memory attribute immediate", s); - } - if (str[0] == 'a') { - if (value > std::numeric_limits::max()) { - throw SParseException("bad align", s); - } - align = value; - } else if (str[0] == 'o') { - if (!memory64 && value > std::numeric_limits::max()) { - throw SParseException("bad offset", s); - } - offset = value; - } else { - throw SParseException("bad memory attribute", s); - } - i++; - } - return i; -} - -bool SExpressionWasmBuilder::hasMemoryIdx(Element& s, - Index defaultSize, - Index i) { - if (s.size() > defaultSize && !s[i]->isList() && - strncmp(s[i]->str().str.data(), "align", 5) != 0 && - strncmp(s[i]->str().str.data(), "offset", 6) != 0) { - return true; - } - return false; -} - -Expression* SExpressionWasmBuilder::makeLoad( - Element& s, Type type, bool signed_, int bytes, bool isAtomic) { - auto* ret = allocator.alloc(); - ret->type = type; - ret->bytes = bytes; - ret->signed_ = signed_; - ret->offset = 0; - ret->align = bytes; - ret->isAtomic = isAtomic; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 2, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - i = parseMemAttributes(i, s, ret->offset, ret->align, isMemory64(memory)); - ret->ptr = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeStore(Element& s, - Type type, - int bytes, - bool isAtomic) { - auto ret = allocator.alloc(); - ret->bytes = bytes; - ret->offset = 0; - ret->align = bytes; - ret->isAtomic = isAtomic; - ret->valueType = type; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 3, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - i = parseMemAttributes(i, s, ret->offset, ret->align, isMemory64(memory)); - ret->ptr = parseExpression(s[i]); - ret->value = parseExpression(s[i + 1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s, - AtomicRMWOp op, - Type type, - uint8_t bytes) { - auto ret = allocator.alloc(); - ret->type = type; - ret->op = op; - ret->bytes = bytes; - ret->offset = 0; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 3, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - Address align = bytes; - i = parseMemAttributes(i, s, ret->offset, align, isMemory64(memory)); - if (align != ret->bytes) { - throw SParseException("Align of Atomic RMW must match size", s); - } - ret->ptr = parseExpression(s[i]); - ret->value = parseExpression(s[i + 1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeAtomicCmpxchg(Element& s, - Type type, - uint8_t bytes) { - auto ret = allocator.alloc(); - ret->type = type; - ret->bytes = bytes; - ret->offset = 0; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 4, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - Address align = ret->bytes; - i = parseMemAttributes(i, s, ret->offset, align, isMemory64(memory)); - if (align != ret->bytes) { - throw SParseException("Align of Atomic Cmpxchg must match size", s); - } - ret->ptr = parseExpression(s[i]); - ret->expected = parseExpression(s[i + 1]); - ret->replacement = parseExpression(s[i + 2]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeAtomicWait(Element& s, Type type) { - auto ret = allocator.alloc(); - ret->type = Type::i32; - ret->offset = 0; - ret->expectedType = type; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 4, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - Address expectedAlign = type == Type::i64 ? 8 : 4; - Address align = expectedAlign; - i = parseMemAttributes(i, s, ret->offset, align, isMemory64(memory)); - if (align != expectedAlign) { - throw SParseException("Align of memory.atomic.wait must match size", s); - } - ret->ptr = parseExpression(s[i]); - ret->expected = parseExpression(s[i + 1]); - ret->timeout = parseExpression(s[i + 2]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeAtomicNotify(Element& s) { - auto ret = allocator.alloc(); - ret->type = Type::i32; - ret->offset = 0; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 3, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - Address align = 4; - i = parseMemAttributes(i, s, ret->offset, align, isMemory64(memory)); - if (align != 4) { - throw SParseException("Align of memory.atomic.notify must be 4", s); - } - ret->ptr = parseExpression(s[i]); - ret->notifyCount = parseExpression(s[i + 1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeAtomicFence(Element& s) { - return allocator.alloc(); -} - -static uint8_t parseLaneIndex(const Element* s, size_t lanes) { - const char* str = s->str().str.data(); - char* end; - auto n = static_cast(strtoll(str, &end, 10)); - if (end == str || *end != '\0') { - throw SParseException("Expected lane index", *s); - } - if (n > lanes) { - throw SParseException( - "lane index must be less than " + std::to_string(lanes), *s); - } - return uint8_t(n); -} - -Expression* SExpressionWasmBuilder::makeSIMDExtract(Element& s, - SIMDExtractOp op, - size_t lanes) { - auto ret = allocator.alloc(); - ret->op = op; - ret->index = parseLaneIndex(s[1], lanes); - ret->vec = parseExpression(s[2]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSIMDReplace(Element& s, - SIMDReplaceOp op, - size_t lanes) { - auto ret = allocator.alloc(); - ret->op = op; - ret->index = parseLaneIndex(s[1], lanes); - ret->vec = parseExpression(s[2]); - ret->value = parseExpression(s[3]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSIMDShuffle(Element& s) { - auto ret = allocator.alloc(); - for (size_t i = 0; i < 16; ++i) { - ret->mask[i] = parseLaneIndex(s[i + 1], 32); - } - ret->left = parseExpression(s[17]); - ret->right = parseExpression(s[18]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSIMDTernary(Element& s, - SIMDTernaryOp op) { - auto ret = allocator.alloc(); - ret->op = op; - ret->a = parseExpression(s[1]); - ret->b = parseExpression(s[2]); - ret->c = parseExpression(s[3]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSIMDShift(Element& s, SIMDShiftOp op) { - auto ret = allocator.alloc(); - ret->op = op; - ret->vec = parseExpression(s[1]); - ret->shift = parseExpression(s[2]); - ret->finalize(); - return ret; -} - -Expression* -SExpressionWasmBuilder::makeSIMDLoad(Element& s, SIMDLoadOp op, int bytes) { - auto ret = allocator.alloc(); - ret->op = op; - ret->offset = 0; - ret->align = bytes; - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 2, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - i = parseMemAttributes(i, s, ret->offset, ret->align, isMemory64(memory)); - ret->ptr = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSIMDLoadStoreLane( - Element& s, SIMDLoadStoreLaneOp op, int bytes) { - auto* ret = allocator.alloc(); - ret->op = op; - ret->offset = 0; - ret->align = bytes; - size_t lanes; - switch (op) { - case Load8LaneVec128: - case Store8LaneVec128: - lanes = 16; - break; - case Load16LaneVec128: - case Store16LaneVec128: - lanes = 8; - break; - case Load32LaneVec128: - case Store32LaneVec128: - lanes = 4; - break; - case Load64LaneVec128: - case Store64LaneVec128: - lanes = 2; - break; - default: - WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op"); - } - Index i = 1; - Name memory; - // Check to make sure there are more than the default args & this str isn't - // the mem attributes - if (hasMemoryIdx(s, 4, i)) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - i = parseMemAttributes(i, s, ret->offset, ret->align, isMemory64(memory)); - ret->index = parseLaneIndex(s[i++], lanes); - ret->ptr = parseExpression(s[i++]); - ret->vec = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeMemoryInit(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name memory; - if (s.size() > 5) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - ret->segment = getDataSegmentName(*s[i++]); - ret->dest = parseExpression(s[i++]); - ret->offset = parseExpression(s[i++]); - ret->size = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeDataDrop(Element& s) { - auto ret = allocator.alloc(); - ret->segment = getDataSegmentName(*s[1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeMemoryCopy(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name destMemory; - Name sourceMemory; - if (s.size() > 4) { - destMemory = getMemoryName(*s[i++]); - sourceMemory = getMemoryName(*s[i++]); - } else { - destMemory = getMemoryNameAtIdx(0); - sourceMemory = getMemoryNameAtIdx(0); - } - ret->destMemory = destMemory; - ret->sourceMemory = sourceMemory; - ret->dest = parseExpression(s[i++]); - ret->source = parseExpression(s[i++]); - ret->size = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeMemoryFill(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name memory; - if (s.size() > 4) { - memory = getMemoryName(*s[i++]); - } else { - memory = getMemoryNameAtIdx(0); - } - ret->memory = memory; - ret->dest = parseExpression(s[i++]); - ret->value = parseExpression(s[i++]); - ret->size = parseExpression(s[i]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makePop(Element& s) { - auto ret = allocator.alloc(); - if (s.size() != 2) { - throw SParseException("expected 'pop '", s); - } - ret->type = elementToType(*s[1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeIf(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name sName; - if (s[i]->dollared()) { - // the if is labeled - sName = s[i++]->str(); - } else { - sName = "if"; - } - auto label = nameMapper.pushLabelName(sName); - // if signature - Type type = parseBlockType(s, i); - ret->condition = parseExpression(s[i++]); - if (!elementStartsWith(*s[i], "then")) { - throw SParseException("expected 'then'", *s[i]); - } - ret->ifTrue = parseExpression(*s[i++]); - if (i < s.size()) { - if (!elementStartsWith(*s[i], "else")) { - throw SParseException("expected 'else'", *s[i]); - } - ret->ifFalse = parseExpression(*s[i++]); - } - ret->finalize(type); - nameMapper.popLabelName(label); - // create a break target if we must - if (BranchUtils::BranchSeeker::has(ret, label)) { - auto* block = allocator.alloc(); - block->name = label; - block->list.push_back(ret); - block->finalize(type); - return block; - } - return ret; -} - -Expression* -SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, Type type) { - Index stopAt = -1; - if (s.size() == i) { - return allocator.alloc(); - } - if (s.size() == i + 1) { - return parseExpression(s[i]); - } - auto ret = allocator.alloc(); - for (; i < s.size() && i < stopAt; i++) { - ret->list.push_back(parseExpression(s[i])); - } - ret->finalize(type); - // Note that we do not name these implicit/synthetic blocks. They - // are the effects of syntactic sugar, and nothing can branch to - // them anyhow. - return ret; -} - -Type SExpressionWasmBuilder::parseBlockType(Element& s, Index& i) { - if (s.size() == i) { - return Type::none; - } - - // TODO(sbc): Remove support for old result syntax (bare streing) once the - // spec tests are updated. - if (s[i]->isStr()) { - return stringToType(s[i++]->str()); - } - - Element* results = s[i]; - IString id = (*results)[0]->str(); - std::optional usedType; - if (id == TYPE) { - auto type = parseHeapType(*(*results)[1]); - if (!type.isSignature()) { - throw SParseException("unexpected non-function type", s); - } - usedType = type.getSignature(); - if (usedType->params != Type::none) { - throw SParseException("block input values are not yet supported", s); - } - i++; - results = s[i]; - id = (*results)[0]->str(); - } - - if (id == RESULT) { - i++; - auto type = Type(parseResults(*results)); - if (usedType && usedType->results != type) { - throw SParseException("results do not match type", s); - } - return type; - } - - if (usedType && usedType->results != Type::none) { - throw SParseException("results do not match type", s); - } - return Type::none; -} - -Expression* SExpressionWasmBuilder::makeLoop(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name sName; - if (s.size() > i && s[i]->dollared()) { - sName = s[i++]->str(); - } else { - sName = "loop-in"; - } - ret->name = nameMapper.pushLabelName(sName); - ret->type = parseBlockType(s, i); - ret->body = makeMaybeBlock(s, i, ret->type); - nameMapper.popLabelName(ret->name); - ret->finalize(ret->type); - return ret; -} - -Expression* SExpressionWasmBuilder::makeCall(Element& s, bool isReturn) { - auto target = getFunctionName(*s[1]); - auto ret = allocator.alloc(); - ret->target = target; - ret->type = getFunctionType(ret->target, s).getSignature().results; - parseCallOperands(s, 2, s.size(), ret); - ret->isReturn = isReturn; - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s, - bool isReturn) { - if (wasm.tables.empty()) { - throw SParseException("no tables", s); - } - Index i = 1; - auto ret = allocator.alloc(); - if (s[i]->isStr()) { - ret->table = s[i++]->str(); - } else { - ret->table = wasm.tables.front()->name; - } - HeapType callType; - i = parseTypeUse(s, i, callType); - ret->heapType = callType; - parseCallOperands(s, i, s.size() - 1, ret); - ret->target = parseExpression(s[s.size() - 1]); - ret->isReturn = isReturn; - ret->finalize(); - return ret; -} - -Name SExpressionWasmBuilder::getLabel(Element& s, LabelType labelType) { - if (s.dollared()) { - return nameMapper.sourceToUnique(s.str()); - } else { - // offset, break to nth outside label - uint64_t offset; - try { - offset = std::stoll(s.toString(), nullptr, 0); - } catch (std::invalid_argument&) { - throw SParseException("invalid break offset", s); - } catch (std::out_of_range&) { - throw SParseException("out of range break offset", s); - } - if (offset > nameMapper.labelStack.size()) { - throw SParseException("invalid label", s); - } - if (offset == nameMapper.labelStack.size()) { - if (labelType == LabelType::Break) { - // a break to the function's scope. this means we need an automatic - // block, with a name - brokeToAutoBlock = true; - return FAKE_RETURN; - } - // This is a delegate that delegates to the caller - return DELEGATE_CALLER_TARGET; - } - return nameMapper.labelStack[nameMapper.labelStack.size() - 1 - offset]; - } -} - -Expression* SExpressionWasmBuilder::makeBreak(Element& s, bool isConditional) { - auto ret = allocator.alloc(); - size_t i = 1; - ret->name = getLabel(*s[i]); - i++; - if (i == s.size()) { - return ret; - } - if (isConditional) { - if (i + 1 < s.size()) { - ret->value = parseExpression(s[i]); - i++; - } - ret->condition = parseExpression(s[i]); - } else { - ret->value = parseExpression(s[i]); - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeBreakTable(Element& s) { - auto ret = allocator.alloc(); - size_t i = 1; - while (!s[i]->isList()) { - ret->targets.push_back(getLabel(*s[i++])); - } - if (ret->targets.size() == 0) { - throw SParseException("switch with no targets", s); - } - ret->default_ = ret->targets.back(); - ret->targets.pop_back(); - ret->condition = parseExpression(s[i++]); - if (i < s.size()) { - ret->value = ret->condition; - ret->condition = parseExpression(s[i++]); - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeReturn(Element& s) { - auto ret = allocator.alloc(); - if (s.size() >= 2) { - ret->value = parseExpression(s[1]); - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefNull(Element& s) { - if (s.size() != 2) { - throw SParseException("invalid heap type reference", s); - } - auto ret = allocator.alloc(); - // The heap type may be just "func", that is, the whole thing is just - // (ref.null func), or it may be the name of a defined type, such as - // (ref.null $struct.FOO) - if (s[1]->dollared()) { - ret->finalize(parseHeapType(*s[1]).getBottom()); - } else { - ret->finalize(stringToHeapType(s[1]->str()).getBottom()); - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefIsNull(Element& s) { - auto ret = allocator.alloc(); - ret->value = parseExpression(s[1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefFunc(Element& s) { - auto func = getFunctionName(*s[1]); - auto ret = allocator.alloc(); - ret->func = func; - // To support typed function refs, we give the reference not just a general - // funcref, but a specific subtype with the actual signature. - ret->finalize(Type(getFunctionType(func, s), NonNullable)); - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefEq(Element& s) { - auto ret = allocator.alloc(); - ret->left = parseExpression(s[1]); - ret->right = parseExpression(s[2]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeTableGet(Element& s) { - auto tableName = s[1]->str(); - auto* index = parseExpression(s[2]); - auto* table = wasm.getTableOrNull(tableName); - if (!table) { - throw SParseException("invalid table name in table.get", s); - } - return Builder(wasm).makeTableGet(tableName, index, table->type); -} - -Expression* SExpressionWasmBuilder::makeTableSet(Element& s) { - auto tableName = s[1]->str(); - auto* table = wasm.getTableOrNull(tableName); - if (!table) { - throw SParseException("invalid table name in table.set", s); - } - auto* index = parseExpression(s[2]); - auto* value = parseExpression(s[3]); - return Builder(wasm).makeTableSet(tableName, index, value); -} - -Expression* SExpressionWasmBuilder::makeTableSize(Element& s) { - auto tableName = s[1]->str(); - auto* table = wasm.getTableOrNull(tableName); - if (!table) { - throw SParseException("invalid table name in table.size", s); - } - return Builder(wasm).makeTableSize(tableName); -} - -Expression* SExpressionWasmBuilder::makeTableGrow(Element& s) { - auto tableName = s[1]->str(); - auto* table = wasm.getTableOrNull(tableName); - if (!table) { - throw SParseException("invalid table name in table.grow", s); - } - auto* value = parseExpression(s[2]); - if (!value->type.isRef()) { - throw SParseException("only reference types are valid for tables", s); - } - auto* delta = parseExpression(s[3]); - return Builder(wasm).makeTableGrow(tableName, value, delta); -} - -Expression* SExpressionWasmBuilder::makeTableFill(Element& s) { - auto tableName = s[1]->str(); - auto* table = wasm.getTableOrNull(tableName); - if (!table) { - throw SParseException("invalid table name in table.fill", s); - } - auto* dest = parseExpression(s[2]); - auto* value = parseExpression(s[3]); - auto* size = parseExpression(s[4]); - return Builder(wasm).makeTableFill(tableName, dest, value, size); -} - -Expression* SExpressionWasmBuilder::makeTableCopy(Element& s) { - auto destTableName = s[1]->str(); - auto* destTable = wasm.getTableOrNull(destTableName); - if (!destTable) { - throw SParseException("invalid dest table name in table.copy", s); - } - auto sourceTableName = s[2]->str(); - auto* sourceTable = wasm.getTableOrNull(sourceTableName); - if (!sourceTable) { - throw SParseException("invalid source table name in table.copy", s); - } - auto* dest = parseExpression(s[3]); - auto* source = parseExpression(s[4]); - auto* size = parseExpression(s[5]); - return Builder(wasm).makeTableCopy( - dest, source, size, destTableName, sourceTableName); -} - -// try can be either in the form of try-catch or try-delegate. -// try-catch is written in the folded wast format as -// (try -// (do -// ... -// ) -// (catch $e -// ... -// ) -// ... -// (catch_all -// ... -// ) -// ) -// Any number of catch blocks can exist, including none. Zero or one catch_all -// block can exist, and if it does, it should be at the end. There should be at -// least one catch or catch_all body per try. -// -// try-delegate is written in the folded format as -// (try -// (do -// ... -// ) -// (delegate $label) -// ) -Expression* SExpressionWasmBuilder::makeTry(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name sName; - if (s[i]->dollared()) { - // the try is labeled - sName = s[i++]->str(); - } else { - sName = "try"; - } - ret->name = nameMapper.pushLabelName(sName); - Type type = parseBlockType(s, i); // signature - - if (!elementStartsWith(*s[i], "do")) { - throw SParseException("try body should start with 'do'", s, *s[i]); - } - ret->body = makeMaybeBlock(*s[i++], 1, type); - - while (i < s.size() && elementStartsWith(*s[i], "catch")) { - Element& inner = *s[i++]; - if (inner.size() < 2) { - throw SParseException("invalid catch block", s, inner); - } - Name tag = getTagName(*inner[1]); - if (!wasm.getTagOrNull(tag)) { - throw SParseException("bad tag name", s, inner); - } - ret->catchTags.push_back(tag); - ret->catchBodies.push_back(makeMaybeBlock(inner, 2, type)); - } - - if (i < s.size() && elementStartsWith(*s[i], "catch_all")) { - ret->catchBodies.push_back(makeMaybeBlock(*s[i++], 1, type)); - } - - // 'delegate' cannot target its own try. So we pop the name here. - nameMapper.popLabelName(ret->name); - - if (i < s.size() && elementStartsWith(*s[i], "delegate")) { - Element& inner = *s[i++]; - if (inner.size() != 2) { - throw SParseException("invalid delegate", s, inner); - } - ret->delegateTarget = getLabel(*inner[1], LabelType::Exception); - } - - if (i != s.size()) { - throw SParseException( - "there should be at most one catch_all block at the end", s); - } - - ret->finalize(type); - - // create a break target if we must - if (BranchUtils::BranchSeeker::has(ret, ret->name)) { - auto* block = allocator.alloc(); - // We create a different name for the wrapping block, because try's name can - // be used by internal delegates - block->name = nameMapper.pushLabelName(sName); - // For simplicity, try's name can only be targeted by delegates and - // rethrows. Make the branches target the new wrapping block instead. - BranchUtils::replaceBranchTargets(ret, ret->name, block->name); - block->list.push_back(ret); - nameMapper.popLabelName(block->name); - block->finalize(type); - return block; - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeTryTable(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - Name sName; - if (s.size() > i && s[i]->dollared()) { - // the try_table is labeled - sName = s[i++]->str(); - } else { - sName = "try_table"; - } - auto label = nameMapper.pushLabelName(sName); - Type type = parseBlockType(s, i); // signature - - while (i < s.size()) { - Element& inner = *s[i]; - - if (elementStartsWith(inner, "catch") || - elementStartsWith(inner, "catch_ref")) { - bool isRef = elementStartsWith(inner, "catch_ref"); - if (inner.size() < 3) { - throw SParseException("invalid catch/catch_ref block", s, inner); - } - Name tag = getTagName(*inner[1]); - if (!wasm.getTagOrNull(tag)) { - throw SParseException("bad tag name", s, inner); - } - ret->catchTags.push_back(tag); - ret->catchDests.push_back(getLabel(*inner[2])); - ret->catchRefs.push_back(isRef); - } else if (elementStartsWith(inner, "catch_all") || - elementStartsWith(inner, "catch_all_ref")) { - bool isRef = elementStartsWith(inner, "catch_all_ref"); - if (inner.size() < 2) { - throw SParseException( - "invalid catch_all/catch_all_ref block", s, inner); - } - ret->catchTags.push_back(Name()); - ret->catchDests.push_back(getLabel(*inner[1])); - ret->catchRefs.push_back(isRef); - } else { - break; - } - i++; - } - - ret->body = makeMaybeBlock(s, i, type); - ret->finalize(type, &wasm); - nameMapper.popLabelName(label); - // create a break target if we must - if (BranchUtils::BranchSeeker::has(ret, label)) { - auto* block = allocator.alloc(); - block->name = label; - block->list.push_back(ret); - block->finalize(type); - return block; - } - return ret; -} - -Expression* SExpressionWasmBuilder::makeThrow(Element& s) { - auto ret = allocator.alloc(); - Index i = 1; - - ret->tag = getTagName(*s[i++]); - if (!wasm.getTagOrNull(ret->tag)) { - throw SParseException("bad tag name", s, *s[i]); - } - for (; i < s.size(); i++) { - ret->operands.push_back(parseExpression(s[i])); - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeRethrow(Element& s) { - auto ret = allocator.alloc(); - ret->target = getLabel(*s[1], LabelType::Exception); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeThrowRef(Element& s) { - auto ret = allocator.alloc(); - ret->exnref = parseExpression(s[1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeTupleMake(Element& s) { - auto ret = allocator.alloc(); - size_t arity = std::stoll(s[1]->toString()); - if (arity != s.size() - 2) { - throw SParseException("unexpected number of elements", s, *s[1]); - } - parseCallOperands(s, 2, s.size(), ret); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) { - auto ret = allocator.alloc(); - size_t arity = std::stoll(s[1]->toString()); - ret->index = parseIndex(*s[2]); - ret->tuple = parseExpression(s[3]); - if (ret->tuple->type != Type::unreachable) { - if (arity != ret->tuple->type.size()) { - throw SParseException("Unexpected tuple.extract arity", s, *s[1]); - } - if (ret->index >= ret->tuple->type.size()) { - throw SParseException("Bad index on tuple.extract", s, *s[2]); - } - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeTupleDrop(Element& s) { - size_t arity = std::stoll(s[1]->toString()); - auto ret = allocator.alloc(); - ret->value = parseExpression(s[2]); - if (ret->value->type != Type::unreachable && - ret->value->type.size() != arity) { - throw SParseException("unexpected tuple.drop arity", s, *s[1]); - } - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) { - HeapType sigType = parseHeapType(*s[1]); - std::vector operands; - parseOperands(s, 2, s.size() - 1, operands); - auto* target = parseExpression(s[s.size() - 1]); - - if (!sigType.isSignature()) { - throw SParseException( - std::string(isReturn ? "return_call_ref" : "call_ref") + - " type annotation should be a signature", - s); - } - if (!Type::isSubType(target->type, Type(sigType, Nullable))) { - throw SParseException( - std::string(isReturn ? "return_call_ref" : "call_ref") + - " target should match expected type", - s); - } - return Builder(wasm).makeCallRef( - target, operands, sigType.getSignature().results, isReturn); -} - -Expression* SExpressionWasmBuilder::makeContBind(Element& s) { - auto ret = allocator.alloc(); - - ret->contTypeBefore = parseHeapType(*s[1]); - if (!ret->contTypeBefore.isContinuation()) { - throw ParseException("expected continuation type", s[1]->line, s[1]->col); - } - ret->contTypeAfter = parseHeapType(*s[2]); - if (!ret->contTypeAfter.isContinuation()) { - throw ParseException("expected continuation type", s[2]->line, s[2]->col); - } - - Index i = 3; - while (i < s.size() - 1) { - ret->operands.push_back(parseExpression(s[i++])); - } - - ret->cont = parseExpression(s[i]); - - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeContNew(Element& s) { - auto ret = allocator.alloc(); - - ret->contType = parseHeapType(*s[1]); - if (!ret->contType.isContinuation()) { - throw ParseException("expected continuation type", s[1]->line, s[1]->col); - } - - ret->func = parseExpression(s[2]); - - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeResume(Element& s) { - auto ret = allocator.alloc(); - - ret->contType = parseHeapType(*s[1]); - if (!ret->contType.isContinuation()) { - throw ParseException("expected continuation type", s[1]->line, s[1]->col); - } - - Index i = 2; - while (i < s.size() && elementStartsWith(*s[i], "tag")) { - Element& inner = *s[i++]; - if (inner.size() < 3) { - throw ParseException("invalid tag block", inner.line, inner.col); - } - Name tag = getTagName(*inner[1]); - if (!wasm.getTagOrNull(tag)) { - throw ParseException("bad tag name", inner[1]->line, inner[1]->col); - } - ret->handlerTags.push_back(tag); - ret->handlerBlocks.push_back(getLabel(*inner[2])); - } - - while (i < s.size() - 1) { - ret->operands.push_back(parseExpression(s[i++])); - } - - ret->cont = parseExpression(s[i]); - - ret->finalize(&wasm); - return ret; -} - -Expression* SExpressionWasmBuilder::makeSuspend(Element& s) { - auto ret = allocator.alloc(); - - ret->tag = getTagName(*s[1]); - - Index i = 2; - while (i < s.size()) { - ret->operands.push_back(parseExpression(s[i++])); - } - - ret->finalize(&wasm); - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefI31(Element& s) { - auto ret = allocator.alloc(); - ret->value = parseExpression(s[1]); - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeI31Get(Element& s, bool signed_) { - auto ret = allocator.alloc(); - ret->i31 = parseExpression(s[1]); - ret->signed_ = signed_; - ret->finalize(); - return ret; -} - -Expression* SExpressionWasmBuilder::makeRefTest(Element& s) { - Type castType = elementToType(*s[1]); - auto* ref = parseExpression(*s[2]); - return Builder(wasm).makeRefTest(ref, castType); -} - -Expression* SExpressionWasmBuilder::makeRefCast(Element& s) { - Type castType = elementToType(*s[1]); - auto* ref = parseExpression(*s[2]); - return Builder(wasm).makeRefCast(ref, castType); -} - -Expression* SExpressionWasmBuilder::makeBrOnNull(Element& s, bool onFail) { - int i = 1; - auto name = getLabel(*s[i++]); - auto* ref = parseExpression(*s[i]); - auto op = onFail ? BrOnNonNull : BrOnNull; - return Builder(wasm).makeBrOn(op, name, ref); -} - -Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s, bool onFail) { - int i = 1; - auto name = getLabel(*s[i++]); - auto inputType = elementToType(*s[i++]); - auto castType = elementToType(*s[i++]); - if (!Type::isSubType(castType, inputType)) { - throw SParseException( - "br_on_cast* cast type must be a subtype of its input type", s); - } - auto* ref = parseExpression(*s[i]); - if (!Type::isSubType(ref->type, inputType)) { - throw SParseException("br_on_cast* ref type does not match expected type", - s); - } - auto op = onFail ? BrOnCastFail : BrOnCast; - return Builder(wasm).makeBrOn(op, name, ref, castType); -} - -Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) { - auto heapType = parseHeapType(*s[1]); - auto numOperands = s.size() - 2; - if (default_ && numOperands > 0) { - throw SParseException("arguments provided for struct.new", s); - } - std::vector operands; - operands.resize(numOperands); - for (Index i = 0; i < numOperands; i++) { - operands[i] = parseExpression(*s[i + 2]); - } - return Builder(wasm).makeStructNew(heapType, operands); -} - -Index SExpressionWasmBuilder::getStructIndex(Element& type, Element& field) { - if (field.dollared()) { - auto name = field.str(); - auto index = typeIndices[type.toString()]; - auto struct_ = types[index].getStruct(); - auto& fields = struct_.fields; - const auto& names = fieldNames[index]; - for (Index i = 0; i < fields.size(); i++) { - auto it = names.find(i); - if (it != names.end() && it->second == name) { - return i; - } - } - throw SParseException("bad struct field name", field); - } - // this is a numeric index - return parseIndex(field); -} - -Expression* SExpressionWasmBuilder::makeStructGet(Element& s, bool signed_) { - auto heapType = parseHeapType(*s[1]); - if (!heapType.isStruct()) { - throw SParseException("bad struct heap type", s); - } - auto index = getStructIndex(*s[1], *s[2]); - auto type = heapType.getStruct().fields[index].type; - auto ref = parseExpression(*s[3]); - validateHeapTypeUsingChild(ref, heapType, s); - return Builder(wasm).makeStructGet(index, ref, type, signed_); -} - -Expression* SExpressionWasmBuilder::makeStructSet(Element& s) { - auto heapType = parseHeapType(*s[1]); - if (!heapType.isStruct()) { - throw SParseException("bad struct heap type", s); - } - auto index = getStructIndex(*s[1], *s[2]); - auto ref = parseExpression(*s[3]); - validateHeapTypeUsingChild(ref, heapType, s); - auto value = parseExpression(*s[4]); - return Builder(wasm).makeStructSet(index, ref, value); -} - -Expression* SExpressionWasmBuilder::makeArrayNew(Element& s, bool default_) { - auto heapType = parseHeapType(*s[1]); - Expression* init = nullptr; - size_t i = 2; - if (!default_) { - init = parseExpression(*s[i++]); - } - auto* size = parseExpression(*s[i++]); - return Builder(wasm).makeArrayNew(heapType, size, init); -} - -Expression* SExpressionWasmBuilder::makeArrayNewData(Element& s) { - auto heapType = parseHeapType(*s[1]); - Name seg = getDataSegmentName(*s[2]); - Expression* offset = parseExpression(*s[3]); - Expression* size = parseExpression(*s[4]); - return Builder(wasm).makeArrayNewData(heapType, seg, offset, size); -} - -Expression* SExpressionWasmBuilder::makeArrayNewElem(Element& s) { - auto heapType = parseHeapType(*s[1]); - Name seg = getElemSegmentName(*s[2]); - Expression* offset = parseExpression(*s[3]); - Expression* size = parseExpression(*s[4]); - return Builder(wasm).makeArrayNewElem(heapType, seg, offset, size); -} - -Expression* SExpressionWasmBuilder::makeArrayNewFixed(Element& s) { - auto heapType = parseHeapType(*s[1]); - if ((size_t)parseIndex(*s[2]) != s.size() - 3) { - throw SParseException("wrong number of elements in array", s); - } - std::vector values; - for (size_t i = 3; i < s.size(); ++i) { - values.push_back(parseExpression(*s[i])); - } - return Builder(wasm).makeArrayNewFixed(heapType, values); -} - -Expression* SExpressionWasmBuilder::makeArrayGet(Element& s, bool signed_) { - auto heapType = parseHeapType(*s[1]); - if (!heapType.isArray()) { - throw SParseException("bad array heap type", s); - } - auto ref = parseExpression(*s[2]); - auto type = heapType.getArray().element.type; - validateHeapTypeUsingChild(ref, heapType, s); - auto index = parseExpression(*s[3]); - return Builder(wasm).makeArrayGet(ref, index, type, signed_); -} - -Expression* SExpressionWasmBuilder::makeArraySet(Element& s) { - auto heapType = parseHeapType(*s[1]); - auto ref = parseExpression(*s[2]); - validateHeapTypeUsingChild(ref, heapType, s); - auto index = parseExpression(*s[3]); - auto value = parseExpression(*s[4]); - return Builder(wasm).makeArraySet(ref, index, value); -} - -Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) { - auto ref = parseExpression(*s[1]); - return Builder(wasm).makeArrayLen(ref); -} - -Expression* SExpressionWasmBuilder::makeArrayCopy(Element& s) { - auto destHeapType = parseHeapType(*s[1]); - auto srcHeapType = parseHeapType(*s[2]); - auto destRef = parseExpression(*s[3]); - validateHeapTypeUsingChild(destRef, destHeapType, s); - auto destIndex = parseExpression(*s[4]); - auto srcRef = parseExpression(*s[5]); - validateHeapTypeUsingChild(srcRef, srcHeapType, s); - auto srcIndex = parseExpression(*s[6]); - auto length = parseExpression(*s[7]); - return Builder(wasm).makeArrayCopy( - destRef, destIndex, srcRef, srcIndex, length); -} - -Expression* SExpressionWasmBuilder::makeArrayFill(Element& s) { - auto heapType = parseHeapType(*s[1]); - auto ref = parseExpression(*s[2]); - validateHeapTypeUsingChild(ref, heapType, s); - auto index = parseExpression(*s[3]); - auto value = parseExpression(*s[4]); - auto size = parseExpression(*s[5]); - return Builder(wasm).makeArrayFill(ref, index, value, size); -} - -Expression* SExpressionWasmBuilder::makeArrayInitData(Element& s) { - auto heapType = parseHeapType(*s[1]); - auto seg = getDataSegmentName(*s[2]); - auto ref = parseExpression(*s[3]); - validateHeapTypeUsingChild(ref, heapType, s); - auto index = parseExpression(*s[4]); - auto offset = parseExpression(*s[5]); - auto size = parseExpression(*s[6]); - return Builder(wasm).makeArrayInitData(seg, ref, index, offset, size); -} - -Expression* SExpressionWasmBuilder::makeArrayInitElem(Element& s) { - auto heapType = parseHeapType(*s[1]); - auto seg = getElemSegmentName(*s[2]); - auto ref = parseExpression(*s[3]); - validateHeapTypeUsingChild(ref, heapType, s); - auto index = parseExpression(*s[4]); - auto offset = parseExpression(*s[5]); - auto size = parseExpression(*s[6]); - return Builder(wasm).makeArrayInitElem(seg, ref, index, offset, size); -} - -Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { - auto* value = parseExpression(s[1]); - if (!value->type.isRef() && value->type != Type::unreachable) { - throw SParseException("ref.as child must be a ref", s); - } - return Builder(wasm).makeRefAs(op, value); -} - -Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { - if (op == StringNewLossyUTF8Array || op == StringNewWTF16Array) { - auto* start = parseExpression(s[2]); - auto* end = parseExpression(s[3]); - return Builder(wasm).makeStringNew(op, parseExpression(s[1]), start, end); - } else if (op == StringNewFromCodePoint) { - return Builder(wasm).makeStringNew(op, parseExpression(s[1])); - } else { - throw SParseException("bad string.new op", s); - } -} - -Expression* SExpressionWasmBuilder::makeStringConst(Element& s) { - std::vector data; - stringToBinary(*s[1], s[1]->str().str, data); - Name str = std::string_view(data.data(), data.size()); - // Re-encode from WTF-8 to WTF-16. - std::stringstream wtf16; - if (!String::convertWTF8ToWTF16(wtf16, str.str)) { - throw SParseException("invalid string constant", s); - } - // TODO: Use wtf16.view() once we have C++20. - return Builder(wasm).makeStringConst(wtf16.str()); -} - -Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s, - StringMeasureOp op) { - return Builder(wasm).makeStringMeasure(op, parseExpression(s[1])); -} - -Expression* SExpressionWasmBuilder::makeStringEncode(Element& s, - StringEncodeOp op) { - - return Builder(wasm).makeStringEncode( - op, parseExpression(s[1]), parseExpression(s[2]), parseExpression(s[3])); -} - -Expression* SExpressionWasmBuilder::makeStringConcat(Element& s) { - return Builder(wasm).makeStringConcat(parseExpression(s[1]), - parseExpression(s[2])); -} - -Expression* SExpressionWasmBuilder::makeStringEq(Element& s, StringEqOp op) { - return Builder(wasm).makeStringEq( - op, parseExpression(s[1]), parseExpression(s[2])); -} - -Expression* SExpressionWasmBuilder::makeStringWTF16Get(Element& s) { - return Builder(wasm).makeStringWTF16Get(parseExpression(s[1]), - parseExpression(s[2])); -} - -Expression* SExpressionWasmBuilder::makeStringSliceWTF(Element& s) { - return Builder(wasm).makeStringSliceWTF( - parseExpression(s[1]), parseExpression(s[2]), parseExpression(s[3])); -} - -// converts an s-expression string representing binary data into an output -// sequence of raw bytes this appends to data, which may already contain -// content. -void SExpressionWasmBuilder::stringToBinary(Element& s, - std::string_view str, - std::vector& data) { - auto originalSize = data.size(); - data.resize(originalSize + str.size()); - char* write = data.data() + originalSize; - const char* end = str.data() + str.size(); - for (const char* input = str.data(); input < end;) { - if (input[0] == '\\') { - if (input + 1 >= end) { - throw SParseException("Unterminated escape sequence", s); - } - if (input[1] == 't') { - *write++ = '\t'; - input += 2; - continue; - } else if (input[1] == 'n') { - *write++ = '\n'; - input += 2; - continue; - } else if (input[1] == 'r') { - *write++ = '\r'; - input += 2; - continue; - } else if (input[1] == '"') { - *write++ = '"'; - input += 2; - continue; - } else if (input[1] == '\'') { - *write++ = '\''; - input += 2; - continue; - } else if (input[1] == '\\') { - *write++ = '\\'; - input += 2; - continue; - } else { - if (input + 2 >= end) { - throw SParseException("Unterminated escape sequence", s); - } - *write++ = (char)(unhex(input[1]) * 16 + unhex(input[2])); - input += 3; - continue; - } - } - *write++ = input[0]; - input++; - } - assert(write >= data.data()); - size_t actual = write - data.data(); - assert(actual <= data.size()); - data.resize(actual); -} - -Index SExpressionWasmBuilder::parseMemoryIndex( - Element& s, Index i, std::unique_ptr& memory) { - if (i < s.size() && s[i]->isStr()) { - if (s[i]->str() == "i64") { - i++; - memory->indexType = Type::i64; - } else if (s[i]->str() == "i32") { - i++; - memory->indexType = Type::i32; - } - } - return i; -} - -Index SExpressionWasmBuilder::parseMemoryLimits( - Element& s, Index i, std::unique_ptr& memory) { - i = parseMemoryIndex(s, i, memory); - if (i == s.size()) { - throw SParseException("missing memory limits", s); - } - auto initElem = s[i++]; - memory->initial = getAddress(initElem); - if (!memory->is64()) { - checkAddress(memory->initial, "excessive memory init", initElem); - } - if (i == s.size()) { - memory->max = Memory::kUnlimitedSize; - } else { - auto maxElem = s[i++]; - memory->max = getAddress(maxElem); - if (!memory->is64() && memory->max > Memory::kMaxSize32) { - throw SParseException("total memory must be <= 4GB", s, *maxElem); - } - } - return i; -} - -void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { - auto memory = std::make_unique(); - memory->shared = *s[s.size() - 1] == SHARED; - Index i = 1; - if (s[i]->dollared()) { - memory->setExplicitName(s[i++]->str()); - } else { - memory->name = Name::fromInt(memoryCounter++); - } - memoryNames.push_back(memory->name); - - i = parseMemoryIndex(s, i, memory); - Name importModule, importBase; - if (s[i]->isList()) { - auto& inner = *s[i]; - if (elementStartsWith(inner, EXPORT)) { - auto ex = std::make_unique(); - ex->name = inner[1]->str(); - ex->value = memory->name; - ex->kind = ExternalKind::Memory; - if (wasm.getExportOrNull(ex->name)) { - throw SParseException("duplicate export", inner); - } - wasm.addExport(ex.release()); - i++; - } else if (elementStartsWith(inner, IMPORT)) { - memory->module = inner[1]->str(); - memory->base = inner[2]->str(); - i++; - } else { - if (!(inner.size() > 0 ? inner[0]->str() != IMPORT : true)) { - throw SParseException("bad import ending", inner); - } - // (memory (data ..)) format - auto j = parseMemoryIndex(inner, 1, memory); - auto offset = allocator.alloc(); - if (memory->is64()) { - offset->set(Literal(int64_t(0))); - } else { - offset->set(Literal(int32_t(0))); - } - auto segName = Name::fromInt(dataCounter++); - auto seg = Builder::makeDataSegment(segName, memory->name, false, offset); - dataSegmentNames.push_back(segName); - parseInnerData(inner, j, seg); - memory->initial = seg->data.size(); - wasm.addDataSegment(std::move(seg)); - wasm.addMemory(std::move(memory)); - return; - } - } - i = parseMemoryLimits(s, i, memory); - if (i + int(memory->shared) != s.size()) { - throw SParseException("expected end of memory", *s[i]); - } - wasm.addMemory(std::move(memory)); -} - -void SExpressionWasmBuilder::parseData(Element& s) { - Index i = 1; - Name name = Name::fromInt(dataCounter++); - bool hasExplicitName = false; - Name memory; - bool isPassive = true; - Expression* offset = nullptr; - - if (s[i]->isStr() && s[i]->dollared()) { - name = s[i++]->str(); - hasExplicitName = true; - } - dataSegmentNames.push_back(name); - - if (s[i]->isList()) { - // Optional (memory ) - if (elementStartsWith(s[i], MEMORY)) { - auto& inner = *s[i++]; - memory = getMemoryName(*inner[1]); - } else { - memory = getMemoryNameAtIdx(0); - } - // Offset expression (offset ()) | () - auto& inner = *s[i++]; - if (elementStartsWith(inner, OFFSET)) { - offset = parseExpression(inner[1]); - } else { - offset = parseExpression(inner); - } - isPassive = false; - } - - auto seg = Builder::makeDataSegment(name, memory, isPassive, offset); - seg->hasExplicitName = hasExplicitName; - parseInnerData(s, i, seg); - wasm.addDataSegment(std::move(seg)); -} - -void SExpressionWasmBuilder::parseInnerData(Element& s, - Index i, - std::unique_ptr& seg) { - std::vector data; - while (i < s.size()) { - std::string_view input = s[i++]->str().str; - stringToBinary(s, input, data); - } - seg->data.resize(data.size()); - std::copy_n(data.data(), data.size(), seg->data.begin()); -} - -void SExpressionWasmBuilder::parseExport(Element& s) { - std::unique_ptr ex = std::make_unique(); - std::vector nameBytes; - stringToBinary(*s[1], s[1]->str().str, nameBytes); - ex->name = std::string(nameBytes.data(), nameBytes.size()); - if (s[2]->isList()) { - auto& inner = *s[2]; - if (elementStartsWith(inner, FUNC)) { - ex->kind = ExternalKind::Function; - ex->value = getFunctionName(*inner[1]); - } else if (elementStartsWith(inner, MEMORY)) { - ex->kind = ExternalKind::Memory; - ex->value = inner[1]->str(); - } else if (elementStartsWith(inner, TABLE)) { - ex->kind = ExternalKind::Table; - ex->value = getTableName(*inner[1]); - } else if (elementStartsWith(inner, GLOBAL)) { - ex->kind = ExternalKind::Global; - ex->value = getGlobalName(*inner[1]); - } else if (inner[0]->str() == TAG) { - ex->kind = ExternalKind::Tag; - ex->value = getTagName(*inner[1]); - } else { - throw SParseException("invalid export", inner); - } - } else { - // function - ex->value = s[2]->str(); - ex->kind = ExternalKind::Function; - } - if (wasm.getExportOrNull(ex->name)) { - throw SParseException("duplicate export", s); - } - wasm.addExport(ex.release()); -} - -void SExpressionWasmBuilder::parseImport(Element& s) { - size_t i = 1; - // (import "env" "STACKTOP" (global $stackTop i32)) - bool newStyle = s.size() == 4 && s[3]->isList(); - auto kind = ExternalKind::Invalid; - if (newStyle) { - if (elementStartsWith(*s[3], FUNC)) { - kind = ExternalKind::Function; - } else if (elementStartsWith(*s[3], MEMORY)) { - kind = ExternalKind::Memory; - } else if (elementStartsWith(*s[3], TABLE)) { - kind = ExternalKind::Table; - } else if (elementStartsWith(*s[3], GLOBAL)) { - kind = ExternalKind::Global; - } else if ((*s[3])[0]->str() == TAG) { - kind = ExternalKind::Tag; - } else { - newStyle = false; // either (param..) or (result..) - } - } - Index newStyleInner = 1; - Name name; - if (s.size() > 3 && s[3]->isStr()) { - name = s[i++]->str(); - } else if (newStyle && newStyleInner < s[3]->size() && - (*s[3])[newStyleInner]->dollared()) { - name = (*s[3])[newStyleInner++]->str(); - } - bool hasExplicitName = name.is(); - if (!hasExplicitName) { - if (kind == ExternalKind::Function) { - name = Name("fimport$" + std::to_string(functionCounter++)); - functionNames.push_back(name); - } else if (kind == ExternalKind::Global) { - // Handled in `parseGlobal`. - } else if (kind == ExternalKind::Memory) { - name = Name("mimport$" + std::to_string(memoryCounter++)); - } else if (kind == ExternalKind::Table) { - name = Name("timport$" + std::to_string(tableCounter++)); - } else if (kind == ExternalKind::Tag) { - name = Name("eimport$" + std::to_string(tagCounter++)); - tagNames.push_back(name); - } else { - throw SParseException("invalid import", s); - } - } - if (!newStyle) { - kind = ExternalKind::Function; - } - std::vector moduleBytes; - stringToBinary(*s[i], s[i]->str().str, moduleBytes); - Name module = std::string(moduleBytes.data(), moduleBytes.size()); - i++; - - if (!s[i]->isStr()) { - throw SParseException("no name for import", s, *s[i]); - } - - std::vector baseBytes; - stringToBinary(*s[i], s[i]->str().str, baseBytes); - Name base = std::string(baseBytes.data(), baseBytes.size()); - i++; - - // parse internals - Element& inner = newStyle ? *s[3] : s; - Index j = newStyle ? newStyleInner : i; - if (kind == ExternalKind::Function) { - auto func = std::make_unique(); - - j = parseTypeUse(inner, j, func->type); - func->setName(name, hasExplicitName); - func->module = module; - func->base = base; - functionTypes[name] = func->type; - wasm.addFunction(func.release()); - } else if (kind == ExternalKind::Global) { - parseGlobal(inner, true); - j++; - auto& global = wasm.globals.back(); - global->module = module; - global->base = base; - } else if (kind == ExternalKind::Table) { - auto table = std::make_unique(); - table->setName(name, hasExplicitName); - table->module = module; - table->base = base; - tableNames.push_back(name); - - if (j < inner.size() - 1) { - auto initElem = inner[j++]; - table->initial = getAddress(initElem); - checkAddress(table->initial, "excessive table init size", initElem); - } - if (j < inner.size() - 1) { - auto maxElem = inner[j++]; - table->max = getAddress(maxElem); - checkAddress(table->max, "excessive table max size", maxElem); - } else { - table->max = Table::kUnlimitedSize; - } - - // ends with the table element type - table->type = elementToType(*inner[j++]); - if (!table->type.isRef()) { - throw SParseException("Only reference types are valid for tables", s); - } - - wasm.addTable(std::move(table)); - } else if (kind == ExternalKind::Memory) { - auto memory = std::make_unique(); - memory->setName(name, hasExplicitName); - memory->module = module; - memory->base = base; - memoryNames.push_back(name); - - j = parseMemoryLimits(inner, j, memory); - if (j != inner.size() && *inner[j] == SHARED) { - memory->shared = true; - j++; - } - - wasm.addMemory(std::move(memory)); - } else if (kind == ExternalKind::Tag) { - auto tag = std::make_unique(); - HeapType tagType; - j = parseTypeUse(inner, j, tagType); - tag->sig = tagType.getSignature(); - tag->setName(name, hasExplicitName); - tag->module = module; - tag->base = base; - wasm.addTag(tag.release()); - } - // If there are more elements, they are invalid - if (j < inner.size()) { - throw SParseException("invalid element", inner, *inner[j]); - } -} - -void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { - std::unique_ptr global = std::make_unique(); - size_t i = 1; - if (s[i]->dollared()) { - global->setExplicitName(s[i++]->str()); - } else if (preParseImport) { - global->name = Name("gimport$" + std::to_string(globalCounter)); - } else { - global->name = Name::fromInt(globalCounter); - } - globalCounter++; - globalNames.push_back(global->name); - bool mutable_ = false; - Type type = Type::none; - Name importModule, importBase; - while (i < s.size() && s[i]->isList()) { - auto& inner = *s[i++]; - if (elementStartsWith(inner, EXPORT)) { - auto ex = std::make_unique(); - ex->name = inner[1]->str(); - ex->value = global->name; - ex->kind = ExternalKind::Global; - if (wasm.getExportOrNull(ex->name)) { - throw SParseException("duplicate export", s); - } - wasm.addExport(ex.release()); - } else if (elementStartsWith(inner, IMPORT)) { - importModule = inner[1]->str(); - importBase = inner[2]->str(); - } else if (elementStartsWith(inner, MUT)) { - mutable_ = true; - type = elementToType(*inner[1]); - break; - } else { - type = elementToType(inner); - break; - } - } - if (type == Type::none) { - type = stringToType(s[i++]->str()); - } - if (importModule.is()) { - // this is an import, actually - if (!importBase.size()) { - throw SParseException("module but no base for import", s); - } - if (!preParseImport) { - throw SParseException("!preParseImport in global", s); - } - auto im = std::make_unique(); - im->name = global->name; - im->module = importModule; - im->base = importBase; - im->type = type; - im->mutable_ = mutable_; - if (wasm.getGlobalOrNull(im->name)) { - throw SParseException("duplicate import", s); - } - wasm.addGlobal(im.release()); - return; - } - global->type = type; - if (i < s.size()) { - global->init = parseExpression(s[i++]); - } else if (!preParseImport) { - throw SParseException("global without init", s); - } - global->mutable_ = mutable_; - if (i != s.size()) { - throw SParseException("extra import elements", s); - } - if (wasm.getGlobalOrNull(global->name)) { - throw SParseException("duplicate import", s); - } - wasm.addGlobal(global.release()); -} - -void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { - std::unique_ptr
table = std::make_unique
(); - Index i = 1; - if (s[i]->dollared()) { - table->setExplicitName(s[i++]->str()); - } else { - table->name = Name::fromInt(tableCounter++); - } - tableNames.push_back(table->name); - - Name importModule, importBase; - if (s[i]->isList()) { - auto& inner = *s[i]; - if (elementStartsWith(inner, EXPORT)) { - auto ex = std::make_unique(); - ex->name = inner[1]->str(); - ex->value = table->name; - ex->kind = ExternalKind::Table; - if (wasm.getExportOrNull(ex->name)) { - throw SParseException("duplicate export", inner); - } - wasm.addExport(ex.release()); - i++; - } else if (elementStartsWith(inner, IMPORT)) { - if (!preParseImport) { - throw SParseException("!preParseImport in table", inner); - } - table->module = inner[1]->str(); - table->base = inner[2]->str(); - i++; - } else if (!elementStartsWith(inner, REF)) { - throw SParseException("invalid table", inner); - } - } - - bool hasExplicitLimit = false; - - if (s[i]->isStr() && String::isNumber(s[i]->toString())) { - table->initial = parseIndex(*s[i++]); - hasExplicitLimit = true; - } - if (s[i]->isStr() && String::isNumber(s[i]->toString())) { - table->max = parseIndex(*s[i++]); - } - - table->type = elementToType(*s[i++]); - if (!table->type.isRef()) { - throw SParseException("Only reference types are valid for tables", s); - } - - if (i < s.size() && s[i]->isList()) { - if (hasExplicitLimit) { - throw SParseException( - "Table cannot have both explicit limits and an inline (elem ...)", s); - } - // (table type (elem ..)) - parseElem(*s[i], table.get()); - auto it = std::find_if(wasm.elementSegments.begin(), - wasm.elementSegments.end(), - [&](std::unique_ptr& segment) { - return segment->table == table->name; - }); - if (it != wasm.elementSegments.end()) { - table->initial = table->max = it->get()->data.size(); - } else { - table->initial = table->max = 0; - } - } - - wasm.addTable(std::move(table)); -} - -// parses an elem segment -// elem ::= (elem (table tableidx)? (offset (expr)) reftype vec(item (expr))) -// | (elem reftype vec(item (expr))) -// | (elem declare reftype vec(item (expr))) -// -// abbreviation: -// (offset (expr)) ≡ (expr) -// (item (expr)) ≡ (expr) -// ϵ ≡ (table 0) -// -// funcref vec(ref.func) ≡ func vec(funcidx) -// (elem (expr) vec(funcidx)) ≡ (elem (table 0) (offset (expr)) func -// vec(funcidx)) -// -void SExpressionWasmBuilder::parseElem(Element& s, Table* table) { - Index i = 1; - Name name = Name::fromInt(elemCounter++); - bool hasExplicitName = false; - bool isPassive = true; - bool usesExpressions = false; - - if (table) { - Expression* offset = allocator.alloc()->set(Literal(int32_t(0))); - auto segment = std::make_unique(table->name, offset); - segment->setName(name, hasExplicitName); - elemSegmentNames.push_back(name); - parseElemFinish(s, segment, i, s[i]->isList()); - return; - } - - if (s[i]->isStr() && s[i]->dollared()) { - name = s[i++]->str(); - hasExplicitName = true; - } - elemSegmentNames.push_back(name); - if (s[i]->isStr() && s[i]->str() == DECLARE) { - // We don't store declared segments in the IR - return; - } - - auto segment = std::make_unique(); - segment->setName(name, hasExplicitName); - - if (s[i]->isList() && !elementStartsWith(s[i], REF)) { - // Optional (table ) - if (elementStartsWith(s[i], TABLE)) { - auto& inner = *s[i++]; - segment->table = getTableName(*inner[1]); - } - - // Offset expression (offset ()) | () - auto& inner = *s[i++]; - if (elementStartsWith(inner, OFFSET)) { - if (inner.size() > 2) { - throw SParseException( - "Invalid offset for an element segment.", s, *s[i]); - } - segment->offset = parseExpression(inner[1]); - } else { - segment->offset = parseExpression(inner); - } - isPassive = false; - } - - if (i < s.size()) { - if (s[i]->isStr() && s[i]->dollared()) { - usesExpressions = false; - } else if (s[i]->isStr() && s[i]->str() == FUNC) { - usesExpressions = false; - i += 1; - } else { - segment->type = elementToType(*s[i]); - usesExpressions = true; - i += 1; - } - } - - if (!isPassive && segment->table.isNull()) { - if (wasm.tables.empty()) { - throw SParseException("active element without table", s); - } - table = wasm.tables.front().get(); - segment->table = table->name; - } - - // We may be post-MVP also due to type reasons or otherwise, as detected by - // the utility function for Binaryen IR. - usesExpressions = - usesExpressions || TableUtils::usesExpressions(segment.get(), &wasm); - - parseElemFinish(s, segment, i, usesExpressions); -} - -ElementSegment* SExpressionWasmBuilder::parseElemFinish( - Element& s, - std::unique_ptr& segment, - Index i, - bool usesExpressions) { - - for (; i < s.size(); i++) { - if (!s[i]->isList()) { - // An MVP-style declaration: just a function name. - auto func = getFunctionName(*s[i]); - segment->data.push_back( - Builder(wasm).makeRefFunc(func, functionTypes[func])); - continue; - } - if (!usesExpressions) { - throw SParseException("expected an MVP-style $funcname in elem.", s); - } - auto& inner = *s[i]; - if (elementStartsWith(inner, ITEM)) { - if (inner[1]->isList()) { - // (item (ref.func $f)) - segment->data.push_back(parseExpression(inner[1])); - } else { - // (item ref.func $f) - inner.list().removeAt(0); - segment->data.push_back(parseExpression(inner)); - } - } else { - segment->data.push_back(parseExpression(inner)); - } - } - return wasm.addElementSegment(std::move(segment)); -} - -HeapType SExpressionWasmBuilder::parseHeapType(Element& s) { - if (s.isStr()) { - // It's a string. - if (s.dollared()) { - auto it = typeIndices.find(s.toString()); - if (it == typeIndices.end()) { - throw SParseException("unknown dollared function type", s); - } - return types[it->second]; - } else { - // It may be a numerical index, or it may be a built-in type name like - // "i31". - auto str = s.toString(); - if (String::isNumber(str)) { - size_t offset = parseIndex(s); - if (offset >= types.size()) { - throw SParseException("unknown indexed function type", s); - } - return types[offset]; - } - return stringToHeapType(s.str(), /* prefix = */ false); - } - } - throw SParseException("invalid heap type", s); -} - -void SExpressionWasmBuilder::parseTag(Element& s, bool preParseImport) { - auto tag = std::make_unique(); - size_t i = 1; - - // Parse name - if (s[i]->isStr() && s[i]->dollared()) { - auto& inner = *s[i++]; - tag->setExplicitName(inner.str()); - if (wasm.getTagOrNull(tag->name)) { - throw SParseException("duplicate tag", inner); - } - } else { - tag->name = Name::fromInt(tagCounter); - assert(!wasm.getTagOrNull(tag->name)); - } - tagCounter++; - tagNames.push_back(tag->name); - - // Parse import, if any - if (i < s.size() && elementStartsWith(*s[i], IMPORT)) { - assert(preParseImport && "import element in non-preParseImport mode"); - auto& importElem = *s[i++]; - if (importElem.size() != 3) { - throw SParseException("invalid import", importElem); - } - if (!importElem[1]->isStr() || importElem[1]->dollared()) { - throw SParseException("invalid import module name", importElem); - } - if (!importElem[2]->isStr() || importElem[2]->dollared()) { - throw SParseException("invalid import base name", importElem); - } - tag->module = importElem[1]->str(); - tag->base = importElem[2]->str(); - } - - // Parse export, if any - if (i < s.size() && elementStartsWith(*s[i], EXPORT)) { - auto& exportElem = *s[i++]; - if (tag->module.is()) { - throw SParseException("import and export cannot be specified together", - exportElem); - } - if (exportElem.size() != 2) { - throw SParseException("invalid export", exportElem); - } - if (!exportElem[1]->isStr() || exportElem[1]->dollared()) { - throw SParseException("invalid export name", exportElem); - } - auto ex = std::make_unique(); - ex->name = exportElem[1]->str(); - if (wasm.getExportOrNull(ex->name)) { - throw SParseException("duplicate export", exportElem); - } - ex->value = tag->name; - ex->kind = ExternalKind::Tag; - wasm.addExport(ex.release()); - } - - // Parse typeuse - HeapType tagType; - i = parseTypeUse(s, i, tagType); - tag->sig = tagType.getSignature(); - - // If there are more elements, they are invalid - if (i < s.size()) { - throw SParseException("invalid element", *s[i]); - } - - wasm.addTag(tag.release()); -} - -void SExpressionWasmBuilder::validateHeapTypeUsingChild(Expression* child, - HeapType heapType, - Element& s) { - if (child->type == Type::unreachable) { - return; - } - if (!child->type.isRef() || - !HeapType::isSubType(child->type.getHeapType(), heapType)) { - throw SParseException("bad heap type: expected " + heapType.toString() + - " but found " + child->type.toString(), - s); - } -} - -} // namespace wasm diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp index 3f74c252c8a..81f095f48d2 100644 --- a/test/example/module-splitting.cpp +++ b/test/example/module-splitting.cpp @@ -5,7 +5,6 @@ #include "ir/stack-utils.h" #include "parser/wat-parser.h" #include "wasm-features.h" -#include "wasm-s-parser.h" #include "wasm-validator.h" #include "wasm.h" diff --git a/test/gtest/possible-contents.cpp b/test/gtest/possible-contents.cpp index a49fdfad5c1..c495a418771 100644 --- a/test/gtest/possible-contents.cpp +++ b/test/gtest/possible-contents.cpp @@ -1,7 +1,6 @@ #include "ir/possible-contents.h" #include "ir/subtypes.h" #include "parser/wat-parser.h" -#include "wasm-s-parser.h" #include "wasm.h" #include "gtest/gtest.h" diff --git a/test/gtest/print-test.h b/test/gtest/print-test.h index 678896eabc8..5a1c92f7a8a 100644 --- a/test/gtest/print-test.h +++ b/test/gtest/print-test.h @@ -2,7 +2,6 @@ #include "parser/wat-parser.h" #include "support/colors.h" -#include "wasm-s-parser.h" #include "wasm.h" #include "gtest/gtest.h" diff --git a/test/lit/deprecated-wat.wast b/test/lit/deprecated-wat.wast deleted file mode 100644 index 401d3244b23..00000000000 --- a/test/lit/deprecated-wat.wast +++ /dev/null @@ -1,24 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. - -;; RUN: wasm-opt --deprecated-wat-parser -all %s -S -o - | filecheck %s - -(module - ;; CHECK: (type $0 (func (param i32))) - - ;; CHECK: (type $1 (func (result i32))) - - ;; CHECK: (import "env" "bad" (func $wrong (type $0) (param i32))) - - ;; CHECK: (func $foo (type $1) (result i32) - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - (func $foo (result i32) - ;; Non-standard block result format - (block i32 - (i32.const 0) - ) - ) - - ;; Non-standard import after declared function - (import $wrong "env" "bad" (param i32)) -) diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index fd8bc5b1e0d..727d1ab2195 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -72,13 +72,6 @@ ;; CHECK-NEXT: --output-source-map-url,-osu Emit specified string as source ;; CHECK-NEXT: map URL ;; CHECK-NEXT: -;; CHECK-NEXT: --deprecated-wat-parser Use the old, deprecated WAT -;; CHECK-NEXT: parser. This option will be -;; CHECK-NEXT: removed soon! -;; CHECK-NEXT: -;; CHECK-NEXT: --new-wat-parser Use the experimental new WAT -;; CHECK-NEXT: parser -;; CHECK-NEXT: ;; CHECK-NEXT: --experimental-new-eh Deprecated; same as ;; CHECK-NEXT: --emit-exnref ;; CHECK-NEXT: diff --git a/test/lit/passes/string-lowering-instructions.wast b/test/lit/passes/string-lowering-instructions.wast index 44c004ea5f2..b98b9af233b 100644 --- a/test/lit/passes/string-lowering-instructions.wast +++ b/test/lit/passes/string-lowering-instructions.wast @@ -1,7 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: foreach %s %t wasm-opt --string-lowering -all -S -o - | filecheck %s -;; RUN: foreach %s %t wasm-opt --new-wat-parser --string-lowering -all -S -o - | filecheck %s (module (rec diff --git a/test/lit/validation/global-cycle.wast b/test/lit/validation/global-cycle.wast index 1887e5716ef..acba9a3b674 100644 --- a/test/lit/validation/global-cycle.wast +++ b/test/lit/validation/global-cycle.wast @@ -1,4 +1,4 @@ -;; RUN: not wasm-opt %s --new-wat-parser -all 2>&1 | filecheck %s +;; RUN: not wasm-opt %s -all 2>&1 | filecheck %s ;; CHECK: global initializer should only refer to previous globals diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index f4b5dc16c1b..527bfdd059d 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -1,6 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: wasm-opt --new-wat-parser -all %s -S -o - | filecheck %s +;; RUN: wasm-opt -all %s -S -o - | filecheck %s (module $parse ;; types From 56fe06220d558d300f3d49a036d637632ebd5ae4 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 29 May 2024 15:40:44 -0700 Subject: [PATCH 362/553] [NFC] Save a line in wasm-shell.cpp (#6631) --- src/tools/wasm-shell.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index c5de531f5a5..65185796516 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -55,7 +55,7 @@ struct Shell { size_t i = 0; for (auto& entry : script) { Colors::red(std::cerr); - std::cerr << i << ' '; + std::cerr << i++ << ' '; Colors::normal(std::cerr); if (std::get_if(&entry.cmd)) { Colors::green(std::cerr); @@ -71,7 +71,6 @@ struct Shell { std::cerr << "CHECKING [line: " << entry.line << "]\n"; Colors::normal(std::cerr); } - ++i; CHECK_ERR(runCommand(entry.cmd)); } return Ok{}; From b85197cac4a295768f83133f7d01347ae2051276 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 29 May 2024 16:48:55 -0700 Subject: [PATCH 363/553] SignaturePruning: Properly handle public types (#6630) The SignaturePruning pass optimizes away parameters that it proves are safe to remove. It turns out that that does not always match the definition of private types, which is more restrictive. Specifically, if say all the types are in one big rec group and one of them is used on an exported function then all of them are considered public (as the rec group is). However, in closed world, it would be ok to leave that rec group unchanged but to create a pruned version of that type and use it, in cases where we see it is safe to remove a parameter. (See the testcase for a concrete example.) To put it another way, SignaturePruning already proves that a parameter is safe to remove in all the ways that matter. Before this PR, however, the testcase in this PR would error - so this PR is not an optimization but a bugfix, really - because SignaturePruning would see that a parameter is safe to remove but then TypeUpdating would see the type is public and so it would leave it alone, leading to a broken module. This situation is in fact not that rare, and happens on real-world Java code. The reason we did not notice it before is that typically there are no remaining SignaturePruning opportunities late in the process (when other closed world optimizations have typically led to a single big rec group). The concrete fix here is to add additionalPrivateTypes to a few more places in TypeUpdating. We already supported that for cases where a pass knew better than the general logic what can be modified, and this adds that ability to the signature-rewriting logic there. Then SignaturePruning can send in all the types it has proven are safe to modify. * Also necessary here is to only add from additionalPrivateTypes if the type is not already in our list (or we'd end up with duplicates in the final rec group). * Also move newSignatures in SignaturePruning out of the top level, which was confusing (the pass has multiple iterations, and we want each to have a fresh instance). --- src/ir/type-updating.cpp | 18 ++++++++-- src/ir/type-updating.h | 24 ++++++++----- src/passes/SignaturePruning.cpp | 22 ++++++++---- test/lit/passes/signature-pruning.wast | 49 ++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 12a8c7c3621..760d71b9c20 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -28,7 +28,10 @@ namespace wasm { GlobalTypeRewriter::GlobalTypeRewriter(Module& wasm) : wasm(wasm) {} -void GlobalTypeRewriter::update() { mapTypes(rebuildTypes()); } +void GlobalTypeRewriter::update( + const std::vector& additionalPrivateTypes) { + mapTypes(rebuildTypes(additionalPrivateTypes)); +} GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( const std::vector& additionalPrivateTypes) { @@ -40,8 +43,17 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( Index i = 0; auto privateTypes = ModuleUtils::getPrivateHeapTypes(wasm); - for (auto t : additionalPrivateTypes) { - privateTypes.push_back(t); + if (!additionalPrivateTypes.empty()) { + // Only add additional private types that are not already in the list. + std::unordered_set privateTypesSet(privateTypes.begin(), + privateTypes.end()); + + for (auto t : additionalPrivateTypes) { + if (!privateTypesSet.count(t)) { + privateTypes.push_back(t); + privateTypesSet.insert(t); + } + } } // Topological sort to have supertypes first, but we have to account for the diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h index 1626b40bdf6..60b92e58531 100644 --- a/src/ir/type-updating.h +++ b/src/ir/type-updating.h @@ -352,7 +352,12 @@ class GlobalTypeRewriter { // Main entry point. This performs the entire process of creating new heap // types and calling the hooks below, then applies the new types throughout // the module. - void update(); + // + // This only operates on private types (so as not to modify the module's + // external ABI). It takes as a parameter a list of public types to consider + // private, which allows more flexibility (e.g. in closed world if a pass + // knows a type is safe to modify despite being public, it can add it). + void update(const std::vector& additionalPrivateTypes = {}); using TypeMap = std::unordered_map; @@ -398,7 +403,10 @@ class GlobalTypeRewriter { // Helper for the repeating pattern of just updating Signature types using a // map of old heap type => new Signature. - static void updateSignatures(const SignatureUpdates& updates, Module& wasm) { + static void + updateSignatures(const SignatureUpdates& updates, + Module& wasm, + const std::vector& additionalPrivateTypes = {}) { if (updates.empty()) { return; } @@ -407,9 +415,11 @@ class GlobalTypeRewriter { const SignatureUpdates& updates; public: - SignatureRewriter(Module& wasm, const SignatureUpdates& updates) + SignatureRewriter(Module& wasm, + const SignatureUpdates& updates, + const std::vector& additionalPrivateTypes) : GlobalTypeRewriter(wasm), updates(updates) { - update(); + update(additionalPrivateTypes); } void modifySignature(HeapType oldSignatureType, Signature& sig) override { @@ -419,7 +429,7 @@ class GlobalTypeRewriter { sig.results = getTempType(iter->second.results); } } - } rewriter(wasm, updates); + } rewriter(wasm, updates, additionalPrivateTypes); } protected: @@ -427,9 +437,7 @@ class GlobalTypeRewriter { // returns a map from the old types to the modified types. Used internally in // update(). // - // This only operates on private types (so as not to modify the module's - // external ABI). It takes as a parameter a list of public types to consider - // private, which allows more flexibility. + // See above regarding private types. TypeMap rebuildTypes(const std::vector& additionalPrivateTypes = {}); diff --git a/src/passes/SignaturePruning.cpp b/src/passes/SignaturePruning.cpp index 2e4be89e895..4480c18321e 100644 --- a/src/passes/SignaturePruning.cpp +++ b/src/passes/SignaturePruning.cpp @@ -45,11 +45,6 @@ namespace wasm { namespace { struct SignaturePruning : public Pass { - // Maps each heap type to the possible pruned heap type. We will fill this - // during analysis and then use it while doing an update of the types. If a - // type has no improvement that we can find, it will not appear in this map. - std::unordered_map newSignatures; - void run(Module* module) override { if (!module->features.hasGC()) { return; @@ -182,6 +177,11 @@ struct SignaturePruning : public Pass { // types with subtyping relations at once. SubTypes subTypes(*module); + // Maps each heap type to the possible pruned signature. We will fill this + // during analysis and then use it while doing an update of the types. If a + // type has no improvement that we can find, it will not appear in this map. + std::unordered_map newSignatures; + // Find parameters to prune. // // TODO: The order matters here, and more than one cycle can find more work @@ -291,8 +291,16 @@ struct SignaturePruning : public Pass { } } - // Rewrite the types. - GlobalTypeRewriter::updateSignatures(newSignatures, *module); + // Rewrite the types. We pass in all the types we intend to modify as being + // "additional private types" because we have proven above that they are + // safe to modify, even if they are technically public (e.g. they may be in + // a singleton big rec group that is public because one member is public). + std::vector additionalPrivateTypes; + for (auto& [type, sig] : newSignatures) { + additionalPrivateTypes.push_back(type); + } + GlobalTypeRewriter::updateSignatures( + newSignatures, *module, additionalPrivateTypes); if (callTargetsToLocalize.empty()) { return false; diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast index cad9af82b7a..c273d1588ba 100644 --- a/test/lit/passes/signature-pruning.wast +++ b/test/lit/passes/signature-pruning.wast @@ -1151,3 +1151,52 @@ ) ) ) + +;; $exported is exported. The entire rec group becomes exported as well, which +;; causes $unused-param's type to be public, which means we cannot normally +;; modify it. However, in closed world we allow such changes, and we can remove +;; the unused param there. What happens is that we keep the original public rec +;; group as-is, and add a new rec group for private types, put the pruned type +;; there, and use that pruned type on $unused-param. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $much (func)) + + ;; CHECK: (type $1 (func)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $none (func)) + (type $none (func)) + ;; CHECK: (type $much (func (param i32))) + (type $much (func (param i32))) + ) + + ;; CHECK: (export "exported" (func $exported)) + + ;; CHECK: (func $exported (type $none) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $exported (export "exported") (type $none) + ) + + ;; CHECK: (func $unused-param (type $much) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $unused-param (type $much) (param $param i32) + ) + + ;; CHECK: (func $caller (type $1) + ;; CHECK-NEXT: (call $unused-param) + ;; CHECK-NEXT: ) + (func $caller + (call $unused-param + (i32.const 0) + ) + ) +) + From 5d90167464ef5709406aea7d87ad1657eec8618b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 29 May 2024 16:49:59 -0700 Subject: [PATCH 364/553] Fix Vacuuming of code leading up to an infinite loop (#6632) We had that logic right in other places, but the specific part of Vacuum that looks at code that leads up to an unreachable did not check for infinite loops, so it could remove them. --- src/passes/Vacuum.cpp | 9 ++--- test/lit/passes/vacuum-tnh.wast | 63 +++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 41a8e02da8a..4a4963291c9 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -158,15 +158,16 @@ struct Vacuum : public WalkerPass> { continue; } - // Check if we may no longer be heading to a trap. Two situations count - // here: Control flow might branch, or we might call (since a call might - // reach an import; see notes on that in pass.h:trapsNeverHappen). + // Check if we may no longer be heading to a trap. We can only optimize + // if the trap will actually be reached. Two situations can prevent that + // here: Control flow might branch away, or we might hang (which can + // happen in a call or a loop). // // We also cannot remove a pop as it is necessary for structural // reasons. EffectAnalyzer effects(getPassOptions(), *getModule(), list[i]); if (effects.transfersControlFlow() || effects.calls || - effects.danglingPop) { + effects.mayNotReturn || effects.danglingPop) { headingToTrap = false; continue; } diff --git a/test/lit/passes/vacuum-tnh.wast b/test/lit/passes/vacuum-tnh.wast index f74dc3c8761..8a93a720fed 100644 --- a/test/lit/passes/vacuum-tnh.wast +++ b/test/lit/passes/vacuum-tnh.wast @@ -117,10 +117,10 @@ ) ;; A helper function for the above, that returns nothing. - ;; YESTNH: (func $return-nothing (type $1) + ;; YESTNH: (func $return-nothing (type $0) ;; YESTNH-NEXT: (nop) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $return-nothing (type $1) + ;; NO_TNH: (func $return-nothing (type $0) ;; NO_TNH-NEXT: (nop) ;; NO_TNH-NEXT: ) (func $return-nothing) @@ -179,10 +179,10 @@ (local.get $y) ) - ;; YESTNH: (func $toplevel (type $1) + ;; YESTNH: (func $toplevel (type $0) ;; YESTNH-NEXT: (nop) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $toplevel (type $1) + ;; NO_TNH: (func $toplevel (type $0) ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) (func $toplevel @@ -191,7 +191,7 @@ (unreachable) ) - ;; YESTNH: (func $drop-loop (type $1) + ;; YESTNH: (func $drop-loop (type $0) ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (loop $loop (result i32) ;; YESTNH-NEXT: (br_if $loop @@ -201,7 +201,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $drop-loop (type $1) + ;; NO_TNH: (func $drop-loop (type $0) ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (loop $loop (result i32) ;; NO_TNH-NEXT: (br_if $loop @@ -224,7 +224,7 @@ ) ) - ;; YESTNH: (func $loop-effects (type $1) + ;; YESTNH: (func $loop-effects (type $0) ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (loop $loop (result i32) ;; YESTNH-NEXT: (drop @@ -239,7 +239,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $loop-effects (type $1) + ;; NO_TNH: (func $loop-effects (type $0) ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (loop $loop (result i32) ;; NO_TNH-NEXT: (drop @@ -272,7 +272,7 @@ ) ) - ;; YESTNH: (func $if-unreachable (type $0) (param $p i32) + ;; YESTNH: (func $if-unreachable (type $1) (param $p i32) ;; YESTNH-NEXT: (drop ;; YESTNH-NEXT: (local.get $p) ;; YESTNH-NEXT: ) @@ -294,7 +294,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $if-unreachable (type $0) (param $p i32) + ;; NO_TNH: (func $if-unreachable (type $1) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) ;; NO_TNH-NEXT: (then @@ -415,7 +415,7 @@ ) ) - ;; YESTNH: (func $block-unreachable (type $0) (param $p i32) + ;; YESTNH: (func $block-unreachable (type $1) (param $p i32) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) ;; YESTNH-NEXT: (then @@ -433,7 +433,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $block-unreachable (type $0) (param $p i32) + ;; NO_TNH: (func $block-unreachable (type $1) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) ;; NO_TNH-NEXT: (then @@ -482,7 +482,7 @@ ) ) - ;; YESTNH: (func $block-unreachable-named (type $0) (param $p i32) + ;; YESTNH: (func $block-unreachable-named (type $1) (param $p i32) ;; YESTNH-NEXT: (if ;; YESTNH-NEXT: (local.get $p) ;; YESTNH-NEXT: (then @@ -499,7 +499,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $block-unreachable-named (type $0) (param $p i32) + ;; NO_TNH: (func $block-unreachable-named (type $1) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) ;; NO_TNH-NEXT: (then @@ -544,10 +544,10 @@ ) ) - ;; YESTNH: (func $block-unreachable-all (type $0) (param $p i32) + ;; YESTNH: (func $block-unreachable-all (type $1) (param $p i32) ;; YESTNH-NEXT: (nop) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $block-unreachable-all (type $0) (param $p i32) + ;; NO_TNH: (func $block-unreachable-all (type $1) (param $p i32) ;; NO_TNH-NEXT: (if ;; NO_TNH-NEXT: (local.get $p) ;; NO_TNH-NEXT: (then @@ -584,7 +584,7 @@ ) ) - ;; YESTNH: (func $block-unreachable-but-call (type $1) + ;; YESTNH: (func $block-unreachable-but-call (type $0) ;; YESTNH-NEXT: (i32.store ;; YESTNH-NEXT: (i32.const 0) ;; YESTNH-NEXT: (i32.const 1) @@ -592,7 +592,7 @@ ;; YESTNH-NEXT: (call $block-unreachable-but-call) ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $block-unreachable-but-call (type $1) + ;; NO_TNH: (func $block-unreachable-but-call (type $0) ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 0) ;; NO_TNH-NEXT: (i32.const 1) @@ -620,7 +620,7 @@ (unreachable) ) - ;; YESTNH: (func $catch-pop (type $1) + ;; YESTNH: (func $catch-pop (type $0) ;; YESTNH-NEXT: (try $try ;; YESTNH-NEXT: (do ;; YESTNH-NEXT: (call $catch-pop) @@ -633,7 +633,7 @@ ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $catch-pop (type $1) + ;; NO_TNH: (func $catch-pop (type $0) ;; NO_TNH-NEXT: (try $try ;; NO_TNH-NEXT: (do ;; NO_TNH-NEXT: (call $catch-pop) @@ -673,7 +673,7 @@ ) ) - ;; YESTNH: (func $loop-unreachable (type $0) (param $p i32) + ;; YESTNH: (func $loop-unreachable (type $1) (param $p i32) ;; YESTNH-NEXT: (loop $loop ;; YESTNH-NEXT: (i32.store ;; YESTNH-NEXT: (i32.const 0) @@ -688,7 +688,7 @@ ;; YESTNH-NEXT: (unreachable) ;; YESTNH-NEXT: ) ;; YESTNH-NEXT: ) - ;; NO_TNH: (func $loop-unreachable (type $0) (param $p i32) + ;; NO_TNH: (func $loop-unreachable (type $1) (param $p i32) ;; NO_TNH-NEXT: (loop $loop ;; NO_TNH-NEXT: (i32.store ;; NO_TNH-NEXT: (i32.const 0) @@ -728,4 +728,23 @@ (unreachable) ) ) + + ;; YESTNH: (func $unreached-infinite-loop (type $0) + ;; YESTNH-NEXT: (loop $label$1 + ;; YESTNH-NEXT: (br $label$1) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: ) + ;; NO_TNH: (func $unreached-infinite-loop (type $0) + ;; NO_TNH-NEXT: (loop $label$1 + ;; NO_TNH-NEXT: (br $label$1) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: ) + (func $unreached-infinite-loop + ;; Code that reaches an unreachable can be removed in TNH mode, but an + ;; infinite loop may not reach it, so nothing can be removed here. + (loop $label$1 + (br $label$1) + ) + (unreachable) + ) ) From 0148db0b081c4bf25cb91ef71f9aba5f7765e378 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 30 May 2024 12:49:24 -0700 Subject: [PATCH 365/553] [NFC] Port LogExecution test to lit (#6634) --- test/lit/passes/log-execution.wast | 146 +++++++++++++++++++++++++++++ test/passes/log-execution.txt | 102 -------------------- test/passes/log-execution.wast | 38 -------- 3 files changed, 146 insertions(+), 140 deletions(-) create mode 100644 test/lit/passes/log-execution.wast delete mode 100644 test/passes/log-execution.txt delete mode 100644 test/passes/log-execution.wast diff --git a/test/lit/passes/log-execution.wast b/test/lit/passes/log-execution.wast new file mode 100644 index 00000000000..561c7560f69 --- /dev/null +++ b/test/lit/passes/log-execution.wast @@ -0,0 +1,146 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --log-execution -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (result i32))) + + ;; CHECK: (type $2 (func (param i32))) + + ;; CHECK: (import "env" "func" (func $import)) + (import "env" "func" (func $import)) + ;; CHECK: (import "env" "log_execution" (func $log_execution (param i32))) + + ;; CHECK: (func $nopp + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nopp + (nop) + ) + ;; CHECK: (func $intt (result i32) + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + (func $intt (result i32) + (i32.const 10) + ) + ;; CHECK: (func $workk + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $workk + (if (i32.const 0) (then (nop))) + (drop (i32.const 1)) + ) + ;; CHECK: (func $loops + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (loop $x + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $loops) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $intt) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (loop $y + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $loops) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loops + (loop $x + (call $loops) + (br $x) + ) + (if (call $intt) + (then + (loop $y + (call $loops) + ) + ) + ) + (loop + (drop (i32.const 10)) + (drop (i32.const 20)) + (drop (i32.const 30)) + ) + ) + ;; CHECK: (func $loops-similar + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $x + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $loops) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loops-similar + (loop $x + (call $loops) + (br $x) + ) + ) +) + diff --git a/test/passes/log-execution.txt b/test/passes/log-execution.txt deleted file mode 100644 index f7c46b58422..00000000000 --- a/test/passes/log-execution.txt +++ /dev/null @@ -1,102 +0,0 @@ -(module - (type $0 (func)) - (type $1 (func (result i32))) - (type $2 (func (param i32))) - (import "env" "func" (func $import)) - (import "env" "log_execution" (func $log_execution (param i32))) - (func $nopp - (call $log_execution - (i32.const 0) - ) - (nop) - ) - (func $intt (result i32) - (call $log_execution - (i32.const 1) - ) - (i32.const 10) - ) - (func $workk - (call $log_execution - (i32.const 3) - ) - (block - (if - (i32.const 0) - (then - (nop) - ) - ) - (block - (call $log_execution - (i32.const 2) - ) - (drop - (i32.const 1) - ) - ) - ) - ) - (func $loops - (call $log_execution - (i32.const 8) - ) - (block - (loop $x - (call $log_execution - (i32.const 4) - ) - (block - (call $loops) - (br $x) - ) - ) - (if - (call $intt) - (then - (loop $y - (call $log_execution - (i32.const 5) - ) - (call $loops) - ) - ) - ) - (block - (call $log_execution - (i32.const 7) - ) - (loop - (call $log_execution - (i32.const 6) - ) - (block - (drop - (i32.const 10) - ) - (drop - (i32.const 20) - ) - (drop - (i32.const 30) - ) - ) - ) - ) - ) - ) - (func $loops-similar - (call $log_execution - (i32.const 10) - ) - (loop $x - (call $log_execution - (i32.const 9) - ) - (block - (call $loops) - (br $x) - ) - ) - ) -) diff --git a/test/passes/log-execution.wast b/test/passes/log-execution.wast deleted file mode 100644 index b84d7ac1f40..00000000000 --- a/test/passes/log-execution.wast +++ /dev/null @@ -1,38 +0,0 @@ -(module - (import "env" "func" (func $import)) - (func $nopp - (nop) - ) - (func $intt (result i32) - (i32.const 10) - ) - (func $workk - (if (i32.const 0) (then (nop))) - (drop (i32.const 1)) - ) - (func $loops - (loop $x - (call $loops) - (br $x) - ) - (if (call $intt) - (then - (loop $y - (call $loops) - ) - ) - ) - (loop - (drop (i32.const 10)) - (drop (i32.const 20)) - (drop (i32.const 30)) - ) - ) - (func $loops-similar - (loop $x - (call $loops) - (br $x) - ) - ) -) - From 18bb1f5af22b4d6bc309b96d844f856077eb6b60 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 30 May 2024 13:44:18 -0700 Subject: [PATCH 366/553] Avoid duplicate type names (#6633) If we replace a type with another, use the original name for the new type, and give the old a unique name (for the rare cases in which it has uses). --- src/ir/type-updating.cpp | 23 ++++++++++++++++++++--- src/passes/RemoveUnusedTypes.cpp | 2 +- test/lit/passes/signature-pruning.wast | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 760d71b9c20..520408d449f 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -18,6 +18,7 @@ #include "find_all.h" #include "ir/local-structural-dominance.h" #include "ir/module-utils.h" +#include "ir/names.h" #include "ir/utils.h" #include "support/topological_sort.h" #include "wasm-type-ordering.h" @@ -152,11 +153,27 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( oldToNewTypes[type] = newTypes[index]; } - // Update type names (doing it before mapTypes can help debugging there, but - // has no other effect; mapTypes does not look at type names). + // Update type names to avoid duplicates. + std::unordered_set typeNames; + for (auto& [type, info] : wasm.typeNames) { + typeNames.insert(info.name); + } for (auto& [old, new_] : oldToNewTypes) { + if (old == new_) { + // The type is being mapped to itself; no need to rename anything. + continue; + } + if (auto it = wasm.typeNames.find(old); it != wasm.typeNames.end()) { - wasm.typeNames[new_] = it->second; + wasm.typeNames[new_] = wasm.typeNames[old]; + // Use the existing name in the new type, as usually it completely + // replaces the old. Rename the old name in a unique way to avoid + // confusion in the case that it remains used. + auto deduped = + Names::getValidName(wasm.typeNames[old].name, + [&](Name test) { return !typeNames.count(test); }); + wasm.typeNames[old].name = deduped; + typeNames.insert(deduped); } } diff --git a/src/passes/RemoveUnusedTypes.cpp b/src/passes/RemoveUnusedTypes.cpp index 1ea65fb0f04..45222708a81 100644 --- a/src/passes/RemoveUnusedTypes.cpp +++ b/src/passes/RemoveUnusedTypes.cpp @@ -45,7 +45,7 @@ struct RemoveUnusedTypes : Pass { } // We're not changing the contents of any of the types, so we just round - // trip them throgh GlobalTypeRewriter, which will put all the private types + // trip them through GlobalTypeRewriter which will put all the private types // in a single new rec group and leave out all the unused types. GlobalTypeRewriter(*module).update(); } diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast index c273d1588ba..8754c8189f8 100644 --- a/test/lit/passes/signature-pruning.wast +++ b/test/lit/passes/signature-pruning.wast @@ -1168,10 +1168,11 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $none (func)) (type $none (func)) - ;; CHECK: (type $much (func (param i32))) (type $much (func (param i32))) ) + ;; CHECK: (type $much_0 (func (param i32))) + ;; CHECK: (export "exported" (func $exported)) ;; CHECK: (func $exported (type $none) From 0c23394e9d73252000c3161fb33344ca7bbf247c Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 31 May 2024 13:04:11 +0900 Subject: [PATCH 367/553] LogExecution: Optionally take a module name for the logger function (#6629) --log-execution=NAME will use NAME as the module for the logger function import, rather than infer it. If the name is not provided (--log-execution as before this PR) then we will try to automatically decide which to use ("env", unless we see another module name is used, which can be the case in optimized modules). --- src/passes/LogExecution.cpp | 42 ++++++++++++++++++-------- test/lit/passes/log-execution_arg.wast | 24 +++++++++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 test/lit/passes/log-execution_arg.wast diff --git a/src/passes/LogExecution.cpp b/src/passes/LogExecution.cpp index 1b90842bc3d..f1d48012f85 100644 --- a/src/passes/LogExecution.cpp +++ b/src/passes/LogExecution.cpp @@ -39,9 +39,18 @@ namespace wasm { Name LOGGER("log_execution"); struct LogExecution : public WalkerPass> { + // The module name the logger function is imported from. + IString loggerModule; + // Adds calls to new imports. bool addsEffects() override { return true; } + void run(Module* module) override { + auto& options = getPassOptions(); + loggerModule = options.getArgumentOrDefault("log-execution", ""); + super::run(module); + } + void visitLoop(Loop* curr) { curr->body = makeLogCall(curr->body); } void visitReturn(Return* curr) { replaceCurrent(makeLogCall(curr)); } @@ -63,23 +72,32 @@ struct LogExecution : public WalkerPass> { auto import = Builder::makeFunction(LOGGER, Signature(Type::i32, Type::none), {}); - // Import the log function from import "env" if the module - // imports other functions from that name. - for (auto& func : curr->functions) { - if (func->imported() && func->module == ENV) { - import->module = func->module; - break; - } - } - - // If not, then pick the import name of the first function we find. - if (!import->module) { + if (loggerModule != "") { + import->module = loggerModule; + } else { + // Import the log function from import "env" if the module + // imports other functions from that name. for (auto& func : curr->functions) { - if (func->imported()) { + if (func->imported() && func->module == ENV) { import->module = func->module; break; } } + + // If not, then pick the import name of the first function we find. + if (!import->module) { + for (auto& func : curr->functions) { + if (func->imported()) { + import->module = func->module; + break; + } + } + } + + // If no function was found, use ENV. + if (!import->module) { + import->module = ENV; + } } import->base = LOGGER; diff --git a/test/lit/passes/log-execution_arg.wast b/test/lit/passes/log-execution_arg.wast new file mode 100644 index 00000000000..e987655d6c5 --- /dev/null +++ b/test/lit/passes/log-execution_arg.wast @@ -0,0 +1,24 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; Test the option to provide the module name as an argument. +;; RUN: foreach %s %t wasm-opt --log-execution=foo -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (param i32))) + + ;; CHECK: (import "env" "func" (func $import)) + (import "env" "func" (func $import)) + ;; CHECK: (import "foo" "log_execution" (func $log_execution (param i32))) + + ;; CHECK: (func $nopp + ;; CHECK-NEXT: (call $log_execution + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nopp + (nop) + ) +) + From f8086adbf030b26eb7ce75e5d1834ae8134c689e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 31 May 2024 14:55:57 -0700 Subject: [PATCH 368/553] Optimize ReorderGlobals ordering with a new algorithm (#6625) The old ordering in that pass did a topological sort while sorting by uses both within topological groups and between them. That could be unoptimal in some cases, however, and actually on J2CL output this pass made the binary larger, which is how we noticed this. The problem is that such a toplogical sort keeps topological groups in place, but it can be useful to interleave them sometimes. Imagine this: $c - $a / $e \ $d - $b Here $e depends on $c, etc. The optimal order may interleave the two arms here, e.g. $a, $b, $d, $c, $e. That is because the dependencies define a partial order, and so the arms here are actually independent. Sorting by toplogical depth first might help in some cases, but also is not optimal in general, as we may want to mix toplogical depths: $a, $c, $b, $d, $e does so, and it may be the best ordering. This PR implements a natural greedy algorithm that picks the global with the highest use count at each step, out of the set of possible globals, which is the set of globals that have no unresolved dependencies. So we start by picking the first global with no dependencies and add at at the front; then that unlocks anything that depended on it and we pick from that set, and so forth. This may also not be optimal, but it is easy to make it more flexible by customizing the counts, and we consider 4 sorts here: * Set all counts to 0. This means we only take into account dependencies, and we break ties by the original order, so this is as close to the original order as we can be. * Use the actual use counts. This is the simple greedy algorithm. * Set the count of each global to also contain the counts of its children, so the count is the total that might be unlocked. This gives more weight to globals that can unlock more later, so it is less greedy. * As last, but weight children's counts lower in an exponential way, which makes sense as they may depend on other globals too. In practice it is simple to generate cases where 1, 2, or 3 is optimal (see new tests), but on real-world J2CL I see that 4 (with a particular exponential coefficient) is best, so the pass computes all 4 and picks the best. As a result it will never worsen the size and it has a good chance of improving. The differences between these are small, so in theory we could pick any of them, but given they are all modifications of a single algorithm it is very easy to compute them all with little code complexity. The benefits are rather small here, but this can save a few hundred bytes on a multi-MB Java file. This comes at a tiny compile time cost, but seems worth it for the new guarantee to never regress size. --- src/passes/ReorderGlobals.cpp | 397 ++++++++-- test/lit/merge/names.wat | 12 +- test/lit/merge/renamings.wat | 11 +- test/lit/passes/j2cl.wast | 25 +- test/lit/passes/reorder-globals-real.wast | 894 ++++++++++++++++++++++ test/lit/passes/reorder-globals.wast | 547 ++++++++++++- 6 files changed, 1774 insertions(+), 112 deletions(-) create mode 100644 test/lit/passes/reorder-globals-real.wast diff --git a/src/passes/ReorderGlobals.cpp b/src/passes/ReorderGlobals.cpp index 9b5940a214b..4602f328496 100644 --- a/src/passes/ReorderGlobals.cpp +++ b/src/passes/ReorderGlobals.cpp @@ -19,6 +19,17 @@ // binaries because fewer bytes are needed to encode references to frequently // used globals. // +// This pass also sorts by dependencies, as each global can only appear after +// those it refers to. Other passes can use this internally to fix the ordering +// after they add new globals. +// +// The "always" variant of this pass will always sort globals, even if there are +// so few they all fit in a single LEB. In "always" mode we sort regardless and +// we measure size by considering each subsequent index to have a higher cost. +// That is, in reality the size of all globals up to 128 is a single byte, and +// then the LEB grows to 2, while in "always" mode we increase the size by 1/128 +// for each global in a smooth manner. "Always" is mainly useful for testing. +// #include "memory" @@ -29,14 +40,15 @@ namespace wasm { -using NameCountMap = std::unordered_map>; +// We'll count uses in parallel. +using AtomicNameCountMap = std::unordered_map>; struct UseCountScanner : public WalkerPass> { bool isFunctionParallel() override { return true; } bool modifiesBinaryenIR() override { return false; } - UseCountScanner(NameCountMap& counts) : counts(counts) {} + UseCountScanner(AtomicNameCountMap& counts) : counts(counts) {} std::unique_ptr create() override { return std::make_unique(counts); @@ -53,112 +65,355 @@ struct UseCountScanner : public WalkerPass> { } private: - NameCountMap& counts; + AtomicNameCountMap& counts; }; struct ReorderGlobals : public Pass { - // Whether to always reorder globals, even if there are very few and the - // benefit is minor. That is useful for testing, and also internally in passes - // that use us to reorder them so dependencies appear first (that is, if a - // pass ends up with an earlier global reading a later one, the sorting in - // this pass will reorder them properly; we need to take those dependencies - // into account anyhow here). bool always; ReorderGlobals(bool always) : always(always) {} + // For efficiency we will use global indices rather than names. That is, we + // use the index of the global in the original ordering to identify each + // global. A different ordering is then a vector of new indices, saying where + // each one moves, which is logically a mapping between indices. + using IndexIndexMap = std::vector; + + // We will also track counts of uses for each global. We use floating-point + // values here since while the initial counts are integers, we will be + // considering fractional sums of them later. + using IndexCountMap = std::vector; + + // We must take into account dependencies, so that globals appear before + // their users in other globals: + // + // (global $a i32 (i32.const 10)) + // (global $b i32 (global.get $a)) ;; $b depends on $a; $a must be first + // + // To do so we construct a map from each global to those it depends on. We + // also build the reverse map, of those that it is depended upon by. + struct Dependencies { + std::unordered_map> dependsOn; + std::unordered_map> dependedUpon; + }; + void run(Module* module) override { - if (module->globals.size() < 128 && !always) { + auto& globals = module->globals; + + if (globals.size() < 128 && !always) { // The module has so few globals that they all fit in a single-byte U32LEB // value, so no reordering we can do can actually decrease code size. Note // that this is the common case with wasm MVP modules where the only // globals are typically the stack pointer and perhaps a handful of others // (however, features like wasm GC there may be a great many globals). + // TODO: we still need to sort here to fix dependencies sometimes return; } - NameCountMap counts; + AtomicNameCountMap atomicCounts; // Fill in info, as we'll operate on it in parallel. - for (auto& global : module->globals) { - counts[global->name]; + for (auto& global : globals) { + atomicCounts[global->name]; } // Count uses. - UseCountScanner scanner(counts); + UseCountScanner scanner(atomicCounts); scanner.run(getPassRunner(), module); scanner.runOnModuleCode(getPassRunner(), module); - // Do a toplogical sort to ensure we keep dependencies before the things - // that need them. For example, if $b's definition depends on $a then $b - // must appear later: - // - // (global $a i32 (i32.const 10)) - // (global $b i32 (global.get $a)) ;; $b depends on $a - // - struct DependencySort : TopologicalSort { - Module& wasm; - const NameCountMap& counts; - - std::unordered_map> deps; - - DependencySort(Module& wasm, const NameCountMap& counts) - : wasm(wasm), counts(counts) { - // Sort a list of global names by their counts. - auto sort = [&](std::vector& globals) { - std::stable_sort( - globals.begin(), globals.end(), [&](const Name& a, const Name& b) { - return counts.at(a) < counts.at(b); - }); - }; - - // Sort the globals. - std::vector sortedNames; - for (auto& global : wasm.globals) { - sortedNames.push_back(global->name); - } - sort(sortedNames); + // Switch to non-atomic for all further processing, and convert names to + // indices. + std::unordered_map originalIndices; + for (Index i = 0; i < globals.size(); i++) { + originalIndices[globals[i]->name] = i; + } + IndexCountMap counts(globals.size()); + for (auto& [name, count] : atomicCounts) { + counts[originalIndices[name]] = count; + } - // Everything is a root (we need to emit all globals). - for (auto global : sortedNames) { - push(global); + // Compute dependencies. + Dependencies deps; + for (Index i = 0; i < globals.size(); i++) { + auto& global = globals[i]; + if (!global->imported()) { + for (auto* get : FindAll(global->init).list) { + auto getIndex = originalIndices[get->name]; + deps.dependsOn[i].insert(getIndex); + deps.dependedUpon[getIndex].insert(i); } + } + } + + // Compute various sorting options. All the options use a variation of the + // algorithm in doSort() below, see there for more details; the only + // difference between the sorts is in the use counts we provide it. + struct SortAndSize { + IndexIndexMap sort; + double size; + SortAndSize(IndexIndexMap&& sort, double size) + : sort(std::move(sort)), size(size) {} + }; + std::vector options; + auto addOption = [&](const IndexCountMap& customCounts) { + // Compute the sort using custom counts that guide us how to order. + auto sort = doSort(customCounts, deps, module); + // Compute the size using the true counts. + auto size = computeSize(sort, counts); + options.emplace_back(std::move(sort), size); + }; - // The dependencies are the globals referred to. - for (auto& global : wasm.globals) { - if (global->imported()) { - continue; - } - std::vector vec; - for (auto* get : FindAll(global->init).list) { - vec.push_back(get->name); - } - sort(vec); - deps[global->name] = std::move(vec); + // Compute the closest thing we can to the original, unoptimized sort, by + // setting all counts to 0 there, so it only takes into account dependencies + // and the original ordering and nothing else. + // + // We put this sort first because if they all end up with equal size we + // prefer it (as it avoids pointless changes). + IndexCountMap zeroes(globals.size()); + addOption(zeroes); + + // A simple sort that uses the counts. As the algorithm in doSort() is + // greedy (see below), this is a pure greedy sort (at each point it time it + // picks the global with the highest count that it can). + addOption(counts); + + // We can make the sort less greedy by adding to each global's count some of + // the count of its children. Then we'd still be picking in a greedy manner + // but our choices would be influenced by the bigger picture of what can be + // unlocked by emitting a particular global (it may have a low count itself, + // but allow emitting something that depends on it that has a high count). + // We try two variations of this, one which is a simple sum (add the + // dependent's counts to the global's) and one which exponentially decreases + // them (that is, we add a small multiple of the dependent's counts, which + // may help as the dependents also depend on other things potentially, so a + // simple sum may be too naive). + double const EXPONENTIAL_FACTOR = 0.095; + IndexCountMap sumCounts(globals.size()), exponentialCounts(globals.size()); + + struct Sort : public TopologicalSort { + const Dependencies& deps; + + Sort(Index numGlobals, const Dependencies& deps) : deps(deps) { + for (Index i = 0; i < numGlobals; i++) { + push(i); } } - void pushPredecessors(Name global) { - for (auto pred : deps[global]) { - push(pred); + void pushPredecessors(Index global) { + auto iter = deps.dependedUpon.find(global); + if (iter == deps.dependedUpon.end()) { + return; + } + for (auto dep : iter->second) { + push(dep); } } - }; + } sort(globals.size(), deps); - std::unordered_map sortedIndexes; - for (auto global : DependencySort(*module, counts)) { - auto index = sortedIndexes.size(); - sortedIndexes[global] = index; + for (auto global : sort) { + // We can compute this global's count as in the sorted order all the + // values it cares about are resolved. Start with the self-count, then + // add the deps. + sumCounts[global] = exponentialCounts[global] = counts[global]; + for (auto dep : deps.dependedUpon[global]) { + sumCounts[global] += sumCounts[dep]; + exponentialCounts[global] += + EXPONENTIAL_FACTOR * exponentialCounts[dep]; + } } - std::sort( - module->globals.begin(), - module->globals.end(), - [&](const std::unique_ptr& a, const std::unique_ptr& b) { - return sortedIndexes[a->name] < sortedIndexes[b->name]; - }); + addOption(sumCounts); + addOption(exponentialCounts); + // Pick the best out of all the options we computed. + IndexIndexMap* best = nullptr; + double bestSize; + for (auto& [sort, size] : options) { + if (!best || size < bestSize) { + best = &sort; + bestSize = size; + } + } + + // Apply the indices we computed. + std::vector> old(std::move(globals)); + globals.resize(old.size()); + for (Index i = 0; i < old.size(); i++) { + globals[(*best)[i]] = std::move(old[i]); + } module->updateMaps(); } + + IndexIndexMap doSort(const IndexCountMap& counts, + const Dependencies& originalDeps, + Module* module) { + auto& globals = module->globals; + + // Copy the deps as we will operate on them as we go. + auto deps = originalDeps; + + // To sort the globals we do a simple greedy approach of always picking the + // global with the highest count at every point in time, subject to the + // constraint that we can only emit globals that have all of their + // dependencies already emitted. To do so we keep a list of the "available" + // globals, which are those with no remaining dependencies. Then by keeping + // the list of available globals in heap form we can simply pop the largest + // from the heap each time, and add new available ones as they become so. + // + // Other approaches here could be to do a topological sort, but the optimal + // order may not require strict ordering by topological depth, e.g.: + /* + // $c - $a + // / + // $e + // \ + // $d - $b + */ + // Here $e depends on $c and $d, $c depends on $a, and $d on $b. This is a + // partial order, as $d can be before or after $a, for example. As a result, + // if we sorted topologically by sub-trees here then we'd keep $c and $a + // together, and $d and $b, but a better order might interleave them. A good + // order also may not keep topological depths separated, e.g. we may want to + // put $a in between $c and $d despite it having a greater depth. + // + // The greedy approach here may also be unoptimal, however. Consider that we + // might see that the best available global is $a, but if we popped $b + // instead that could unlock $c which depends on $b, and $c may have a much + // higher use count than $a. For that reason we try several variations of + // this with different counts, see earlier. + std::vector availableHeap; + + // Comparison function. Given a and b, returns if a should be before b. This + // is used in a heap, where "highest" means "popped first", so see the notes + // below on how we order. + auto cmp = [&](Index a, Index b) { + // Imports always go first. The binary writer takes care of this itself + // anyhow, but it is better to do it here in the IR so we can actually + // see what the final layout will be. + auto aImported = globals[a]->imported(); + auto bImported = globals[b]->imported(); + // The highest items will be popped first off the heap, so we want imports + // to be at higher indexes, that is, + // + // unimported, unimported, imported, imported. + // + // Then the imports are popped first. + if (aImported != bImported) { + return bImported; + } + + // Sort by the counts. We want higher counts at higher indexes so they are + // popped first, that is, + // + // 10, 20, 30, 40 + // + auto aCount = counts[a]; + auto bCount = counts[b]; + if (aCount != bCount) { + return aCount < bCount; + } + + // Break ties using the original order, which means just using the + // indices we have. We need lower indexes at the top so they are popped + // first, that is, + // + // 3, 2, 1, 0 + // + return a > b; + }; + + // Push an item that just became available to the available heap. + auto push = [&](Index global) { + availableHeap.push_back(global); + std::push_heap(availableHeap.begin(), availableHeap.end(), cmp); + }; + + // The initially available globals are those with no dependencies. + for (Index i = 0; i < globals.size(); i++) { + if (deps.dependsOn[i].empty()) { + push(i); + } + } + + // Pop off the heap: Emit the global and its final, sorted index. Keep + // doing that until we finish processing all the globals. + IndexIndexMap sortedindices(globals.size()); + Index numSortedindices = 0; + while (!availableHeap.empty()) { + std::pop_heap(availableHeap.begin(), availableHeap.end(), cmp); + auto global = availableHeap.back(); + sortedindices[global] = numSortedindices++; + availableHeap.pop_back(); + + // Each time we pop we emit the global, which means anything that only + // depended on it becomes available to be popped as well. + for (auto other : deps.dependedUpon[global]) { + assert(deps.dependsOn[other].count(global)); + deps.dependsOn[other].erase(global); + if (deps.dependsOn[other].empty()) { + push(other); + } + } + } + + // All globals must have been handled. Cycles would prevent this, but they + // cannot exist in valid IR. + assert(numSortedindices == globals.size()); + + return sortedindices; + } + + // Given an indexing of the globals and the counts of how many times each is + // used, estimate the size of relevant parts of the wasm binary (that is, of + // LEBs in global.gets). + double computeSize(IndexIndexMap& indices, IndexCountMap& counts) { + // |indices| maps each old index to its new position in the sort. We need + // the reverse map here, which at index 0 has the old index of the global + // that will be first, and so forth. + IndexIndexMap actualOrder(indices.size()); + for (Index i = 0; i < indices.size(); i++) { + // Each global has a unique index, so we only replace 0's here, and they + // must be in bounds. + assert(indices[i] < indices.size()); + assert(actualOrder[indices[i]] == 0); + + actualOrder[indices[i]] = i; + } + + if (always) { + // In this mode we gradually increase the cost of later globals, in an + // unrealistic but smooth manner. + double total = 0; + for (Index i = 0; i < actualOrder.size(); i++) { + // Multiply the count for this global by a smoothed LEB factor, which + // starts at 1 (for 1 byte) at index 0, and then increases linearly with + // i, so that after 128 globals we reach 2 (which is the true index at + // which the LEB size normally jumps from 1 to 2), and so forth. + total += counts[actualOrder[i]] * (1.0 + (i / 128.0)); + } + return total; + } + + // The total size we are computing. + double total = 0; + // Track the size in bits and the next index at which the size increases. At + // the first iteration we'll compute the size of the LEB for index 0, and so + // forth. + size_t sizeInBits = 0; + size_t nextSizeIncrease = 0; + for (Index i = 0; i < actualOrder.size(); i++) { + if (i == nextSizeIncrease) { + sizeInBits++; + // At the current size we have 7 * sizeInBits bits to use. For example, + // at index 0 the size is 1 and we'll compute 128 here, and indeed after + // emitting 128 globals (0,..,127) the 129th (at index 128) requires a + // larger LEB. + nextSizeIncrease = 1 << (7 * sizeInBits); + } + total += counts[actualOrder[i]] * sizeInBits; + } + return total; + } }; Pass* createReorderGlobalsPass() { return new ReorderGlobals(false); } diff --git a/test/lit/merge/names.wat b/test/lit/merge/names.wat index 4562af58bc3..c4e81464960 100644 --- a/test/lit/merge/names.wat +++ b/test/lit/merge/names.wat @@ -12,13 +12,13 @@ ;; CHECK: (type $4 (func (param (ref $u)))) - ;; CHECK: (global $global$0 i32 (i32.const 0)) + ;; CHECK: (global $glob0 i32 (i32.const 0)) - ;; CHECK: (global $glob2 i32 (i32.const 0)) + ;; CHECK: (global $global$1 i32 (i32.const 0)) - ;; CHECK: (global $global$2 i32 (i32.const 0)) + ;; CHECK: (global $glob2 i32 (i32.const 0)) - ;; CHECK: (global $glob0 i32 (i32.const 0)) + ;; CHECK: (global $global$3 i32 (i32.const 0)) ;; CHECK: (memory $mem0 0) @@ -54,7 +54,7 @@ ;; CHECK: (export "g0" (global $glob0)) - ;; CHECK: (export "g1" (global $global$2)) + ;; CHECK: (export "g1" (global $global$1)) ;; CHECK: (export "m0" (memory $mem0)) @@ -80,7 +80,7 @@ ;; CHECK: (export "g2" (global $glob2)) - ;; CHECK: (export "g3" (global $global$0)) + ;; CHECK: (export "g3" (global $global$3)) ;; CHECK: (export "tag2" (tag $tag2)) diff --git a/test/lit/merge/renamings.wat b/test/lit/merge/renamings.wat index 4d1c32c5af1..c6a22542ac5 100644 --- a/test/lit/merge/renamings.wat +++ b/test/lit/merge/renamings.wat @@ -23,21 +23,20 @@ ;; CHECK: (import "elsewhere" "some.tag" (tag $imported (param f64))) - ;; CHECK: (global $bar_2 i32 (i32.const 4)) - - ;; CHECK: (global $other i32 (i32.const 3)) - - ;; CHECK: (global $bar i32 (i32.const 2)) - ;; CHECK: (global $foo i32 (i32.const 1)) (global $foo i32 (i32.const 1)) ;; This global has a conflict in second.wat, and so second.wat's $bar ;; will be renamed. + ;; CHECK: (global $bar i32 (i32.const 2)) (global $bar i32 (i32.const 2)) ;; This memory has a conflict in second.wat, and so second.wat's $foo ;; will be renamed. + ;; CHECK: (global $other i32 (i32.const 3)) + + ;; CHECK: (global $bar_2 i32 (i32.const 4)) + ;; CHECK: (memory $foo 10 20) (memory $foo 10 20) diff --git a/test/lit/passes/j2cl.wast b/test/lit/passes/j2cl.wast index 1963203a88b..b8081d8b22c 100644 --- a/test/lit/passes/j2cl.wast +++ b/test/lit/passes/j2cl.wast @@ -6,10 +6,9 @@ (module ;; CHECK: (type $0 (func)) - ;; CHECK: (global $field-f64@Foo f64 (f64.const 1)) - ;; CHECK: (global $field-i32@Foo i32 (i32.const 1)) (global $field-i32@Foo (mut i32) (i32.const 0)) + ;; CHECK: (global $field-f64@Foo f64 (f64.const 1)) (global $field-f64@Foo (mut f64) (f64.const 0)) ;; CHECK: (func $clinit__@Foo (type $0) @@ -29,20 +28,18 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (global $field2@Foo (mut anyref) (ref.null none)) - ;; CHECK: (global $referredField@Foo i32 (i32.const 42)) (global $referredField@Foo i32 (i32.const 42)) - ;; CHECK: (global $field1@Foo anyref (struct.new $A - ;; CHECK-NEXT: (global.get $referredField@Foo) - ;; CHECK-NEXT: )) - ;; CHECK: (global $referredFieldMut@Foo (mut i32) (i32.const 42)) (global $referredFieldMut@Foo (mut i32) (i32.const 42)) + ;; CHECK: (global $field1@Foo anyref (struct.new $A + ;; CHECK-NEXT: (global.get $referredField@Foo) + ;; CHECK-NEXT: )) (global $field1@Foo (mut anyref) (ref.null none)) + ;; CHECK: (global $field2@Foo (mut anyref) (ref.null none)) (global $field2@Foo (mut anyref) (ref.null none)) ;; CHECK: (global $field3@Foo anyref (global.get $field1@Foo)) @@ -78,11 +75,10 @@ (type $A (struct)) ;; CHECK: (type $1 (func)) - ;; CHECK: (global $field-any@Foo (mut anyref) (struct.new_default $A)) - ;; CHECK: (global $field-i32@Foo (mut i32) (i32.const 2)) (global $field-i32@Foo (mut i32) (i32.const 2)) + ;; CHECK: (global $field-any@Foo (mut anyref) (struct.new_default $A)) (global $field-any@Foo (mut anyref) (struct.new $A)) ;; CHECK: (func $clinit__@Foo (type $1) @@ -156,13 +152,11 @@ (module ;; CHECK: (type $0 (func (result i32))) - ;; CHECK: (global $$var3@Zoo i32 (i32.const 2)) - - ;; CHECK: (global $$var2@Zoo i32 (i32.const 2)) - ;; CHECK: (global $$var1@Zoo i32 (i32.const 2)) (global $$var1@Zoo (mut i32) (i32.const 0)) + ;; CHECK: (global $$var2@Zoo i32 (i32.const 2)) (global $$var2@Zoo (mut i32) (i32.const 0)) + ;; CHECK: (global $$var3@Zoo i32 (i32.const 2)) (global $$var3@Zoo (mut i32) (i32.const 0)) ;; CHECK: (func $getVar1__@Zoo (type $0) (result i32) @@ -211,10 +205,9 @@ ;; CHECK: (type $1 (func (result i32))) - ;; CHECK: (global $$var2@Zoo (mut i32) (i32.const 3)) - ;; CHECK: (global $$var1@Zoo (mut i32) (i32.const 2)) (global $$var1@Zoo (mut i32) (i32.const 2)) + ;; CHECK: (global $$var2@Zoo (mut i32) (i32.const 3)) (global $$var2@Zoo (mut i32) (i32.const 3)) diff --git a/test/lit/passes/reorder-globals-real.wast b/test/lit/passes/reorder-globals-real.wast new file mode 100644 index 00000000000..87ccc92c9e8 --- /dev/null +++ b/test/lit/passes/reorder-globals-real.wast @@ -0,0 +1,894 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; Similar to reorder-globals, but this runs the "real" version, without +;; "-always". That is, this tests the production code. The downside is we need +;; 128+ globals to see any changes here, so we keep most testing in the other +;; file. + +;; RUN: foreach %s %t wasm-opt -all --reorder-globals -S -o - | filecheck %s + +;; A situation where the simple greedy sort fails to be optimal. We have 129 +;; globals, enough for the LEB size to grow by 1 for the last. One global, +;; |other|, is independent of the rest. The second is in a chain with all the +;; others: +;; +;; global1 <- global2 <- .. <- global128 +;; +;; other has a higher count than global1, so if we are greedy we pick it. But +;; global128 has the highest count by far, so it is actually worth emitting the +;; entire chain first, and only then other, which is the original order. +(module + ;; CHECK: (global $global1 i32 (i32.const 1)) + (global $global1 i32 (i32.const 1)) + ;; CHECK: (global $global2 i32 (global.get $global1)) + (global $global2 i32 (global.get $global1)) + ;; CHECK: (global $global3 i32 (global.get $global2)) + (global $global3 i32 (global.get $global2)) + ;; CHECK: (global $global4 i32 (global.get $global3)) + (global $global4 i32 (global.get $global3)) + ;; CHECK: (global $global5 i32 (global.get $global4)) + (global $global5 i32 (global.get $global4)) + ;; CHECK: (global $global6 i32 (global.get $global5)) + (global $global6 i32 (global.get $global5)) + ;; CHECK: (global $global7 i32 (global.get $global6)) + (global $global7 i32 (global.get $global6)) + ;; CHECK: (global $global8 i32 (global.get $global7)) + (global $global8 i32 (global.get $global7)) + ;; CHECK: (global $global9 i32 (global.get $global8)) + (global $global9 i32 (global.get $global8)) + ;; CHECK: (global $global10 i32 (global.get $global9)) + (global $global10 i32 (global.get $global9)) + ;; CHECK: (global $global11 i32 (global.get $global10)) + (global $global11 i32 (global.get $global10)) + ;; CHECK: (global $global12 i32 (global.get $global11)) + (global $global12 i32 (global.get $global11)) + ;; CHECK: (global $global13 i32 (global.get $global12)) + (global $global13 i32 (global.get $global12)) + ;; CHECK: (global $global14 i32 (global.get $global13)) + (global $global14 i32 (global.get $global13)) + ;; CHECK: (global $global15 i32 (global.get $global14)) + (global $global15 i32 (global.get $global14)) + ;; CHECK: (global $global16 i32 (global.get $global15)) + (global $global16 i32 (global.get $global15)) + ;; CHECK: (global $global17 i32 (global.get $global16)) + (global $global17 i32 (global.get $global16)) + ;; CHECK: (global $global18 i32 (global.get $global17)) + (global $global18 i32 (global.get $global17)) + ;; CHECK: (global $global19 i32 (global.get $global18)) + (global $global19 i32 (global.get $global18)) + ;; CHECK: (global $global20 i32 (global.get $global19)) + (global $global20 i32 (global.get $global19)) + ;; CHECK: (global $global21 i32 (global.get $global20)) + (global $global21 i32 (global.get $global20)) + ;; CHECK: (global $global22 i32 (global.get $global21)) + (global $global22 i32 (global.get $global21)) + ;; CHECK: (global $global23 i32 (global.get $global22)) + (global $global23 i32 (global.get $global22)) + ;; CHECK: (global $global24 i32 (global.get $global23)) + (global $global24 i32 (global.get $global23)) + ;; CHECK: (global $global25 i32 (global.get $global24)) + (global $global25 i32 (global.get $global24)) + ;; CHECK: (global $global26 i32 (global.get $global25)) + (global $global26 i32 (global.get $global25)) + ;; CHECK: (global $global27 i32 (global.get $global26)) + (global $global27 i32 (global.get $global26)) + ;; CHECK: (global $global28 i32 (global.get $global27)) + (global $global28 i32 (global.get $global27)) + ;; CHECK: (global $global29 i32 (global.get $global28)) + (global $global29 i32 (global.get $global28)) + ;; CHECK: (global $global30 i32 (global.get $global29)) + (global $global30 i32 (global.get $global29)) + ;; CHECK: (global $global31 i32 (global.get $global30)) + (global $global31 i32 (global.get $global30)) + ;; CHECK: (global $global32 i32 (global.get $global31)) + (global $global32 i32 (global.get $global31)) + ;; CHECK: (global $global33 i32 (global.get $global32)) + (global $global33 i32 (global.get $global32)) + ;; CHECK: (global $global34 i32 (global.get $global33)) + (global $global34 i32 (global.get $global33)) + ;; CHECK: (global $global35 i32 (global.get $global34)) + (global $global35 i32 (global.get $global34)) + ;; CHECK: (global $global36 i32 (global.get $global35)) + (global $global36 i32 (global.get $global35)) + ;; CHECK: (global $global37 i32 (global.get $global36)) + (global $global37 i32 (global.get $global36)) + ;; CHECK: (global $global38 i32 (global.get $global37)) + (global $global38 i32 (global.get $global37)) + ;; CHECK: (global $global39 i32 (global.get $global38)) + (global $global39 i32 (global.get $global38)) + ;; CHECK: (global $global40 i32 (global.get $global39)) + (global $global40 i32 (global.get $global39)) + ;; CHECK: (global $global41 i32 (global.get $global40)) + (global $global41 i32 (global.get $global40)) + ;; CHECK: (global $global42 i32 (global.get $global41)) + (global $global42 i32 (global.get $global41)) + ;; CHECK: (global $global43 i32 (global.get $global42)) + (global $global43 i32 (global.get $global42)) + ;; CHECK: (global $global44 i32 (global.get $global43)) + (global $global44 i32 (global.get $global43)) + ;; CHECK: (global $global45 i32 (global.get $global44)) + (global $global45 i32 (global.get $global44)) + ;; CHECK: (global $global46 i32 (global.get $global45)) + (global $global46 i32 (global.get $global45)) + ;; CHECK: (global $global47 i32 (global.get $global46)) + (global $global47 i32 (global.get $global46)) + ;; CHECK: (global $global48 i32 (global.get $global47)) + (global $global48 i32 (global.get $global47)) + ;; CHECK: (global $global49 i32 (global.get $global48)) + (global $global49 i32 (global.get $global48)) + ;; CHECK: (global $global50 i32 (global.get $global49)) + (global $global50 i32 (global.get $global49)) + ;; CHECK: (global $global51 i32 (global.get $global50)) + (global $global51 i32 (global.get $global50)) + ;; CHECK: (global $global52 i32 (global.get $global51)) + (global $global52 i32 (global.get $global51)) + ;; CHECK: (global $global53 i32 (global.get $global52)) + (global $global53 i32 (global.get $global52)) + ;; CHECK: (global $global54 i32 (global.get $global53)) + (global $global54 i32 (global.get $global53)) + ;; CHECK: (global $global55 i32 (global.get $global54)) + (global $global55 i32 (global.get $global54)) + ;; CHECK: (global $global56 i32 (global.get $global55)) + (global $global56 i32 (global.get $global55)) + ;; CHECK: (global $global57 i32 (global.get $global56)) + (global $global57 i32 (global.get $global56)) + ;; CHECK: (global $global58 i32 (global.get $global57)) + (global $global58 i32 (global.get $global57)) + ;; CHECK: (global $global59 i32 (global.get $global58)) + (global $global59 i32 (global.get $global58)) + ;; CHECK: (global $global60 i32 (global.get $global59)) + (global $global60 i32 (global.get $global59)) + ;; CHECK: (global $global61 i32 (global.get $global60)) + (global $global61 i32 (global.get $global60)) + ;; CHECK: (global $global62 i32 (global.get $global61)) + (global $global62 i32 (global.get $global61)) + ;; CHECK: (global $global63 i32 (global.get $global62)) + (global $global63 i32 (global.get $global62)) + ;; CHECK: (global $global64 i32 (global.get $global63)) + (global $global64 i32 (global.get $global63)) + ;; CHECK: (global $global65 i32 (global.get $global64)) + (global $global65 i32 (global.get $global64)) + ;; CHECK: (global $global66 i32 (global.get $global65)) + (global $global66 i32 (global.get $global65)) + ;; CHECK: (global $global67 i32 (global.get $global66)) + (global $global67 i32 (global.get $global66)) + ;; CHECK: (global $global68 i32 (global.get $global67)) + (global $global68 i32 (global.get $global67)) + ;; CHECK: (global $global69 i32 (global.get $global68)) + (global $global69 i32 (global.get $global68)) + ;; CHECK: (global $global70 i32 (global.get $global69)) + (global $global70 i32 (global.get $global69)) + ;; CHECK: (global $global71 i32 (global.get $global70)) + (global $global71 i32 (global.get $global70)) + ;; CHECK: (global $global72 i32 (global.get $global71)) + (global $global72 i32 (global.get $global71)) + ;; CHECK: (global $global73 i32 (global.get $global72)) + (global $global73 i32 (global.get $global72)) + ;; CHECK: (global $global74 i32 (global.get $global73)) + (global $global74 i32 (global.get $global73)) + ;; CHECK: (global $global75 i32 (global.get $global74)) + (global $global75 i32 (global.get $global74)) + ;; CHECK: (global $global76 i32 (global.get $global75)) + (global $global76 i32 (global.get $global75)) + ;; CHECK: (global $global77 i32 (global.get $global76)) + (global $global77 i32 (global.get $global76)) + ;; CHECK: (global $global78 i32 (global.get $global77)) + (global $global78 i32 (global.get $global77)) + ;; CHECK: (global $global79 i32 (global.get $global78)) + (global $global79 i32 (global.get $global78)) + ;; CHECK: (global $global80 i32 (global.get $global79)) + (global $global80 i32 (global.get $global79)) + ;; CHECK: (global $global81 i32 (global.get $global80)) + (global $global81 i32 (global.get $global80)) + ;; CHECK: (global $global82 i32 (global.get $global81)) + (global $global82 i32 (global.get $global81)) + ;; CHECK: (global $global83 i32 (global.get $global82)) + (global $global83 i32 (global.get $global82)) + ;; CHECK: (global $global84 i32 (global.get $global83)) + (global $global84 i32 (global.get $global83)) + ;; CHECK: (global $global85 i32 (global.get $global84)) + (global $global85 i32 (global.get $global84)) + ;; CHECK: (global $global86 i32 (global.get $global85)) + (global $global86 i32 (global.get $global85)) + ;; CHECK: (global $global87 i32 (global.get $global86)) + (global $global87 i32 (global.get $global86)) + ;; CHECK: (global $global88 i32 (global.get $global87)) + (global $global88 i32 (global.get $global87)) + ;; CHECK: (global $global89 i32 (global.get $global88)) + (global $global89 i32 (global.get $global88)) + ;; CHECK: (global $global90 i32 (global.get $global89)) + (global $global90 i32 (global.get $global89)) + ;; CHECK: (global $global91 i32 (global.get $global90)) + (global $global91 i32 (global.get $global90)) + ;; CHECK: (global $global92 i32 (global.get $global91)) + (global $global92 i32 (global.get $global91)) + ;; CHECK: (global $global93 i32 (global.get $global92)) + (global $global93 i32 (global.get $global92)) + ;; CHECK: (global $global94 i32 (global.get $global93)) + (global $global94 i32 (global.get $global93)) + ;; CHECK: (global $global95 i32 (global.get $global94)) + (global $global95 i32 (global.get $global94)) + ;; CHECK: (global $global96 i32 (global.get $global95)) + (global $global96 i32 (global.get $global95)) + ;; CHECK: (global $global97 i32 (global.get $global96)) + (global $global97 i32 (global.get $global96)) + ;; CHECK: (global $global98 i32 (global.get $global97)) + (global $global98 i32 (global.get $global97)) + ;; CHECK: (global $global99 i32 (global.get $global98)) + (global $global99 i32 (global.get $global98)) + ;; CHECK: (global $global100 i32 (global.get $global99)) + (global $global100 i32 (global.get $global99)) + ;; CHECK: (global $global101 i32 (global.get $global100)) + (global $global101 i32 (global.get $global100)) + ;; CHECK: (global $global102 i32 (global.get $global101)) + (global $global102 i32 (global.get $global101)) + ;; CHECK: (global $global103 i32 (global.get $global102)) + (global $global103 i32 (global.get $global102)) + ;; CHECK: (global $global104 i32 (global.get $global103)) + (global $global104 i32 (global.get $global103)) + ;; CHECK: (global $global105 i32 (global.get $global104)) + (global $global105 i32 (global.get $global104)) + ;; CHECK: (global $global106 i32 (global.get $global105)) + (global $global106 i32 (global.get $global105)) + ;; CHECK: (global $global107 i32 (global.get $global106)) + (global $global107 i32 (global.get $global106)) + ;; CHECK: (global $global108 i32 (global.get $global107)) + (global $global108 i32 (global.get $global107)) + ;; CHECK: (global $global109 i32 (global.get $global108)) + (global $global109 i32 (global.get $global108)) + ;; CHECK: (global $global110 i32 (global.get $global109)) + (global $global110 i32 (global.get $global109)) + ;; CHECK: (global $global111 i32 (global.get $global110)) + (global $global111 i32 (global.get $global110)) + ;; CHECK: (global $global112 i32 (global.get $global111)) + (global $global112 i32 (global.get $global111)) + ;; CHECK: (global $global113 i32 (global.get $global112)) + (global $global113 i32 (global.get $global112)) + ;; CHECK: (global $global114 i32 (global.get $global113)) + (global $global114 i32 (global.get $global113)) + ;; CHECK: (global $global115 i32 (global.get $global114)) + (global $global115 i32 (global.get $global114)) + ;; CHECK: (global $global116 i32 (global.get $global115)) + (global $global116 i32 (global.get $global115)) + ;; CHECK: (global $global117 i32 (global.get $global116)) + (global $global117 i32 (global.get $global116)) + ;; CHECK: (global $global118 i32 (global.get $global117)) + (global $global118 i32 (global.get $global117)) + ;; CHECK: (global $global119 i32 (global.get $global118)) + (global $global119 i32 (global.get $global118)) + ;; CHECK: (global $global120 i32 (global.get $global119)) + (global $global120 i32 (global.get $global119)) + ;; CHECK: (global $global121 i32 (global.get $global120)) + (global $global121 i32 (global.get $global120)) + ;; CHECK: (global $global122 i32 (global.get $global121)) + (global $global122 i32 (global.get $global121)) + ;; CHECK: (global $global123 i32 (global.get $global122)) + (global $global123 i32 (global.get $global122)) + ;; CHECK: (global $global124 i32 (global.get $global123)) + (global $global124 i32 (global.get $global123)) + ;; CHECK: (global $global125 i32 (global.get $global124)) + (global $global125 i32 (global.get $global124)) + ;; CHECK: (global $global126 i32 (global.get $global125)) + (global $global126 i32 (global.get $global125)) + ;; CHECK: (global $global127 i32 (global.get $global126)) + (global $global127 i32 (global.get $global126)) + ;; CHECK: (global $global128 i32 (global.get $global127)) + (global $global128 i32 (global.get $global127)) + + ;; CHECK: (global $other i32 (i32.const 0)) + (global $other i32 (i32.const 0)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $global128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + ;; Aside from the uses in the globals themselves (which means one use for + ;; each of global1..global127), we add two uses of other, to make it + ;; have a higher count than global1, and 10 uses of global128, to make it + ;; have the highest count by far. + (drop (global.get $other)) + (drop (global.get $other)) + + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + (drop (global.get $global128)) + ) +) + +;; As above, but now the greedy sort is optimal. We remove all uses of +;; $global128, so $other has the highest count and there is no other factor that +;; matters here, so emitting $other first is best. +(module + ;; CHECK: (global $other i32 (i32.const 0)) + + ;; CHECK: (global $global1 i32 (i32.const 1)) + (global $global1 i32 (i32.const 1)) + ;; CHECK: (global $global2 i32 (global.get $global1)) + (global $global2 i32 (global.get $global1)) + ;; CHECK: (global $global3 i32 (global.get $global2)) + (global $global3 i32 (global.get $global2)) + ;; CHECK: (global $global4 i32 (global.get $global3)) + (global $global4 i32 (global.get $global3)) + ;; CHECK: (global $global5 i32 (global.get $global4)) + (global $global5 i32 (global.get $global4)) + ;; CHECK: (global $global6 i32 (global.get $global5)) + (global $global6 i32 (global.get $global5)) + ;; CHECK: (global $global7 i32 (global.get $global6)) + (global $global7 i32 (global.get $global6)) + ;; CHECK: (global $global8 i32 (global.get $global7)) + (global $global8 i32 (global.get $global7)) + ;; CHECK: (global $global9 i32 (global.get $global8)) + (global $global9 i32 (global.get $global8)) + ;; CHECK: (global $global10 i32 (global.get $global9)) + (global $global10 i32 (global.get $global9)) + ;; CHECK: (global $global11 i32 (global.get $global10)) + (global $global11 i32 (global.get $global10)) + ;; CHECK: (global $global12 i32 (global.get $global11)) + (global $global12 i32 (global.get $global11)) + ;; CHECK: (global $global13 i32 (global.get $global12)) + (global $global13 i32 (global.get $global12)) + ;; CHECK: (global $global14 i32 (global.get $global13)) + (global $global14 i32 (global.get $global13)) + ;; CHECK: (global $global15 i32 (global.get $global14)) + (global $global15 i32 (global.get $global14)) + ;; CHECK: (global $global16 i32 (global.get $global15)) + (global $global16 i32 (global.get $global15)) + ;; CHECK: (global $global17 i32 (global.get $global16)) + (global $global17 i32 (global.get $global16)) + ;; CHECK: (global $global18 i32 (global.get $global17)) + (global $global18 i32 (global.get $global17)) + ;; CHECK: (global $global19 i32 (global.get $global18)) + (global $global19 i32 (global.get $global18)) + ;; CHECK: (global $global20 i32 (global.get $global19)) + (global $global20 i32 (global.get $global19)) + ;; CHECK: (global $global21 i32 (global.get $global20)) + (global $global21 i32 (global.get $global20)) + ;; CHECK: (global $global22 i32 (global.get $global21)) + (global $global22 i32 (global.get $global21)) + ;; CHECK: (global $global23 i32 (global.get $global22)) + (global $global23 i32 (global.get $global22)) + ;; CHECK: (global $global24 i32 (global.get $global23)) + (global $global24 i32 (global.get $global23)) + ;; CHECK: (global $global25 i32 (global.get $global24)) + (global $global25 i32 (global.get $global24)) + ;; CHECK: (global $global26 i32 (global.get $global25)) + (global $global26 i32 (global.get $global25)) + ;; CHECK: (global $global27 i32 (global.get $global26)) + (global $global27 i32 (global.get $global26)) + ;; CHECK: (global $global28 i32 (global.get $global27)) + (global $global28 i32 (global.get $global27)) + ;; CHECK: (global $global29 i32 (global.get $global28)) + (global $global29 i32 (global.get $global28)) + ;; CHECK: (global $global30 i32 (global.get $global29)) + (global $global30 i32 (global.get $global29)) + ;; CHECK: (global $global31 i32 (global.get $global30)) + (global $global31 i32 (global.get $global30)) + ;; CHECK: (global $global32 i32 (global.get $global31)) + (global $global32 i32 (global.get $global31)) + ;; CHECK: (global $global33 i32 (global.get $global32)) + (global $global33 i32 (global.get $global32)) + ;; CHECK: (global $global34 i32 (global.get $global33)) + (global $global34 i32 (global.get $global33)) + ;; CHECK: (global $global35 i32 (global.get $global34)) + (global $global35 i32 (global.get $global34)) + ;; CHECK: (global $global36 i32 (global.get $global35)) + (global $global36 i32 (global.get $global35)) + ;; CHECK: (global $global37 i32 (global.get $global36)) + (global $global37 i32 (global.get $global36)) + ;; CHECK: (global $global38 i32 (global.get $global37)) + (global $global38 i32 (global.get $global37)) + ;; CHECK: (global $global39 i32 (global.get $global38)) + (global $global39 i32 (global.get $global38)) + ;; CHECK: (global $global40 i32 (global.get $global39)) + (global $global40 i32 (global.get $global39)) + ;; CHECK: (global $global41 i32 (global.get $global40)) + (global $global41 i32 (global.get $global40)) + ;; CHECK: (global $global42 i32 (global.get $global41)) + (global $global42 i32 (global.get $global41)) + ;; CHECK: (global $global43 i32 (global.get $global42)) + (global $global43 i32 (global.get $global42)) + ;; CHECK: (global $global44 i32 (global.get $global43)) + (global $global44 i32 (global.get $global43)) + ;; CHECK: (global $global45 i32 (global.get $global44)) + (global $global45 i32 (global.get $global44)) + ;; CHECK: (global $global46 i32 (global.get $global45)) + (global $global46 i32 (global.get $global45)) + ;; CHECK: (global $global47 i32 (global.get $global46)) + (global $global47 i32 (global.get $global46)) + ;; CHECK: (global $global48 i32 (global.get $global47)) + (global $global48 i32 (global.get $global47)) + ;; CHECK: (global $global49 i32 (global.get $global48)) + (global $global49 i32 (global.get $global48)) + ;; CHECK: (global $global50 i32 (global.get $global49)) + (global $global50 i32 (global.get $global49)) + ;; CHECK: (global $global51 i32 (global.get $global50)) + (global $global51 i32 (global.get $global50)) + ;; CHECK: (global $global52 i32 (global.get $global51)) + (global $global52 i32 (global.get $global51)) + ;; CHECK: (global $global53 i32 (global.get $global52)) + (global $global53 i32 (global.get $global52)) + ;; CHECK: (global $global54 i32 (global.get $global53)) + (global $global54 i32 (global.get $global53)) + ;; CHECK: (global $global55 i32 (global.get $global54)) + (global $global55 i32 (global.get $global54)) + ;; CHECK: (global $global56 i32 (global.get $global55)) + (global $global56 i32 (global.get $global55)) + ;; CHECK: (global $global57 i32 (global.get $global56)) + (global $global57 i32 (global.get $global56)) + ;; CHECK: (global $global58 i32 (global.get $global57)) + (global $global58 i32 (global.get $global57)) + ;; CHECK: (global $global59 i32 (global.get $global58)) + (global $global59 i32 (global.get $global58)) + ;; CHECK: (global $global60 i32 (global.get $global59)) + (global $global60 i32 (global.get $global59)) + ;; CHECK: (global $global61 i32 (global.get $global60)) + (global $global61 i32 (global.get $global60)) + ;; CHECK: (global $global62 i32 (global.get $global61)) + (global $global62 i32 (global.get $global61)) + ;; CHECK: (global $global63 i32 (global.get $global62)) + (global $global63 i32 (global.get $global62)) + ;; CHECK: (global $global64 i32 (global.get $global63)) + (global $global64 i32 (global.get $global63)) + ;; CHECK: (global $global65 i32 (global.get $global64)) + (global $global65 i32 (global.get $global64)) + ;; CHECK: (global $global66 i32 (global.get $global65)) + (global $global66 i32 (global.get $global65)) + ;; CHECK: (global $global67 i32 (global.get $global66)) + (global $global67 i32 (global.get $global66)) + ;; CHECK: (global $global68 i32 (global.get $global67)) + (global $global68 i32 (global.get $global67)) + ;; CHECK: (global $global69 i32 (global.get $global68)) + (global $global69 i32 (global.get $global68)) + ;; CHECK: (global $global70 i32 (global.get $global69)) + (global $global70 i32 (global.get $global69)) + ;; CHECK: (global $global71 i32 (global.get $global70)) + (global $global71 i32 (global.get $global70)) + ;; CHECK: (global $global72 i32 (global.get $global71)) + (global $global72 i32 (global.get $global71)) + ;; CHECK: (global $global73 i32 (global.get $global72)) + (global $global73 i32 (global.get $global72)) + ;; CHECK: (global $global74 i32 (global.get $global73)) + (global $global74 i32 (global.get $global73)) + ;; CHECK: (global $global75 i32 (global.get $global74)) + (global $global75 i32 (global.get $global74)) + ;; CHECK: (global $global76 i32 (global.get $global75)) + (global $global76 i32 (global.get $global75)) + ;; CHECK: (global $global77 i32 (global.get $global76)) + (global $global77 i32 (global.get $global76)) + ;; CHECK: (global $global78 i32 (global.get $global77)) + (global $global78 i32 (global.get $global77)) + ;; CHECK: (global $global79 i32 (global.get $global78)) + (global $global79 i32 (global.get $global78)) + ;; CHECK: (global $global80 i32 (global.get $global79)) + (global $global80 i32 (global.get $global79)) + ;; CHECK: (global $global81 i32 (global.get $global80)) + (global $global81 i32 (global.get $global80)) + ;; CHECK: (global $global82 i32 (global.get $global81)) + (global $global82 i32 (global.get $global81)) + ;; CHECK: (global $global83 i32 (global.get $global82)) + (global $global83 i32 (global.get $global82)) + ;; CHECK: (global $global84 i32 (global.get $global83)) + (global $global84 i32 (global.get $global83)) + ;; CHECK: (global $global85 i32 (global.get $global84)) + (global $global85 i32 (global.get $global84)) + ;; CHECK: (global $global86 i32 (global.get $global85)) + (global $global86 i32 (global.get $global85)) + ;; CHECK: (global $global87 i32 (global.get $global86)) + (global $global87 i32 (global.get $global86)) + ;; CHECK: (global $global88 i32 (global.get $global87)) + (global $global88 i32 (global.get $global87)) + ;; CHECK: (global $global89 i32 (global.get $global88)) + (global $global89 i32 (global.get $global88)) + ;; CHECK: (global $global90 i32 (global.get $global89)) + (global $global90 i32 (global.get $global89)) + ;; CHECK: (global $global91 i32 (global.get $global90)) + (global $global91 i32 (global.get $global90)) + ;; CHECK: (global $global92 i32 (global.get $global91)) + (global $global92 i32 (global.get $global91)) + ;; CHECK: (global $global93 i32 (global.get $global92)) + (global $global93 i32 (global.get $global92)) + ;; CHECK: (global $global94 i32 (global.get $global93)) + (global $global94 i32 (global.get $global93)) + ;; CHECK: (global $global95 i32 (global.get $global94)) + (global $global95 i32 (global.get $global94)) + ;; CHECK: (global $global96 i32 (global.get $global95)) + (global $global96 i32 (global.get $global95)) + ;; CHECK: (global $global97 i32 (global.get $global96)) + (global $global97 i32 (global.get $global96)) + ;; CHECK: (global $global98 i32 (global.get $global97)) + (global $global98 i32 (global.get $global97)) + ;; CHECK: (global $global99 i32 (global.get $global98)) + (global $global99 i32 (global.get $global98)) + ;; CHECK: (global $global100 i32 (global.get $global99)) + (global $global100 i32 (global.get $global99)) + ;; CHECK: (global $global101 i32 (global.get $global100)) + (global $global101 i32 (global.get $global100)) + ;; CHECK: (global $global102 i32 (global.get $global101)) + (global $global102 i32 (global.get $global101)) + ;; CHECK: (global $global103 i32 (global.get $global102)) + (global $global103 i32 (global.get $global102)) + ;; CHECK: (global $global104 i32 (global.get $global103)) + (global $global104 i32 (global.get $global103)) + ;; CHECK: (global $global105 i32 (global.get $global104)) + (global $global105 i32 (global.get $global104)) + ;; CHECK: (global $global106 i32 (global.get $global105)) + (global $global106 i32 (global.get $global105)) + ;; CHECK: (global $global107 i32 (global.get $global106)) + (global $global107 i32 (global.get $global106)) + ;; CHECK: (global $global108 i32 (global.get $global107)) + (global $global108 i32 (global.get $global107)) + ;; CHECK: (global $global109 i32 (global.get $global108)) + (global $global109 i32 (global.get $global108)) + ;; CHECK: (global $global110 i32 (global.get $global109)) + (global $global110 i32 (global.get $global109)) + ;; CHECK: (global $global111 i32 (global.get $global110)) + (global $global111 i32 (global.get $global110)) + ;; CHECK: (global $global112 i32 (global.get $global111)) + (global $global112 i32 (global.get $global111)) + ;; CHECK: (global $global113 i32 (global.get $global112)) + (global $global113 i32 (global.get $global112)) + ;; CHECK: (global $global114 i32 (global.get $global113)) + (global $global114 i32 (global.get $global113)) + ;; CHECK: (global $global115 i32 (global.get $global114)) + (global $global115 i32 (global.get $global114)) + ;; CHECK: (global $global116 i32 (global.get $global115)) + (global $global116 i32 (global.get $global115)) + ;; CHECK: (global $global117 i32 (global.get $global116)) + (global $global117 i32 (global.get $global116)) + ;; CHECK: (global $global118 i32 (global.get $global117)) + (global $global118 i32 (global.get $global117)) + ;; CHECK: (global $global119 i32 (global.get $global118)) + (global $global119 i32 (global.get $global118)) + ;; CHECK: (global $global120 i32 (global.get $global119)) + (global $global120 i32 (global.get $global119)) + ;; CHECK: (global $global121 i32 (global.get $global120)) + (global $global121 i32 (global.get $global120)) + ;; CHECK: (global $global122 i32 (global.get $global121)) + (global $global122 i32 (global.get $global121)) + ;; CHECK: (global $global123 i32 (global.get $global122)) + (global $global123 i32 (global.get $global122)) + ;; CHECK: (global $global124 i32 (global.get $global123)) + (global $global124 i32 (global.get $global123)) + ;; CHECK: (global $global125 i32 (global.get $global124)) + (global $global125 i32 (global.get $global124)) + ;; CHECK: (global $global126 i32 (global.get $global125)) + (global $global126 i32 (global.get $global125)) + ;; CHECK: (global $global127 i32 (global.get $global126)) + (global $global127 i32 (global.get $global126)) + ;; CHECK: (global $global128 i32 (global.get $global127)) + (global $global128 i32 (global.get $global127)) + + (global $other i32 (i32.const 0)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop (global.get $other)) + (drop (global.get $other)) + ) +) + +;; As the last testcase, but one global fewer. As a result we only need a single +;; LEB byte for them all, and we do not bother changing the sort here. +(module + ;; CHECK: (global $global1 i32 (i32.const 1)) + (global $global1 i32 (i32.const 1)) + ;; CHECK: (global $global2 i32 (global.get $global1)) + (global $global2 i32 (global.get $global1)) + ;; CHECK: (global $global3 i32 (global.get $global2)) + (global $global3 i32 (global.get $global2)) + ;; CHECK: (global $global4 i32 (global.get $global3)) + (global $global4 i32 (global.get $global3)) + ;; CHECK: (global $global5 i32 (global.get $global4)) + (global $global5 i32 (global.get $global4)) + ;; CHECK: (global $global6 i32 (global.get $global5)) + (global $global6 i32 (global.get $global5)) + ;; CHECK: (global $global7 i32 (global.get $global6)) + (global $global7 i32 (global.get $global6)) + ;; CHECK: (global $global8 i32 (global.get $global7)) + (global $global8 i32 (global.get $global7)) + ;; CHECK: (global $global9 i32 (global.get $global8)) + (global $global9 i32 (global.get $global8)) + ;; CHECK: (global $global10 i32 (global.get $global9)) + (global $global10 i32 (global.get $global9)) + ;; CHECK: (global $global11 i32 (global.get $global10)) + (global $global11 i32 (global.get $global10)) + ;; CHECK: (global $global12 i32 (global.get $global11)) + (global $global12 i32 (global.get $global11)) + ;; CHECK: (global $global13 i32 (global.get $global12)) + (global $global13 i32 (global.get $global12)) + ;; CHECK: (global $global14 i32 (global.get $global13)) + (global $global14 i32 (global.get $global13)) + ;; CHECK: (global $global15 i32 (global.get $global14)) + (global $global15 i32 (global.get $global14)) + ;; CHECK: (global $global16 i32 (global.get $global15)) + (global $global16 i32 (global.get $global15)) + ;; CHECK: (global $global17 i32 (global.get $global16)) + (global $global17 i32 (global.get $global16)) + ;; CHECK: (global $global18 i32 (global.get $global17)) + (global $global18 i32 (global.get $global17)) + ;; CHECK: (global $global19 i32 (global.get $global18)) + (global $global19 i32 (global.get $global18)) + ;; CHECK: (global $global20 i32 (global.get $global19)) + (global $global20 i32 (global.get $global19)) + ;; CHECK: (global $global21 i32 (global.get $global20)) + (global $global21 i32 (global.get $global20)) + ;; CHECK: (global $global22 i32 (global.get $global21)) + (global $global22 i32 (global.get $global21)) + ;; CHECK: (global $global23 i32 (global.get $global22)) + (global $global23 i32 (global.get $global22)) + ;; CHECK: (global $global24 i32 (global.get $global23)) + (global $global24 i32 (global.get $global23)) + ;; CHECK: (global $global25 i32 (global.get $global24)) + (global $global25 i32 (global.get $global24)) + ;; CHECK: (global $global26 i32 (global.get $global25)) + (global $global26 i32 (global.get $global25)) + ;; CHECK: (global $global27 i32 (global.get $global26)) + (global $global27 i32 (global.get $global26)) + ;; CHECK: (global $global28 i32 (global.get $global27)) + (global $global28 i32 (global.get $global27)) + ;; CHECK: (global $global29 i32 (global.get $global28)) + (global $global29 i32 (global.get $global28)) + ;; CHECK: (global $global30 i32 (global.get $global29)) + (global $global30 i32 (global.get $global29)) + ;; CHECK: (global $global31 i32 (global.get $global30)) + (global $global31 i32 (global.get $global30)) + ;; CHECK: (global $global32 i32 (global.get $global31)) + (global $global32 i32 (global.get $global31)) + ;; CHECK: (global $global33 i32 (global.get $global32)) + (global $global33 i32 (global.get $global32)) + ;; CHECK: (global $global34 i32 (global.get $global33)) + (global $global34 i32 (global.get $global33)) + ;; CHECK: (global $global35 i32 (global.get $global34)) + (global $global35 i32 (global.get $global34)) + ;; CHECK: (global $global36 i32 (global.get $global35)) + (global $global36 i32 (global.get $global35)) + ;; CHECK: (global $global37 i32 (global.get $global36)) + (global $global37 i32 (global.get $global36)) + ;; CHECK: (global $global38 i32 (global.get $global37)) + (global $global38 i32 (global.get $global37)) + ;; CHECK: (global $global39 i32 (global.get $global38)) + (global $global39 i32 (global.get $global38)) + ;; CHECK: (global $global40 i32 (global.get $global39)) + (global $global40 i32 (global.get $global39)) + ;; CHECK: (global $global41 i32 (global.get $global40)) + (global $global41 i32 (global.get $global40)) + ;; CHECK: (global $global42 i32 (global.get $global41)) + (global $global42 i32 (global.get $global41)) + ;; CHECK: (global $global43 i32 (global.get $global42)) + (global $global43 i32 (global.get $global42)) + ;; CHECK: (global $global44 i32 (global.get $global43)) + (global $global44 i32 (global.get $global43)) + ;; CHECK: (global $global45 i32 (global.get $global44)) + (global $global45 i32 (global.get $global44)) + ;; CHECK: (global $global46 i32 (global.get $global45)) + (global $global46 i32 (global.get $global45)) + ;; CHECK: (global $global47 i32 (global.get $global46)) + (global $global47 i32 (global.get $global46)) + ;; CHECK: (global $global48 i32 (global.get $global47)) + (global $global48 i32 (global.get $global47)) + ;; CHECK: (global $global49 i32 (global.get $global48)) + (global $global49 i32 (global.get $global48)) + ;; CHECK: (global $global50 i32 (global.get $global49)) + (global $global50 i32 (global.get $global49)) + ;; CHECK: (global $global51 i32 (global.get $global50)) + (global $global51 i32 (global.get $global50)) + ;; CHECK: (global $global52 i32 (global.get $global51)) + (global $global52 i32 (global.get $global51)) + ;; CHECK: (global $global53 i32 (global.get $global52)) + (global $global53 i32 (global.get $global52)) + ;; CHECK: (global $global54 i32 (global.get $global53)) + (global $global54 i32 (global.get $global53)) + ;; CHECK: (global $global55 i32 (global.get $global54)) + (global $global55 i32 (global.get $global54)) + ;; CHECK: (global $global56 i32 (global.get $global55)) + (global $global56 i32 (global.get $global55)) + ;; CHECK: (global $global57 i32 (global.get $global56)) + (global $global57 i32 (global.get $global56)) + ;; CHECK: (global $global58 i32 (global.get $global57)) + (global $global58 i32 (global.get $global57)) + ;; CHECK: (global $global59 i32 (global.get $global58)) + (global $global59 i32 (global.get $global58)) + ;; CHECK: (global $global60 i32 (global.get $global59)) + (global $global60 i32 (global.get $global59)) + ;; CHECK: (global $global61 i32 (global.get $global60)) + (global $global61 i32 (global.get $global60)) + ;; CHECK: (global $global62 i32 (global.get $global61)) + (global $global62 i32 (global.get $global61)) + ;; CHECK: (global $global63 i32 (global.get $global62)) + (global $global63 i32 (global.get $global62)) + ;; CHECK: (global $global64 i32 (global.get $global63)) + (global $global64 i32 (global.get $global63)) + ;; CHECK: (global $global65 i32 (global.get $global64)) + (global $global65 i32 (global.get $global64)) + ;; CHECK: (global $global66 i32 (global.get $global65)) + (global $global66 i32 (global.get $global65)) + ;; CHECK: (global $global67 i32 (global.get $global66)) + (global $global67 i32 (global.get $global66)) + ;; CHECK: (global $global68 i32 (global.get $global67)) + (global $global68 i32 (global.get $global67)) + ;; CHECK: (global $global69 i32 (global.get $global68)) + (global $global69 i32 (global.get $global68)) + ;; CHECK: (global $global70 i32 (global.get $global69)) + (global $global70 i32 (global.get $global69)) + ;; CHECK: (global $global71 i32 (global.get $global70)) + (global $global71 i32 (global.get $global70)) + ;; CHECK: (global $global72 i32 (global.get $global71)) + (global $global72 i32 (global.get $global71)) + ;; CHECK: (global $global73 i32 (global.get $global72)) + (global $global73 i32 (global.get $global72)) + ;; CHECK: (global $global74 i32 (global.get $global73)) + (global $global74 i32 (global.get $global73)) + ;; CHECK: (global $global75 i32 (global.get $global74)) + (global $global75 i32 (global.get $global74)) + ;; CHECK: (global $global76 i32 (global.get $global75)) + (global $global76 i32 (global.get $global75)) + ;; CHECK: (global $global77 i32 (global.get $global76)) + (global $global77 i32 (global.get $global76)) + ;; CHECK: (global $global78 i32 (global.get $global77)) + (global $global78 i32 (global.get $global77)) + ;; CHECK: (global $global79 i32 (global.get $global78)) + (global $global79 i32 (global.get $global78)) + ;; CHECK: (global $global80 i32 (global.get $global79)) + (global $global80 i32 (global.get $global79)) + ;; CHECK: (global $global81 i32 (global.get $global80)) + (global $global81 i32 (global.get $global80)) + ;; CHECK: (global $global82 i32 (global.get $global81)) + (global $global82 i32 (global.get $global81)) + ;; CHECK: (global $global83 i32 (global.get $global82)) + (global $global83 i32 (global.get $global82)) + ;; CHECK: (global $global84 i32 (global.get $global83)) + (global $global84 i32 (global.get $global83)) + ;; CHECK: (global $global85 i32 (global.get $global84)) + (global $global85 i32 (global.get $global84)) + ;; CHECK: (global $global86 i32 (global.get $global85)) + (global $global86 i32 (global.get $global85)) + ;; CHECK: (global $global87 i32 (global.get $global86)) + (global $global87 i32 (global.get $global86)) + ;; CHECK: (global $global88 i32 (global.get $global87)) + (global $global88 i32 (global.get $global87)) + ;; CHECK: (global $global89 i32 (global.get $global88)) + (global $global89 i32 (global.get $global88)) + ;; CHECK: (global $global90 i32 (global.get $global89)) + (global $global90 i32 (global.get $global89)) + ;; CHECK: (global $global91 i32 (global.get $global90)) + (global $global91 i32 (global.get $global90)) + ;; CHECK: (global $global92 i32 (global.get $global91)) + (global $global92 i32 (global.get $global91)) + ;; CHECK: (global $global93 i32 (global.get $global92)) + (global $global93 i32 (global.get $global92)) + ;; CHECK: (global $global94 i32 (global.get $global93)) + (global $global94 i32 (global.get $global93)) + ;; CHECK: (global $global95 i32 (global.get $global94)) + (global $global95 i32 (global.get $global94)) + ;; CHECK: (global $global96 i32 (global.get $global95)) + (global $global96 i32 (global.get $global95)) + ;; CHECK: (global $global97 i32 (global.get $global96)) + (global $global97 i32 (global.get $global96)) + ;; CHECK: (global $global98 i32 (global.get $global97)) + (global $global98 i32 (global.get $global97)) + ;; CHECK: (global $global99 i32 (global.get $global98)) + (global $global99 i32 (global.get $global98)) + ;; CHECK: (global $global100 i32 (global.get $global99)) + (global $global100 i32 (global.get $global99)) + ;; CHECK: (global $global101 i32 (global.get $global100)) + (global $global101 i32 (global.get $global100)) + ;; CHECK: (global $global102 i32 (global.get $global101)) + (global $global102 i32 (global.get $global101)) + ;; CHECK: (global $global103 i32 (global.get $global102)) + (global $global103 i32 (global.get $global102)) + ;; CHECK: (global $global104 i32 (global.get $global103)) + (global $global104 i32 (global.get $global103)) + ;; CHECK: (global $global105 i32 (global.get $global104)) + (global $global105 i32 (global.get $global104)) + ;; CHECK: (global $global106 i32 (global.get $global105)) + (global $global106 i32 (global.get $global105)) + ;; CHECK: (global $global107 i32 (global.get $global106)) + (global $global107 i32 (global.get $global106)) + ;; CHECK: (global $global108 i32 (global.get $global107)) + (global $global108 i32 (global.get $global107)) + ;; CHECK: (global $global109 i32 (global.get $global108)) + (global $global109 i32 (global.get $global108)) + ;; CHECK: (global $global110 i32 (global.get $global109)) + (global $global110 i32 (global.get $global109)) + ;; CHECK: (global $global111 i32 (global.get $global110)) + (global $global111 i32 (global.get $global110)) + ;; CHECK: (global $global112 i32 (global.get $global111)) + (global $global112 i32 (global.get $global111)) + ;; CHECK: (global $global113 i32 (global.get $global112)) + (global $global113 i32 (global.get $global112)) + ;; CHECK: (global $global114 i32 (global.get $global113)) + (global $global114 i32 (global.get $global113)) + ;; CHECK: (global $global115 i32 (global.get $global114)) + (global $global115 i32 (global.get $global114)) + ;; CHECK: (global $global116 i32 (global.get $global115)) + (global $global116 i32 (global.get $global115)) + ;; CHECK: (global $global117 i32 (global.get $global116)) + (global $global117 i32 (global.get $global116)) + ;; CHECK: (global $global118 i32 (global.get $global117)) + (global $global118 i32 (global.get $global117)) + ;; CHECK: (global $global119 i32 (global.get $global118)) + (global $global119 i32 (global.get $global118)) + ;; CHECK: (global $global120 i32 (global.get $global119)) + (global $global120 i32 (global.get $global119)) + ;; CHECK: (global $global121 i32 (global.get $global120)) + (global $global121 i32 (global.get $global120)) + ;; CHECK: (global $global122 i32 (global.get $global121)) + (global $global122 i32 (global.get $global121)) + ;; CHECK: (global $global123 i32 (global.get $global122)) + (global $global123 i32 (global.get $global122)) + ;; CHECK: (global $global124 i32 (global.get $global123)) + (global $global124 i32 (global.get $global123)) + ;; CHECK: (global $global125 i32 (global.get $global124)) + (global $global125 i32 (global.get $global124)) + ;; CHECK: (global $global126 i32 (global.get $global125)) + (global $global126 i32 (global.get $global125)) + ;; CHECK: (global $global127 i32 (global.get $global126)) + (global $global127 i32 (global.get $global126)) + + ;; $global128 was removed + + ;; CHECK: (global $other i32 (i32.const 0)) + (global $other i32 (i32.const 0)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop (global.get $other)) + (drop (global.get $other)) + ) +) diff --git a/test/lit/passes/reorder-globals.wast b/test/lit/passes/reorder-globals.wast index 6017f09ad41..542311d59d9 100644 --- a/test/lit/passes/reorder-globals.wast +++ b/test/lit/passes/reorder-globals.wast @@ -145,8 +145,6 @@ ;; As above, but without dependencies, so now $c is first and then $b. (module - - ;; CHECK: (global $c i32 (i32.const 30)) ;; CHECK: (global $b i32 (i32.const 20)) @@ -180,10 +178,10 @@ ) ) -;; As above, but a mixed case: $b depends on $a but $c has no dependencies. $c -;; can be first. +;; As above, but a mixed case: $b depends on $a but $c has no dependencies, and +;; the counts are $c with the most, followed by $b, and then $a. $c can be +;; first here, but $b must follow $a. (module - ;; CHECK: (global $c i32 (i32.const 30)) ;; CHECK: (global $a i32 (i32.const 10)) @@ -197,6 +195,12 @@ ;; CHECK-NEXT: (global.get $b) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (global.get $c) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -204,6 +208,10 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $uses + ;; ($a already has one use in the global $b) + (drop + (global.get $b) + ) (drop (global.get $b) ) @@ -213,27 +221,111 @@ (drop (global.get $c) ) + (drop + (global.get $c) + ) ) ) -;; Another mixed case, now with $c depending on $b. $b can be before $a. +;; As above, but with the counts adjusted: before we had $c, $b, $a from most to +;; least uses, and now $b, $c, $a. +;; +;; A greedy sort would do $c, $a, $b (as the first choice is between $c and $a, +;; and $c wins), but that leaves $b, the highest count, for the end. The +;; smoothed-out LEB costs (1 byte at the start, +1/128 each index later) are: +;; +;; $c $a $b +;; 1 * 2 + 129/128 * 1 + 130/128 * 3 = 775/128 +;; +;; The original sort is +;; +;; $a $b $c +;; 1 * 1 + 129/128 * 3 + 130/128 * 2 = 775/128 +;; +;; As they are equal we prefer the original order. (module + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + ;; CHECK: (global $c i32 (i32.const 30)) + (global $c i32 (i32.const 30)) + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop + (global.get $b) + ) + (drop + (global.get $b) + ) + (drop + (global.get $b) + ) + (drop + (global.get $c) + ) + (drop + (global.get $c) + ) + ) +) - ;; CHECK: (global $b i32 (i32.const 20)) - - ;; CHECK: (global $c i32 (global.get $b)) - +;; As above, but with the counts adjusted to $b, $a, $c. +(module ;; CHECK: (global $a i32 (i32.const 10)) (global $a i32 (i32.const 10)) - (global $b i32 (i32.const 20)) - (global $c i32 (global.get $b)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + ;; CHECK: (global $c i32 (i32.const 30)) + (global $c i32 (i32.const 30)) ;; CHECK: (func $uses (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (global.get $b) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop + (global.get $b) + ) + (drop + (global.get $b) + ) + ) +) + +;; As above, but with the counts adjusted to $c, $a, $b. +(module + ;; CHECK: (global $c i32 (i32.const 30)) + + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + (global $c i32 (i32.const 30)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (global.get $c) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -242,11 +334,63 @@ ;; CHECK-NEXT: ) (func $uses (drop - (global.get $b) + (global.get $c) ) (drop (global.get $c) ) + ) +) + +;; As above, but with the counts adjusted to $a, $b, $c. +(module + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + ;; CHECK: (global $c i32 (i32.const 30)) + (global $c i32 (i32.const 30)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $a) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop + (global.get $a) + ) + (drop + (global.get $b) + ) + ) +) + +;; As above, but with the counts adjusted to $a, $c, $b. +(module + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + ;; CHECK: (global $c i32 (i32.const 30)) + + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + (global $c i32 (i32.const 30)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $a) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + (drop + (global.get $a) + ) (drop (global.get $c) ) @@ -292,3 +436,380 @@ ) ) ) + +;; Lower letters have lower counts: $a has the least, and $e has the most. +;; +;; Dependency graph (left depends on right): +;; +;; $c - $a +;; / +;; $e +;; \ +;; $d - $b +;; +;; $e has the most uses, followed by $c and $d. $a and $b have a reverse +;; ordering from their dependers, so a naive topological sort will fail to +;; be optimal. There are multiple optimal orders however, including: +;; +;; $b, $a, $c, $d, $e +;; $b, $d, $a, $c, $e +;; +;; $b and $e must be at the edges, but there is no single way to sort the +;; others: the first sorting here puts $a before both $d (though $a has +;; lower count) while the second puts $d before $c. Our greedy algorithm +;; picks the second order here. +(module + ;; CHECK: (global $b i32 (i32.const 20)) + + ;; CHECK: (global $d i32 (global.get $b)) + + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + + (global $b i32 (i32.const 20)) + + ;; CHECK: (global $c i32 (global.get $a)) + (global $c i32 (global.get $a)) + + (global $d i32 (global.get $b)) + + ;; CHECK: (global $e i32 (i32.add + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: )) + (global $e i32 (i32.add + (global.get $c) + (global.get $d) + )) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + ;; $a, $b, $c, $d each have one already from the globals. Add more so that + ;; $a has the least, and $e has the most + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + + (drop (global.get $d)) + (drop (global.get $d)) + (drop (global.get $d)) + + (drop (global.get $c)) + (drop (global.get $c)) + + (drop (global.get $b)) + ) +) + +;; As above, but add a direct dep from $d to $a: +;; +;; $c - $a +;; / / +;; $e / <-- this was added +;; \ / +;; $d - $b +;; +;; This forces $a to appear before $d: the order goes from before, which was +;; $b, $d, $a, $c, $e +;; to +;; $b, $a, $d, $c, $e +(module + ;; CHECK: (global $b i32 (i32.const 20)) + + ;; CHECK: (global $a i32 (i32.const 10)) + (global $a i32 (i32.const 10)) + + (global $b i32 (i32.const 20)) + + ;; CHECK: (global $d i32 (i32.add + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: (global.get $a) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $c i32 (global.get $a)) + (global $c i32 (global.get $a)) + + (global $d i32 (i32.add + (global.get $b) + (global.get $a) ;; this was added + )) + + ;; CHECK: (global $e i32 (i32.add + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: )) + (global $e i32 (i32.add + (global.get $c) + (global.get $d) + )) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $d) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + ;; $b, $c, $d each have one already from the globals, and $a has two. Add + ;; more so that $a has the least, and $e has the most. + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + (drop (global.get $e)) + + (drop (global.get $d)) + (drop (global.get $d)) + (drop (global.get $d)) + (drop (global.get $d)) + + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + + (drop (global.get $b)) + (drop (global.get $b)) + ) +) + +;; A situation where the simple greedy sort fails to be optimal. We have a +;; chain and one more independent global +;; +;; a <- b <- c +;; +;; other +;; +;; The candidates for the first global emitted are a and other, as they have no +;; dependencies, and other has a higher count so greedy sorting would pick it. +;; however, c has the highest count by far, so it is worth being less greedy and +;; doing a just in order to be able to do b and then c, and to emit other last. +;; In other words, the original order is best. +(module + ;; CHECK: (global $a i32 (i32.const 0)) + (global $a i32 (i32.const 0)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + ;; CHECK: (global $c i32 (global.get $b)) + (global $c i32 (global.get $b)) + + ;; CHECK: (global $other i32 (i32.const 1)) + (global $other i32 (i32.const 1)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + ;; Ten uses for $c, far more than all the rest combined. + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + + ;; Two uses for other, which is more than $a's single use. + (drop (global.get $other)) + (drop (global.get $other)) + ) +) + +;; As above, but with the original order a little different. This is again a +;; case where the greedy sort is unoptimal (see above), but now also the +;; original sort is unoptimal as well, and instead we use the "sum" sort, which +;; counts the sum of the uses of a global and all the things it depends on and +;; uses that as the count for that global (which in effect means that we take +;; into consideration not only its own size but the entire size that it may +;; unlock, which happens to work well here). +;; +;; The only change in the input compared to the previous test is that $other +;; was moved up to between $b and $c. Sum sort works well here because the +;; first comparison is $a and $other, and sum takes into account $b and $c in +;; $a's favor, so it wins. Likewise $b and $c win against $other as well, so +;; the order is $a, $b, $c, $other which is optimal here. +(module + ;; CHECK: (global $a i32 (i32.const 0)) + (global $a i32 (i32.const 0)) + ;; CHECK: (global $b i32 (global.get $a)) + (global $b i32 (global.get $a)) + + ;; CHECK: (global $c i32 (global.get $b)) + + ;; CHECK: (global $other i32 (i32.const 1)) + (global $other i32 (i32.const 1)) + + (global $c i32 (global.get $b)) + + ;; CHECK: (func $uses (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (global.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $uses + ;; Ten uses for $c, far more than all the rest combined. + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + (drop (global.get $c)) + + ;; Two uses for other, which is more than $a's single use. + (drop (global.get $other)) + (drop (global.get $other)) + ) +) + From 1f2cd4f7b51c7afd6a6cafc4e48286e850bb36bd Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Fri, 31 May 2024 16:59:05 -0700 Subject: [PATCH 369/553] Make Emscripten CMake build more configurable (#6638) This makes several changes to make the Emscripten build more configurable and convenient for testing: 1) Remove ERROR_ON_WASM_CHANGES_AFTER_LINK from ENABLE_BIGINT: this makes the setting composable with optimized builds 2) Add EMSCRIPTEN_ENABLE_MEMORY64 to build with the memory64 option 3) Add EMSCRIPTEN_ENABLE_SINGLE_FILE to allow disabling the single-file build (to make it easier to analyze binary output) --- CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 07dc8d2819b..fef45bfca8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,9 +52,15 @@ option(BUILD_FOR_BROWSER "Build binaryen toolchain utilities for the browser" OF # Turn this on to use the Wasm EH feature instead of emscripten EH in the wasm/BinaryenJS builds option(EMSCRIPTEN_ENABLE_WASM_EH "Enable Wasm EH feature in emscripten build" OFF) +option(EMSCRIPTEN_ENABLE_WASM64 "Enable memory64 in emscripten build" OFF) + # Turn this on to use pthreads feature in the wasm/BinaryenJS builds option(EMSCRIPTEN_ENABLE_PTHREADS "Enable pthreads in emscripten build" OFF) +# Turn this off to generate a separate .wasm file instead of packaging it into the JS. +# This is useful for debugging, performance analysis, and other testing. +option(EMSCRIPTEN_ENABLE_SINGLE_FILE "Enable SINGLE_FILE mode in emscripten build" ON) + # For git users, attempt to generate a more useful version string if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) find_package(Git QUIET REQUIRED) @@ -329,7 +335,6 @@ if(EMSCRIPTEN) # does when run on wasm files. option(ENABLE_BIGINT "Enable wasm BigInt support" OFF) if(ENABLE_BIGINT) - add_link_flag("-sERROR_ON_WASM_CHANGES_AFTER_LINK") add_link_flag("-sWASM_BIGINT") endif() @@ -377,6 +382,10 @@ if(EMSCRIPTEN) endif() # in opt builds, LTO helps so much (>20%) it's worth slow compile times add_nondebug_compile_flag("-flto") + if(EMSCRIPTEN_ENABLE_WASM64) + add_compile_flag("-sMEMORY64 -Wno-experimental") + add_link_flag("-sMEMORY64") + endif() endif() # clang doesn't print colored diagnostics when invoked from Ninja @@ -477,7 +486,9 @@ if(EMSCRIPTEN) target_link_libraries(binaryen_wasm "-Wno-unused-command-line-argument") # Emit a single file for convenience of people using binaryen.js as a library, # so they only need to distribute a single file. - target_link_libraries(binaryen_wasm "-sSINGLE_FILE") + if(EMSCRIPTEN_ENABLE_SINGLE_FILE) + target_link_libraries(binaryen_wasm "-sSINGLE_FILE") + endif() target_link_libraries(binaryen_wasm "-sEXPORT_ES6") target_link_libraries(binaryen_wasm "-sEXPORTED_RUNTIME_METHODS=stringToUTF8OnStack,stringToAscii") target_link_libraries(binaryen_wasm "-sEXPORTED_FUNCTIONS=_malloc,_free") @@ -512,7 +523,9 @@ if(EMSCRIPTEN) target_link_libraries(binaryen_js "-sNODERAWFS=0") # Do not error on the repeated NODERAWFS argument target_link_libraries(binaryen_js "-Wno-unused-command-line-argument") - target_link_libraries(binaryen_js "-sSINGLE_FILE") + if(EMSCRIPTEN_ENABLE_SINGLE_FILE) + target_link_libraries(binaryen_js "-sSINGLE_FILE") + endif() target_link_libraries(binaryen_js "-sEXPORT_NAME=Binaryen") # Currently, js_of_ocaml can only process ES5 code if(JS_OF_OCAML) From 9347a223fcc1b6c297805b3c37fe1e7473158720 Mon Sep 17 00:00:00 2001 From: Rikito Taniguchi Date: Tue, 4 Jun 2024 04:42:02 +0900 Subject: [PATCH 370/553] Fix binary parser of declarative element segments (#6618) The parser was incorrectly handling the parsing of declarative element segments whose `init` is a `vec(expr)`. https://webassembly.github.io/spec/core/binary/modules.html#element-section Binry parser was simply reading a single `u32LEB` value for `init` instead of parsing a expression regardless `usesExpressions = true`. This commit updates the `WasmBinaryReader::readElementSegments` function to correctly parse the expressions for declarative element segments by calling `readExpression` instead of `getU32LEB` when `usesExpressions = true`. Resolves the parsing exception: "[parse exception: bad section size, started at ... not being equal to new position ...]" Related discussion: https://github.com/tanishiking/scala-wasm/issues/136 --- src/wasm/wasm-binary.cpp | 6 +++- .../binary/declarative-element-use-expr.test | 28 ++++++++++++++++++ .../declarative-element-use-expr.test.wasm | Bin 0 -> 59 bytes 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/lit/binary/declarative-element-use-expr.test create mode 100644 test/lit/binary/declarative-element-use-expr.test.wasm diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 805af189203..32dcc883aab 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3369,7 +3369,11 @@ void WasmBinaryReader::readElementSegments() { [[maybe_unused]] auto type = getU32LEB(); auto num = getU32LEB(); for (Index i = 0; i < num; i++) { - getU32LEB(); + if (usesExpressions) { + readExpression(); + } else { + getU32LEB(); + } } continue; } diff --git a/test/lit/binary/declarative-element-use-expr.test b/test/lit/binary/declarative-element-use-expr.test new file mode 100644 index 00000000000..aecdf9ebde9 --- /dev/null +++ b/test/lit/binary/declarative-element-use-expr.test @@ -0,0 +1,28 @@ +;; Verify a binary with declarative element segment whose init is vector of expr +;; can be parsed correctly. +;; The declarative-element-use-expr file contains this: +;; +;; (module +;; (type $0 (func)) +;; (func $0 (type 0) (block (ref.func 0) (drop))) +;; (elem $0 declare funcref (item ref.func 0)) +;; ) +;; +;; The wasm-opt output contains `(elem declare func 0)` instead of +;; `(elem declare funcref (item ref.func 0))` because the parser doesn't +;; preserve declarative segments. This is fine, as we test that the +;; binary parser can parse it correctly. + +;; RUN: wasm-opt -all %s.wasm -all --print | filecheck %s + +;; CHECK: (module +;; CHECK-NEXT: (type $0 (func)) +;; CHECK-NEXT: (elem declare func $0) +;; CHECK-NEXT: (func $0 (type $0) +;; CHECK-NEXT: (block $label$1 +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (ref.func $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) diff --git a/test/lit/binary/declarative-element-use-expr.test.wasm b/test/lit/binary/declarative-element-use-expr.test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..54ebc37d4524bc37d93fe0fd2b046e67cf1c677d GIT binary patch literal 59 zcmZQbEY4+QU|?WuX=rF*U`$|OU~U4l7&zO(GPL^3crTw;*o<^}+% CiVk`J literal 0 HcmV?d00001 From ea4d9e45e1b9a929a38fbca9a6c316b0b918b12e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 3 Jun 2024 14:19:50 -0700 Subject: [PATCH 371/553] Effects: Add missing combining logic for MayNotReturn (#6635) Without that logic we could end up dropping that particular effect. This actually made a test pass when it should not: the modified test here has a function with effects that are ok to remove, but it had a loop which adds MayNotReturn which we should actually not remove, so it was removed erroneously. To fix the test, add other effects there (local ones) that we can see are removable. Also add a function with a loop to test that we do not remove an infinite loop, which adds coverage for the fix here. --- src/ir/effects.h | 1 + test/lit/passes/global-effects-O.wast | 376 ++++++++++++++++++++------ 2 files changed, 296 insertions(+), 81 deletions(-) diff --git a/src/ir/effects.h b/src/ir/effects.h index 28de838506a..46138d03c0f 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -364,6 +364,7 @@ class EffectAnalyzer { isAtomic = isAtomic || other.isAtomic; throws_ = throws_ || other.throws_; danglingPop = danglingPop || other.danglingPop; + mayNotReturn = mayNotReturn || other.mayNotReturn; for (auto i : other.localsRead) { localsRead.insert(i); } diff --git a/test/lit/passes/global-effects-O.wast b/test/lit/passes/global-effects-O.wast index c7ba0678186..ef2cf62e06c 100644 --- a/test/lit/passes/global-effects-O.wast +++ b/test/lit/passes/global-effects-O.wast @@ -11,31 +11,38 @@ (module ;; CHECK_0: (type $0 (func)) - ;; CHECK_0: (type $1 (func (result i32))) + ;; CHECK_0: (type $1 (func (param i32) (result i32))) ;; CHECK_0: (export "main" (func $main)) ;; CHECK_1: (type $0 (func)) - ;; CHECK_1: (type $1 (func (result i32))) + ;; CHECK_1: (type $1 (func (param i32) (result i32))) ;; CHECK_1: (export "main" (func $main)) ;; CHECK_3: (type $0 (func)) - ;; CHECK_3: (type $1 (func (result i32))) + ;; CHECK_3: (type $1 (func (param i32) (result i32))) ;; CHECK_3: (export "main" (func $main)) ;; CHECK_s: (type $0 (func)) - ;; CHECK_s: (type $1 (func (result i32))) + ;; CHECK_s: (type $1 (func (param i32) (result i32))) ;; CHECK_s: (export "main" (func $main)) ;; CHECK_O: (type $0 (func)) - ;; CHECK_O: (type $1 (func (result i32))) + ;; CHECK_O: (type $1 (func (param i32) (result i32))) ;; CHECK_O: (export "main" (func $main)) (export "main" (func $main)) + ;; CHECK_0: (export "main-infinite" (func $main-infinite)) + ;; CHECK_1: (export "main-infinite" (func $main-infinite)) + ;; CHECK_3: (export "main-infinite" (func $main-infinite)) + ;; CHECK_s: (export "main-infinite" (func $main-infinite)) + ;; CHECK_O: (export "main-infinite" (func $main-infinite)) + (export "main-infinite" (func $main-infinite)) + ;; CHECK_0: (export "pointless-work" (func $pointless-work)) ;; CHECK_1: (export "pointless-work" (func $pointless-work)) ;; CHECK_3: (export "pointless-work" (func $pointless-work)) @@ -45,10 +52,14 @@ ;; CHECK_0: (func $main (type $0) ;; CHECK_0-NEXT: (if - ;; CHECK_0-NEXT: (call $pointless-work) + ;; CHECK_0-NEXT: (call $pointless-work + ;; CHECK_0-NEXT: (i32.const 0) + ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: (then ;; CHECK_0-NEXT: (drop - ;; CHECK_0-NEXT: (call $pointless-work) + ;; CHECK_0-NEXT: (call $pointless-work + ;; CHECK_0-NEXT: (i32.const 1) + ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: ) @@ -70,17 +81,248 @@ ;; effects we can see that it is pointless and remove this entire if (except ;; for -O0). (if - (call $pointless-work) + (call $pointless-work + (i32.const 0) + ) (then (drop - (call $pointless-work) + (call $pointless-work + (i32.const 1) + ) ) ) ) ) - ;; CHECK_0: (func $pointless-work (type $1) (result i32) - ;; CHECK_0-NEXT: (local $x i32) + ;; CHECK_0: (func $main-infinite (type $0) + ;; CHECK_0-NEXT: (if + ;; CHECK_0-NEXT: (call $infinite-work + ;; CHECK_0-NEXT: (i32.const 0) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (then + ;; CHECK_0-NEXT: (drop + ;; CHECK_0-NEXT: (call $infinite-work + ;; CHECK_0-NEXT: (i32.const 1) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_1: (func $main-infinite (type $0) + ;; CHECK_1-NEXT: (if + ;; CHECK_1-NEXT: (call $infinite-work + ;; CHECK_1-NEXT: (i32.const 0) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (then + ;; CHECK_1-NEXT: (drop + ;; CHECK_1-NEXT: (call $infinite-work + ;; CHECK_1-NEXT: (i32.const 1) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_3: (func $main-infinite (type $0) + ;; CHECK_3-NEXT: (if + ;; CHECK_3-NEXT: (call $infinite-work + ;; CHECK_3-NEXT: (i32.const 0) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (then + ;; CHECK_3-NEXT: (drop + ;; CHECK_3-NEXT: (call $infinite-work + ;; CHECK_3-NEXT: (i32.const 1) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_s: (func $main-infinite (type $0) + ;; CHECK_s-NEXT: (if + ;; CHECK_s-NEXT: (call $infinite-work + ;; CHECK_s-NEXT: (i32.const 0) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (then + ;; CHECK_s-NEXT: (drop + ;; CHECK_s-NEXT: (call $infinite-work + ;; CHECK_s-NEXT: (i32.const 1) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_O: (func $main-infinite (type $0) + ;; CHECK_O-NEXT: (if + ;; CHECK_O-NEXT: (call $infinite-work + ;; CHECK_O-NEXT: (i32.const 0) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (then + ;; CHECK_O-NEXT: (drop + ;; CHECK_O-NEXT: (call $infinite-work + ;; CHECK_O-NEXT: (i32.const 1) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + (func $main-infinite + ;; We cannot remove in this case as the pointless work may have an infinite + ;; loop, which we do not eliminate. + (if + (call $infinite-work + (i32.const 0) + ) + (then + (drop + (call $infinite-work + (i32.const 1) + ) + ) + ) + ) + ) + + ;; CHECK_0: (func $pointless-work (type $1) (param $x i32) (result i32) + ;; CHECK_0-NEXT: (local.set $x + ;; CHECK_0-NEXT: (i32.add + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: (i32.const 1) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (if + ;; CHECK_0-NEXT: (i32.ge_u + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: (i32.const 12345678) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (then + ;; CHECK_0-NEXT: (local.set $x + ;; CHECK_0-NEXT: (i32.add + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: (i32.const 1) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (return + ;; CHECK_0-NEXT: (local.get $x) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: ) + ;; CHECK_1: (func $pointless-work (type $1) (param $0 i32) (result i32) + ;; CHECK_1-NEXT: (if (result i32) + ;; CHECK_1-NEXT: (i32.ge_u + ;; CHECK_1-NEXT: (local.tee $0 + ;; CHECK_1-NEXT: (i32.add + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: (i32.const 1) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (i32.const 12345678) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (then + ;; CHECK_1-NEXT: (i32.add + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: (i32.const 1) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (else + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: ) + ;; CHECK_3: (func $pointless-work (type $1) (param $0 i32) (result i32) + ;; CHECK_3-NEXT: (if (result i32) + ;; CHECK_3-NEXT: (i32.ge_u + ;; CHECK_3-NEXT: (local.tee $0 + ;; CHECK_3-NEXT: (i32.add + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: (i32.const 1) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (i32.const 12345678) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (then + ;; CHECK_3-NEXT: (i32.add + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: (i32.const 1) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (else + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: ) + ;; CHECK_s: (func $pointless-work (type $1) (param $0 i32) (result i32) + ;; CHECK_s-NEXT: (if (result i32) + ;; CHECK_s-NEXT: (i32.ge_u + ;; CHECK_s-NEXT: (local.tee $0 + ;; CHECK_s-NEXT: (i32.add + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: (i32.const 1) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (i32.const 12345678) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (then + ;; CHECK_s-NEXT: (i32.add + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: (i32.const 1) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (else + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: ) + ;; CHECK_O: (func $pointless-work (type $1) (param $0 i32) (result i32) + ;; CHECK_O-NEXT: (if (result i32) + ;; CHECK_O-NEXT: (i32.ge_u + ;; CHECK_O-NEXT: (local.tee $0 + ;; CHECK_O-NEXT: (i32.add + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: (i32.const 1) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (i32.const 12345678) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (then + ;; CHECK_O-NEXT: (i32.add + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: (i32.const 1) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (else + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: ) + (func $pointless-work (param $x i32) (result i32) + ;; Some pointless work, with no side effects, that cannot be inlined. (The + ;; changes here are not important for this test.) + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) + ) + (if + (i32.ge_u + (local.get $x) + (i32.const 12345678) + ) + (then + (local.set $x + (i32.add + (local.get $x) + (i32.const 1) + ) + ) + ) + ) + (return + (local.get $x) + ) + ) + + ;; CHECK_0: (func $infinite-work (type $1) (param $x i32) (result i32) ;; CHECK_0-NEXT: (loop $loop ;; CHECK_0-NEXT: (local.set $x ;; CHECK_0-NEXT: (i32.add @@ -88,92 +330,70 @@ ;; CHECK_0-NEXT: (i32.const 1) ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: ) - ;; CHECK_0-NEXT: (if - ;; CHECK_0-NEXT: (i32.ge_u - ;; CHECK_0-NEXT: (local.get $x) - ;; CHECK_0-NEXT: (i32.const 12345678) - ;; CHECK_0-NEXT: ) - ;; CHECK_0-NEXT: (then - ;; CHECK_0-NEXT: (return - ;; CHECK_0-NEXT: (local.get $x) - ;; CHECK_0-NEXT: ) - ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (br_if $loop + ;; CHECK_0-NEXT: (local.get $x) ;; CHECK_0-NEXT: ) - ;; CHECK_0-NEXT: (br $loop) + ;; CHECK_0-NEXT: ) + ;; CHECK_0-NEXT: (return + ;; CHECK_0-NEXT: (local.get $x) ;; CHECK_0-NEXT: ) ;; CHECK_0-NEXT: ) - ;; CHECK_1: (func $pointless-work (type $1) (result i32) - ;; CHECK_1-NEXT: (local $0 i32) - ;; CHECK_1-NEXT: (loop $loop (result i32) + ;; CHECK_1: (func $infinite-work (type $1) (param $0 i32) (result i32) + ;; CHECK_1-NEXT: (loop $loop ;; CHECK_1-NEXT: (br_if $loop - ;; CHECK_1-NEXT: (i32.lt_u - ;; CHECK_1-NEXT: (local.tee $0 - ;; CHECK_1-NEXT: (i32.add - ;; CHECK_1-NEXT: (local.get $0) - ;; CHECK_1-NEXT: (i32.const 1) - ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (local.tee $0 + ;; CHECK_1-NEXT: (i32.add + ;; CHECK_1-NEXT: (local.get $0) + ;; CHECK_1-NEXT: (i32.const 1) ;; CHECK_1-NEXT: ) - ;; CHECK_1-NEXT: (i32.const 12345678) ;; CHECK_1-NEXT: ) ;; CHECK_1-NEXT: ) - ;; CHECK_1-NEXT: (local.get $0) ;; CHECK_1-NEXT: ) + ;; CHECK_1-NEXT: (local.get $0) ;; CHECK_1-NEXT: ) - ;; CHECK_3: (func $pointless-work (type $1) (result i32) - ;; CHECK_3-NEXT: (local $0 i32) - ;; CHECK_3-NEXT: (loop $loop (result i32) + ;; CHECK_3: (func $infinite-work (type $1) (param $0 i32) (result i32) + ;; CHECK_3-NEXT: (loop $loop ;; CHECK_3-NEXT: (br_if $loop - ;; CHECK_3-NEXT: (i32.lt_u - ;; CHECK_3-NEXT: (local.tee $0 - ;; CHECK_3-NEXT: (i32.add - ;; CHECK_3-NEXT: (local.get $0) - ;; CHECK_3-NEXT: (i32.const 1) - ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (local.tee $0 + ;; CHECK_3-NEXT: (i32.add + ;; CHECK_3-NEXT: (local.get $0) + ;; CHECK_3-NEXT: (i32.const 1) ;; CHECK_3-NEXT: ) - ;; CHECK_3-NEXT: (i32.const 12345678) ;; CHECK_3-NEXT: ) ;; CHECK_3-NEXT: ) - ;; CHECK_3-NEXT: (local.get $0) ;; CHECK_3-NEXT: ) + ;; CHECK_3-NEXT: (local.get $0) ;; CHECK_3-NEXT: ) - ;; CHECK_s: (func $pointless-work (type $1) (result i32) - ;; CHECK_s-NEXT: (local $0 i32) - ;; CHECK_s-NEXT: (loop $loop (result i32) + ;; CHECK_s: (func $infinite-work (type $1) (param $0 i32) (result i32) + ;; CHECK_s-NEXT: (loop $loop ;; CHECK_s-NEXT: (br_if $loop - ;; CHECK_s-NEXT: (i32.lt_u - ;; CHECK_s-NEXT: (local.tee $0 - ;; CHECK_s-NEXT: (i32.add - ;; CHECK_s-NEXT: (local.get $0) - ;; CHECK_s-NEXT: (i32.const 1) - ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (local.tee $0 + ;; CHECK_s-NEXT: (i32.add + ;; CHECK_s-NEXT: (local.get $0) + ;; CHECK_s-NEXT: (i32.const 1) ;; CHECK_s-NEXT: ) - ;; CHECK_s-NEXT: (i32.const 12345678) ;; CHECK_s-NEXT: ) ;; CHECK_s-NEXT: ) - ;; CHECK_s-NEXT: (local.get $0) ;; CHECK_s-NEXT: ) + ;; CHECK_s-NEXT: (local.get $0) ;; CHECK_s-NEXT: ) - ;; CHECK_O: (func $pointless-work (type $1) (result i32) - ;; CHECK_O-NEXT: (local $0 i32) - ;; CHECK_O-NEXT: (loop $loop (result i32) + ;; CHECK_O: (func $infinite-work (type $1) (param $0 i32) (result i32) + ;; CHECK_O-NEXT: (loop $loop ;; CHECK_O-NEXT: (br_if $loop - ;; CHECK_O-NEXT: (i32.lt_u - ;; CHECK_O-NEXT: (local.tee $0 - ;; CHECK_O-NEXT: (i32.add - ;; CHECK_O-NEXT: (local.get $0) - ;; CHECK_O-NEXT: (i32.const 1) - ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (local.tee $0 + ;; CHECK_O-NEXT: (i32.add + ;; CHECK_O-NEXT: (local.get $0) + ;; CHECK_O-NEXT: (i32.const 1) ;; CHECK_O-NEXT: ) - ;; CHECK_O-NEXT: (i32.const 12345678) ;; CHECK_O-NEXT: ) ;; CHECK_O-NEXT: ) - ;; CHECK_O-NEXT: (local.get $0) ;; CHECK_O-NEXT: ) + ;; CHECK_O-NEXT: (local.get $0) ;; CHECK_O-NEXT: ) - (func $pointless-work (result i32) - (local $x i32) - ;; Some pointless work, with no side effects, that cannot be inlined. (The - ;; changes here are not important for this test.) + (func $infinite-work (param $x i32) (result i32) + ;; Some work with no side effects aside from that it appears to potentially + ;; do infinite work, due to a loop. (The changes here are not important for + ;; this test.) (loop $loop (local.set $x (i32.add @@ -181,18 +401,12 @@ (i32.const 1) ) ) - (if - (i32.ge_u - (local.get $x) - (i32.const 12345678) - ) - (then - (return - (local.get $x) - ) - ) + (br_if $loop + (local.get $x) ) - (br $loop) + ) + (return + (local.get $x) ) ) ) From 76d1ac3e9c5abfe589bcdfc84b89f263bac7c574 Mon Sep 17 00:00:00 2001 From: mtb <39337159+mtb0x1@users.noreply.github.com> Date: Wed, 5 Jun 2024 02:14:50 +0200 Subject: [PATCH 372/553] Fix stack-use-after-scope on Windows in Precompute (#6643) Create a temp var to store the ChildIterator. Fixes #6639 --- src/passes/Precompute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 295d86b40e2..ba04a68aa26 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -858,7 +858,8 @@ struct Precompute } auto* child = stack[index]; - for (auto** currChild : ChildIterator(stack[index - 1]).children) { + auto childIterator = ChildIterator(stack[index - 1]); + for (auto** currChild : childIterator.children) { if (*currChild == child) { return currChild; } From 0a1a59af573414a20fe457fd77b732729aa92fb2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 10 Jun 2024 16:02:00 -0700 Subject: [PATCH 373/553] wasm2js: Add basic reference operations (#6648) This adds ref.eq, ref.null, ref.is_null, ref.func. --- src/asmjs/asm_v_wasm.cpp | 4 ++ src/emscripten-optimizer/optimizer-shared.cpp | 10 ++++- src/emscripten-optimizer/optimizer.h | 2 + src/wasm2js.h | 30 ++++++------- test/wasm2js/refs.2asm.js | 44 +++++++++++++++++++ test/wasm2js/refs.2asm.js.opt | 42 ++++++++++++++++++ test/wasm2js/refs.wast | 33 ++++++++++++++ 7 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 test/wasm2js/refs.2asm.js create mode 100644 test/wasm2js/refs.2asm.js.opt create mode 100644 test/wasm2js/refs.wast diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp index 314c2494ff6..bbbaad5bc59 100644 --- a/src/asmjs/asm_v_wasm.cpp +++ b/src/asmjs/asm_v_wasm.cpp @@ -21,6 +21,10 @@ namespace wasm { JsType wasmToJsType(Type type) { + if (type.isRef()) { + return JS_REF; + } + TODO_SINGLE_COMPOUND(type); switch (type.getBasic()) { case Type::i32: diff --git a/src/emscripten-optimizer/optimizer-shared.cpp b/src/emscripten-optimizer/optimizer-shared.cpp index 8208f6f47ed..773c5d9fc27 100644 --- a/src/emscripten-optimizer/optimizer-shared.cpp +++ b/src/emscripten-optimizer/optimizer-shared.cpp @@ -104,6 +104,11 @@ Ref makeJsCoercedZero(JsType type) { abort(); } +bool needsJsCoercion(JsType type) { + // References need no coercion, but everything else does. + return type != JS_REF; +} + Ref makeJsCoercion(Ref node, JsType type) { switch (type) { case JS_INT: @@ -122,10 +127,11 @@ Ref makeJsCoercion(Ref node, JsType type) { return ValueBuilder::makeCall(SIMD_INT16X8_CHECK, node); case JS_INT32X4: return ValueBuilder::makeCall(SIMD_INT32X4_CHECK, node); + case JS_REF: case JS_NONE: default: - // non-validating code, emit nothing XXX this is dangerous, we should only - // allow this when we know we are not validating + // No coercion is needed. + // TODO see if JS_NONE is actually used here. return node; } } diff --git a/src/emscripten-optimizer/optimizer.h b/src/emscripten-optimizer/optimizer.h index a27fe25ebff..6347c194c06 100644 --- a/src/emscripten-optimizer/optimizer.h +++ b/src/emscripten-optimizer/optimizer.h @@ -39,6 +39,7 @@ enum JsType { JS_INT16X8, JS_INT32X4, JS_INT64, + JS_REF, JS_NONE // number of types }; @@ -51,6 +52,7 @@ enum JsSign { }; cashew::Ref makeJsCoercedZero(JsType type); +bool needsJsCoercion(JsType type); cashew::Ref makeJsCoercion(cashew::Ref node, JsType type); cashew::Ref makeSigning(cashew::Ref node, JsSign sign); diff --git a/src/wasm2js.h b/src/wasm2js.h index 7540bd71ac2..2084c04537c 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -921,11 +921,13 @@ Ref Wasm2JSBuilder::processFunction(Module* m, IString name = fromName(func->getLocalNameOrGeneric(i), NameScope::Local); ValueBuilder::appendArgumentToFunction(ret, name); if (needCoercions) { - ret[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeBinary( - ValueBuilder::makeName(name), - SET, - makeJsCoercion(ValueBuilder::makeName(name), - wasmToJsType(func->getLocalType(i)))))); + auto jsType = wasmToJsType(func->getLocalType(i)); + if (needsJsCoercion(jsType)) { + ret[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeBinary( + ValueBuilder::makeName(name), + SET, + makeJsCoercion(ValueBuilder::makeName(name), jsType)))); + } } } Ref theVar = ValueBuilder::makeVar(); @@ -2219,21 +2221,19 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, visit(curr->value, EXPRESSION_RESULT), visit(curr->size, EXPRESSION_RESULT)); } - Ref visitRefNull(RefNull* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); - } + Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName("null"); } Ref visitRefIsNull(RefIsNull* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT), + EQ, + ValueBuilder::makeName("null")); } Ref visitRefFunc(RefFunc* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeName(fromName(curr->func, NameScope::Top)); } Ref visitRefEq(RefEq* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeBinary(visit(curr->left, EXPRESSION_RESULT), + EQ, + visit(curr->right, EXPRESSION_RESULT)); } Ref visitTableGet(TableGet* curr) { unimplemented(curr); diff --git a/test/wasm2js/refs.2asm.js b/test/wasm2js/refs.2asm.js new file mode 100644 index 00000000000..0133159b9e9 --- /dev/null +++ b/test/wasm2js/refs.2asm.js @@ -0,0 +1,44 @@ + +function asmFunc(imports) { + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function null_() { + return null; + } + + function is_null(ref) { + return ref == null | 0; + } + + function ref_func() { + var ref_func_1 = 0; + ref_func_1 = ref_func_1 + 1 | 0; + return ref_func; + } + + function ref_eq(x, y) { + return x == y | 0; + } + + return { + "null_": null_, + "is_null": is_null, + "ref_func": ref_func, + "ref_eq": ref_eq + }; +} + +var retasmFunc = asmFunc({ +}); +export var null_ = retasmFunc.null_; +export var is_null = retasmFunc.is_null; +export var ref_func = retasmFunc.ref_func; +export var ref_eq = retasmFunc.ref_eq; diff --git a/test/wasm2js/refs.2asm.js.opt b/test/wasm2js/refs.2asm.js.opt new file mode 100644 index 00000000000..e38afe1cf6f --- /dev/null +++ b/test/wasm2js/refs.2asm.js.opt @@ -0,0 +1,42 @@ + +function asmFunc(imports) { + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function null_() { + return null; + } + + function is_null($0) { + return $0 == null | 0; + } + + function ref_func() { + return ref_func; + } + + function ref_eq($0, $1) { + return $0 == $1 | 0; + } + + return { + "null_": null_, + "is_null": is_null, + "ref_func": ref_func, + "ref_eq": ref_eq + }; +} + +var retasmFunc = asmFunc({ +}); +export var null_ = retasmFunc.null_; +export var is_null = retasmFunc.is_null; +export var ref_func = retasmFunc.ref_func; +export var ref_eq = retasmFunc.ref_eq; diff --git a/test/wasm2js/refs.wast b/test/wasm2js/refs.wast new file mode 100644 index 00000000000..4e133c03efe --- /dev/null +++ b/test/wasm2js/refs.wast @@ -0,0 +1,33 @@ +(module + (func $null (export "null") (result anyref) + (ref.null any) + ) + + (func $is_null (export "is_null") (param $ref anyref) (result i32) + (ref.is_null + (local.get $ref) + ) + ) + + (func $ref.func (export "ref.func") (result funcref) + ;; Test that we are aware that "$ref.func" below refers to the function and + ;; not the local. This code will keep the local around (at least in an + ;; unoptimized build), and it should use a different name than the function. + (local $ref.func i32) + (local.set $ref.func + (i32.add + (local.get $ref.func) + (i32.const 1) + ) + ) + + (ref.func $ref.func) + ) + + (func $ref.eq (export "ref.eq") (param $x eqref) (param $y eqref) (result i32) + (ref.eq + (local.get $x) + (local.get $y) + ) + ) +) From 3d0e687447be426c4157dbe9c6d2626b147f85bf Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 10 Jun 2024 16:15:46 -0700 Subject: [PATCH 374/553] [Strings] Keep public and private types separate in StringLowering (#6642) We need StringLowering to modify even public types, as it must replace every single stringref with externref, even if that modifies the ABI. To achieve that we told it that all string-using types were private, which let TypeUpdater update them, but the problem is that it moves all private types to a new single rec group, which meant public and private types ended up in the same group. As a result, a single public type would make it all public, preventing optimizations and breaking things as in #6630 #6640. Ideally TypeUpdater would modify public types while keeping them in the same rec groups, but this may be a very specific issue for StringLowering, and that might be a lot of work. Instead, just make StringLowering handle public types of functions in a manual way, which is simple and should handle all cases that matter in practice, at least in J2Wasm. --- src/passes/StringLowering.cpp | 52 +++++++++---- .../passes/string-lowering-instructions.wast | 56 +++++++------- test/lit/passes/string-lowering_types.wast | 74 +++++++++++++++++++ 3 files changed, 141 insertions(+), 41 deletions(-) create mode 100644 test/lit/passes/string-lowering_types.wast diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index 9903f090e30..ca0ba773c76 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -267,6 +267,44 @@ struct StringLowering : public StringGathering { Type nnExt = Type(HeapType::ext, NonNullable); void updateTypes(Module* module) { + // TypeMapper will not handle public types, but we do want to modify them as + // well: we are modifying the public ABI here. We can't simply tell + // TypeMapper to consider them private, as then they'd end up in the new big + // rec group with the private types (and as they are public, that would make + // the entire rec group public, and all types in the module with it). + // Instead, manually handle singleton-rec groups of function types. This + // keeps them at size 1, as expected, and handles the cases of function + // imports and exports. If we need more (non-function types, non-singleton + // rec groups, etc.) then more work will be necessary TODO + // + // Note that we do this before TypeMapper, which allows it to then fix up + // things like the types of parameters (which depend on the type of the + // function, which must be modified either in TypeMapper - but as just + // explained we cannot do that - or before it, which is what we do here). + for (auto& func : module->functions) { + if (func->type.getRecGroup().size() != 1 || + !Type(func->type, Nullable).getFeatures().hasStrings()) { + continue; + } + + // Fix up the stringrefs in this type that uses strings and is in a + // singleton rec group. + std::vector params, results; + auto fix = [](Type t) { + if (t.isRef() && t.getHeapType() == HeapType::string) { + t = Type(HeapType::ext, t.getNullability()); + } + return t; + }; + for (auto param : func->type.getSignature().params) { + params.push_back(fix(param)); + } + for (auto result : func->type.getSignature().results) { + results.push_back(fix(result)); + } + func->type = Signature(params, results); + } + TypeMapper::TypeUpdates updates; // Strings turn into externref. @@ -288,19 +326,7 @@ struct StringLowering : public StringGathering { } } - // We consider all types that use strings as modifiable, which means we - // mark them as non-public. That is, we are doing something TypeMapper - // normally does not, as we are changing the external interface/ABI of the - // module: we are changing that ABI from using strings to externs. - auto publicTypes = ModuleUtils::getPublicHeapTypes(*module); - std::vector stringUsers; - for (auto t : publicTypes) { - if (Type(t, Nullable).getFeatures().hasStrings()) { - stringUsers.push_back(t); - } - } - - TypeMapper(*module, updates).map(stringUsers); + TypeMapper(*module, updates).map(); } // Imported string functions. diff --git a/test/lit/passes/string-lowering-instructions.wast b/test/lit/passes/string-lowering-instructions.wast index b98b9af233b..459f1817019 100644 --- a/test/lit/passes/string-lowering-instructions.wast +++ b/test/lit/passes/string-lowering-instructions.wast @@ -8,14 +8,12 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $2 (func (param externref externref) (result i32))) + ;; CHECK: (type $2 (func (result externref))) - ;; CHECK: (rec - ;; CHECK-NEXT: (type $3 (func (param externref i32 externref))) - - ;; CHECK: (type $4 (func (result externref))) + ;; CHECK: (type $3 (func (param externref externref) (result i32))) - ;; CHECK: (type $5 (func (param externref))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $4 (func (param externref))) ;; CHECK: (type $struct-of-string (struct (field externref) (field i32) (field anyref))) (type $struct-of-string (struct (field stringref) (field i32) (field anyref))) @@ -39,17 +37,19 @@ (type $array16 (array (mut i16))) ) - ;; CHECK: (type $13 (func (param externref) (result externref))) + ;; CHECK: (type $12 (func (param externref) (result externref))) + + ;; CHECK: (type $13 (func (param externref) (result i32))) - ;; CHECK: (type $14 (func (param externref) (result i32))) + ;; CHECK: (type $14 (func (param externref externref) (result i32))) - ;; CHECK: (type $15 (func (param externref externref) (result i32))) + ;; CHECK: (type $15 (func (param externref (ref $0)) (result i32))) - ;; CHECK: (type $16 (func (param externref (ref $0)) (result i32))) + ;; CHECK: (type $16 (func (param externref externref) (result (ref extern)))) - ;; CHECK: (type $17 (func (param externref externref) (result (ref extern)))) + ;; CHECK: (type $17 (func (param (ref $0)))) - ;; CHECK: (type $18 (func (param (ref $0)))) + ;; CHECK: (type $18 (func (param externref i32 externref))) ;; CHECK: (type $19 (func (param (ref null $0) i32 i32) (result (ref extern)))) @@ -81,9 +81,9 @@ ;; CHECK: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $22) (param externref (ref null $0) i32) (result i32))) - ;; CHECK: (import "wasm:js-string" "equals" (func $equals (type $2) (param externref externref) (result i32))) + ;; CHECK: (import "wasm:js-string" "equals" (func $equals (type $3) (param externref externref) (result i32))) - ;; CHECK: (import "wasm:js-string" "compare" (func $compare (type $2) (param externref externref) (result i32))) + ;; CHECK: (import "wasm:js-string" "compare" (func $compare (type $3) (param externref externref) (result i32))) ;; CHECK: (import "wasm:js-string" "length" (func $length (type $23) (param externref) (result i32))) @@ -98,7 +98,7 @@ ;; CHECK: (export "export.2" (func $exported-string-receiver)) - ;; CHECK: (func $string.new.gc (type $18) (param $array16 (ref $0)) + ;; CHECK: (func $string.new.gc (type $17) (param $array16 (ref $0)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $fromCharCodeArray ;; CHECK-NEXT: (local.get $array16) @@ -117,7 +117,7 @@ ) ) - ;; CHECK: (func $string.from_code_point (type $4) (result externref) + ;; CHECK: (func $string.from_code_point (type $2) (result externref) ;; CHECK-NEXT: (call $fromCodePoint_18 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -128,7 +128,7 @@ ) ) - ;; CHECK: (func $string.concat (type $17) (param $0 externref) (param $1 externref) (result (ref extern)) + ;; CHECK: (func $string.concat (type $16) (param $0 externref) (param $1 externref) (result (ref extern)) ;; CHECK-NEXT: (call $concat ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -141,7 +141,7 @@ ) ) - ;; CHECK: (func $string.encode (type $16) (param $ref externref) (param $array16 (ref $0)) (result i32) + ;; CHECK: (func $string.encode (type $15) (param $ref externref) (param $array16 (ref $0)) (result i32) ;; CHECK-NEXT: (call $intoCharCodeArray ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: (local.get $array16) @@ -156,7 +156,7 @@ ) ) - ;; CHECK: (func $string.eq (type $15) (param $a externref) (param $b externref) (result i32) + ;; CHECK: (func $string.eq (type $14) (param $a externref) (param $b externref) (result i32) ;; CHECK-NEXT: (call $equals ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: (local.get $b) @@ -169,7 +169,7 @@ ) ) - ;; CHECK: (func $string.compare (type $15) (param $a externref) (param $b externref) (result i32) + ;; CHECK: (func $string.compare (type $14) (param $a externref) (param $b externref) (result i32) ;; CHECK-NEXT: (call $compare ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: (local.get $b) @@ -182,7 +182,7 @@ ) ) - ;; CHECK: (func $string.length (type $14) (param $ref externref) (result i32) + ;; CHECK: (func $string.length (type $13) (param $ref externref) (result i32) ;; CHECK-NEXT: (call $length ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) @@ -193,7 +193,7 @@ ) ) - ;; CHECK: (func $string.get_codeunit (type $14) (param $ref externref) (result i32) + ;; CHECK: (func $string.get_codeunit (type $13) (param $ref externref) (result i32) ;; CHECK-NEXT: (call $charCodeAt ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: (i32.const 2) @@ -206,7 +206,7 @@ ) ) - ;; CHECK: (func $string.slice (type $13) (param $ref externref) (result externref) + ;; CHECK: (func $string.slice (type $12) (param $ref externref) (result externref) ;; CHECK-NEXT: (call $substring ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: (i32.const 2) @@ -221,7 +221,7 @@ ) ) - ;; CHECK: (func $if.string (type $13) (param $ref externref) (result externref) + ;; CHECK: (func $if.string (type $12) (param $ref externref) (result externref) ;; CHECK-NEXT: (if (result externref) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -244,7 +244,7 @@ ) ) - ;; CHECK: (func $if.string.flip (type $13) (param $ref externref) (result externref) + ;; CHECK: (func $if.string.flip (type $12) (param $ref externref) (result externref) ;; CHECK-NEXT: (if (result externref) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -268,7 +268,7 @@ ) ) - ;; CHECK: (func $exported-string-returner (type $4) (result externref) + ;; CHECK: (func $exported-string-returner (type $2) (result externref) ;; CHECK-NEXT: (global.get $string.const_exported) ;; CHECK-NEXT: ) (func $exported-string-returner (export "export.1") (result stringref) @@ -277,7 +277,7 @@ (string.const "exported") ) - ;; CHECK: (func $exported-string-receiver (type $3) (param $x externref) (param $y i32) (param $z externref) + ;; CHECK: (func $exported-string-receiver (type $18) (param $x externref) (param $y i32) (param $z externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) @@ -398,7 +398,7 @@ ) ) - ;; CHECK: (func $call-param-null (type $5) (param $str externref) + ;; CHECK: (func $call-param-null (type $4) (param $str externref) ;; CHECK-NEXT: (call $call-param-null ;; CHECK-NEXT: (ref.null noextern) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/string-lowering_types.wast b/test/lit/passes/string-lowering_types.wast new file mode 100644 index 00000000000..54367e85af5 --- /dev/null +++ b/test/lit/passes/string-lowering_types.wast @@ -0,0 +1,74 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --string-lowering -all -S -o - | filecheck %s + +;; A private type exists, and a public type is used by imports (one explicitly, +;; one implicitly). When we lower stringref into externref the import's types +;; should not be part of a rec group with the private type: public and private +;; types must remain separate. +(module + (rec + ;; CHECK: (type $0 (func (param externref externref) (result i32))) + + ;; CHECK: (type $1 (array (mut i16))) + + ;; CHECK: (type $2 (func (param externref))) + + ;; CHECK: (type $3 (func (param (ref extern)))) + + ;; CHECK: (type $4 (func)) + + ;; CHECK: (type $private (struct (field externref))) + (type $private (struct (field stringref))) + ) + (type $public (func (param stringref))) + + ;; CHECK: (type $6 (func (param (ref null $1) i32 i32) (result (ref extern)))) + + ;; CHECK: (type $7 (func (param i32) (result (ref extern)))) + + ;; CHECK: (type $8 (func (param externref externref) (result (ref extern)))) + + ;; CHECK: (type $9 (func (param externref (ref null $1) i32) (result i32))) + + ;; CHECK: (type $10 (func (param externref) (result i32))) + + ;; CHECK: (type $11 (func (param externref i32) (result i32))) + + ;; CHECK: (type $12 (func (param externref i32 i32) (result (ref extern)))) + + ;; CHECK: (import "a" "b" (func $import (type $2) (param externref))) + (import "a" "b" (func $import (type $public) (param stringref))) + + ;; CHECK: (import "a" "b" (func $import-implicit (type $3) (param (ref extern)))) + (import "a" "b" (func $import-implicit (param (ref string)))) + + ;; CHECK: (import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $6) (param (ref null $1) i32 i32) (result (ref extern)))) + + ;; CHECK: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint (type $7) (param i32) (result (ref extern)))) + + ;; CHECK: (import "wasm:js-string" "concat" (func $concat (type $8) (param externref externref) (result (ref extern)))) + + ;; CHECK: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $9) (param externref (ref null $1) i32) (result i32))) + + ;; CHECK: (import "wasm:js-string" "equals" (func $equals (type $0) (param externref externref) (result i32))) + + ;; CHECK: (import "wasm:js-string" "compare" (func $compare (type $0) (param externref externref) (result i32))) + + ;; CHECK: (import "wasm:js-string" "length" (func $length (type $10) (param externref) (result i32))) + + ;; CHECK: (import "wasm:js-string" "charCodeAt" (func $charCodeAt (type $11) (param externref i32) (result i32))) + + ;; CHECK: (import "wasm:js-string" "substring" (func $substring (type $12) (param externref i32 i32) (result (ref extern)))) + + ;; CHECK: (export "export" (func $export)) + + ;; CHECK: (func $export (type $4) + ;; CHECK-NEXT: (local $0 (ref $private)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $export (export "export") + ;; Keep the private type alive. + (local (ref $private)) + ) +) From cdd94a01ad02e944eaa9ba5e20a1129bef9ac305 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 11 Jun 2024 13:11:04 -0700 Subject: [PATCH 375/553] Fix scratch local optimizations when emitting string slice (#6649) The binary writing of `stringview_wtf16.slice` requires scratch locals to store the `start` and `end` operands while the string operand is converted to a stringview. To avoid unbounded binary bloat when round-tripping, we detect the case that `start` and `end` are already `local.get`s and avoid using scratch locals by deferring the binary writing of the `local.get` operands until after the stringview conversoins is emitted. We previously optimized the scratch locals for `start` and `end` independently, but this could produce incorrect code in the case where the `local.get` for `start` is deferred but its value is changed by a `local.set` in the code for `end`. Fix the problem by only optimizing to avoid scratch locals in the case where both `start` and `end` are already `local.get`s, so they will still be emitted in the original relative order and they cannot interfere with each other anyway. --- src/wasm/wasm-stack.cpp | 53 +++++++++------------ test/lit/exec/strings.wast | 19 ++++++++ test/lit/string.as_wtf16.wast | 86 ++++++++++++++++++++++++++--------- 3 files changed, 105 insertions(+), 53 deletions(-) diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 50c13da65de..ac117e2e0ab 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2455,32 +2455,25 @@ void BinaryInstWriter::visitStringWTF16Get(StringWTF16Get* curr) { void BinaryInstWriter::visitStringSliceWTF(StringSliceWTF* curr) { // We need to convert the ref operand to a stringview, but it is buried under // the start and end operands. Put the i32s in scratch locals, emit the - // conversion, then get the i32s back onto the stack. If either `start` or - // `end` is already a local.get, then we can skip its scratch local. - bool startDeferred = false, endDeferred = false; + // conversion, then get the i32s back onto the stack. If both `start` and + // `end` are already local.gets, then we can skip the scratch locals. + bool deferred = false; Index startIndex, endIndex; - if (auto* get = curr->start->dynCast()) { - assert(deferredGets.count(get)); - startDeferred = true; - startIndex = mappedLocals[{get->index, 0}]; + auto* startGet = curr->start->dynCast(); + auto* endGet = curr->end->dynCast(); + if (startGet && endGet) { + assert(deferredGets.count(startGet)); + assert(deferredGets.count(endGet)); + deferred = true; + startIndex = mappedLocals[{startGet->index, 0}]; + endIndex = mappedLocals[{endGet->index, 0}]; } else { startIndex = scratchLocals[Type::i32]; - } - if (auto* get = curr->end->dynCast()) { - assert(deferredGets.count(get)); - endDeferred = true; - endIndex = mappedLocals[{get->index, 0}]; - } else { - endIndex = scratchLocals[Type::i32]; - if (!startDeferred) { - ++endIndex; - } + endIndex = startIndex + 1; } - if (!endDeferred) { + if (!deferred) { o << int8_t(BinaryConsts::LocalSet) << U32LEB(endIndex); - } - if (!startDeferred) { o << int8_t(BinaryConsts::LocalSet) << U32LEB(startIndex); } o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StringAsWTF16); @@ -2698,21 +2691,19 @@ InsertOrderedMap BinaryInstWriter::countScratchLocals() { if (curr->type == Type::unreachable) { return; } - // If `start` or `end` are already local.gets, we can defer emitting those - // gets instead of using scratch locals. - Index numScratches = 2; - if (auto* get = curr->start->dynCast()) { - parent.deferredGets.insert(get); - --numScratches; - } - if (auto* get = curr->end->dynCast()) { - parent.deferredGets.insert(get); - --numScratches; + // If `start` and `end` are already local.gets, we can defer emitting + // those gets instead of using scratch locals. + auto* startGet = curr->start->dynCast(); + auto* endGet = curr->end->dynCast(); + if (startGet && endGet) { + parent.deferredGets.insert(startGet); + parent.deferredGets.insert(endGet); + return; } // Scratch locals to hold the `start` and `end` values while we emit a // stringview conversion for the `ref` value. auto& count = scratches[Type::i32]; - count = std::max(count, numScratches); + count = std::max(count, 2u); } // As mentioned in BinaryInstWriter::visitBreak, the type of br_if with a diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index ca77f9882d9..f0c659d19e9 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -284,6 +284,21 @@ ) ) + ;; CHECK: [fuzz-exec] calling slice-ordering + ;; CHECK-NEXT: [fuzz-exec] note result: slice-ordering => string("h") + (func $slice-ordering (export "slice-ordering") (result (ref string)) + (local $0 i32) + (stringview_wtf16.slice + (string.const "hello") + ;; If we were to defer emitting this get in the binary writer, it would + ;; end up with the wrong value. + (local.get $0) + (local.tee $0 + (i32.const 1) + ) + ) + ) + ;; CHECK: [fuzz-exec] calling new_empty ;; CHECK-NEXT: [fuzz-exec] note result: new_empty => string("") (func $new_empty (export "new_empty") (result stringref) @@ -536,6 +551,9 @@ ;; CHECK: [fuzz-exec] calling slice-big ;; CHECK-NEXT: [fuzz-exec] note result: slice-big => string("defgh") +;; CHECK: [fuzz-exec] calling slice-ordering +;; CHECK-NEXT: [fuzz-exec] note result: slice-ordering => string("h") + ;; CHECK: [fuzz-exec] calling new_empty ;; CHECK-NEXT: [fuzz-exec] note result: new_empty => string("") @@ -620,6 +638,7 @@ ;; CHECK-NEXT: [fuzz-exec] comparing new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] comparing slice ;; CHECK-NEXT: [fuzz-exec] comparing slice-big +;; CHECK-NEXT: [fuzz-exec] comparing slice-ordering ;; CHECK-NEXT: [fuzz-exec] comparing slice-unicode ;; CHECK-NEXT: [fuzz-exec] comparing string.from_code_point ;; CHECK-NEXT: [fuzz-exec] comparing string.measure diff --git a/test/lit/string.as_wtf16.wast b/test/lit/string.as_wtf16.wast index 97a5d90559f..916e11d39a1 100644 --- a/test/lit/string.as_wtf16.wast +++ b/test/lit/string.as_wtf16.wast @@ -185,38 +185,59 @@ ;; RTRIP: (func $slice-start-get (type $0) (result stringref) ;; RTRIP-NEXT: (local $start i32) ;; RTRIP-NEXT: (local $1 i32) - ;; RTRIP-NEXT: (local $2 (ref string)) + ;; RTRIP-NEXT: (local $2 i32) + ;; RTRIP-NEXT: (local $3 i32) + ;; RTRIP-NEXT: (local $4 (ref string)) ;; RTRIP-NEXT: (stringview_wtf16.slice ;; RTRIP-NEXT: (block (result (ref string)) - ;; RTRIP-NEXT: (local.set $2 + ;; RTRIP-NEXT: (local.set $4 ;; RTRIP-NEXT: (string.const "abc") ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: (local.set $1 - ;; RTRIP-NEXT: (i32.const 2) + ;; RTRIP-NEXT: (block (result i32) + ;; RTRIP-NEXT: (local.set $3 + ;; RTRIP-NEXT: (local.get $start) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (local.set $2 + ;; RTRIP-NEXT: (i32.const 2) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (local.get $3) + ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: ) - ;; RTRIP-NEXT: (local.get $2) + ;; RTRIP-NEXT: (local.get $4) ;; RTRIP-NEXT: ) - ;; RTRIP-NEXT: (local.get $start) ;; RTRIP-NEXT: (local.get $1) + ;; RTRIP-NEXT: (local.get $2) ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: ) ;; RRTRP: (func $slice-start-get (type $0) (result stringref) ;; RRTRP-NEXT: (local $start i32) ;; RRTRP-NEXT: (local $1 i32) - ;; RRTRP-NEXT: (local $2 (ref string)) - ;; RRTRP-NEXT: (local $3 (ref string)) + ;; RRTRP-NEXT: (local $2 i32) + ;; RRTRP-NEXT: (local $3 i32) + ;; RRTRP-NEXT: (local $4 (ref string)) + ;; RRTRP-NEXT: (local $5 i32) + ;; RRTRP-NEXT: (local $6 (ref string)) ;; RRTRP-NEXT: (stringview_wtf16.slice ;; RRTRP-NEXT: (block (result (ref string)) - ;; RRTRP-NEXT: (local.set $3 + ;; RRTRP-NEXT: (local.set $6 ;; RRTRP-NEXT: (string.const "abc") ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: (local.set $1 - ;; RRTRP-NEXT: (i32.const 2) + ;; RRTRP-NEXT: (block (result i32) + ;; RRTRP-NEXT: (local.set $5 + ;; RRTRP-NEXT: (local.get $start) + ;; RRTRP-NEXT: ) + ;; RRTRP-NEXT: (local.set $2 + ;; RRTRP-NEXT: (i32.const 2) + ;; RRTRP-NEXT: ) + ;; RRTRP-NEXT: (local.get $5) + ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: ) - ;; RRTRP-NEXT: (local.get $3) + ;; RRTRP-NEXT: (local.get $6) ;; RRTRP-NEXT: ) - ;; RRTRP-NEXT: (local.get $start) ;; RRTRP-NEXT: (local.get $1) + ;; RRTRP-NEXT: (local.get $2) ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: ) (func $slice-start-get (result stringref) @@ -240,38 +261,59 @@ ;; RTRIP: (func $slice-end-get (type $0) (result stringref) ;; RTRIP-NEXT: (local $end i32) ;; RTRIP-NEXT: (local $1 i32) - ;; RTRIP-NEXT: (local $2 (ref string)) + ;; RTRIP-NEXT: (local $2 i32) + ;; RTRIP-NEXT: (local $3 i32) + ;; RTRIP-NEXT: (local $4 (ref string)) ;; RTRIP-NEXT: (stringview_wtf16.slice ;; RTRIP-NEXT: (block (result (ref string)) - ;; RTRIP-NEXT: (local.set $2 + ;; RTRIP-NEXT: (local.set $4 ;; RTRIP-NEXT: (string.const "abc") ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: (local.set $1 - ;; RTRIP-NEXT: (i32.const 1) + ;; RTRIP-NEXT: (block (result i32) + ;; RTRIP-NEXT: (local.set $3 + ;; RTRIP-NEXT: (i32.const 1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (local.set $2 + ;; RTRIP-NEXT: (local.get $end) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (local.get $3) + ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: ) - ;; RTRIP-NEXT: (local.get $2) + ;; RTRIP-NEXT: (local.get $4) ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: (local.get $1) - ;; RTRIP-NEXT: (local.get $end) + ;; RTRIP-NEXT: (local.get $2) ;; RTRIP-NEXT: ) ;; RTRIP-NEXT: ) ;; RRTRP: (func $slice-end-get (type $0) (result stringref) ;; RRTRP-NEXT: (local $end i32) ;; RRTRP-NEXT: (local $1 i32) - ;; RRTRP-NEXT: (local $2 (ref string)) - ;; RRTRP-NEXT: (local $3 (ref string)) + ;; RRTRP-NEXT: (local $2 i32) + ;; RRTRP-NEXT: (local $3 i32) + ;; RRTRP-NEXT: (local $4 (ref string)) + ;; RRTRP-NEXT: (local $5 i32) + ;; RRTRP-NEXT: (local $6 (ref string)) ;; RRTRP-NEXT: (stringview_wtf16.slice ;; RRTRP-NEXT: (block (result (ref string)) - ;; RRTRP-NEXT: (local.set $3 + ;; RRTRP-NEXT: (local.set $6 ;; RRTRP-NEXT: (string.const "abc") ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: (local.set $1 - ;; RRTRP-NEXT: (i32.const 1) + ;; RRTRP-NEXT: (block (result i32) + ;; RRTRP-NEXT: (local.set $5 + ;; RRTRP-NEXT: (i32.const 1) + ;; RRTRP-NEXT: ) + ;; RRTRP-NEXT: (local.set $2 + ;; RRTRP-NEXT: (local.get $end) + ;; RRTRP-NEXT: ) + ;; RRTRP-NEXT: (local.get $5) + ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: ) - ;; RRTRP-NEXT: (local.get $3) + ;; RRTRP-NEXT: (local.get $6) ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: (local.get $1) - ;; RRTRP-NEXT: (local.get $end) + ;; RRTRP-NEXT: (local.get $2) ;; RRTRP-NEXT: ) ;; RRTRP-NEXT: ) (func $slice-end-get (result stringref) From 2dcf67049ef4d2cbcb2a65d367be97ae675f9d8a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Jun 2024 14:13:52 -0700 Subject: [PATCH 376/553] wasm2js: Add Table operations (#6650) TableGet, Set, Size, Grow, Fill, Copy. Also move "null" into shared-constants, to make the code more consistent overall. --- src/abi/js.h | 13 ++++- src/asmjs/shared-constants.cpp | 4 ++ src/asmjs/shared-constants.h | 1 + src/wasm2js.h | 73 +++++++++++++++++++++------ test/wasm2js/tables.2asm.js | 89 +++++++++++++++++++++++++++++++++ test/wasm2js/tables.2asm.js.opt | 89 +++++++++++++++++++++++++++++++++ test/wasm2js/tables.wast | 46 +++++++++++++++++ 7 files changed, 298 insertions(+), 17 deletions(-) create mode 100644 test/wasm2js/tables.2asm.js create mode 100644 test/wasm2js/tables.2asm.js.opt create mode 100644 test/wasm2js/tables.wast diff --git a/src/abi/js.h b/src/abi/js.h index e121e9b2864..b8f56f14d64 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -36,6 +36,9 @@ extern IString SCRATCH_STORE_F64; extern IString MEMORY_INIT; extern IString MEMORY_FILL; extern IString MEMORY_COPY; +extern IString TABLE_GROW; +extern IString TABLE_FILL; +extern IString TABLE_COPY; extern IString DATA_DROP; extern IString ATOMIC_WAIT_I32; extern IString ATOMIC_RMW_I64; @@ -81,6 +84,13 @@ inline void ensureHelpers(Module* wasm, IString specific = IString()) { Type::i32); ensureImport(GET_STASHED_BITS, {}, Type::i32); ensureImport(TRAP, {}, Type::none); + + if (wasm->features.hasReferenceTypes()) { + auto funcref = Type(HeapType::func, Nullable); + ensureImport(TABLE_GROW, {funcref, Type::i32}, Type::none); + ensureImport(TABLE_FILL, {Type::i32, funcref, Type::i32}, Type::none); + ensureImport(TABLE_COPY, {Type::i32, Type::i32, Type::i32}, Type::none); + } } inline bool isHelper(IString name) { @@ -88,7 +98,8 @@ inline bool isHelper(IString name) { name == SCRATCH_LOAD_F32 || name == SCRATCH_STORE_F32 || name == SCRATCH_LOAD_F64 || name == SCRATCH_STORE_F64 || name == ATOMIC_WAIT_I32 || name == MEMORY_INIT || - name == MEMORY_FILL || name == MEMORY_COPY || name == DATA_DROP || + name == MEMORY_FILL || name == MEMORY_COPY || name == TABLE_GROW || + name == TABLE_FILL || name == TABLE_COPY || name == DATA_DROP || name == ATOMIC_RMW_I64 || name == GET_STASHED_BITS || name == TRAP; } diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 57b9c4f8790..bd924f17943 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -62,6 +62,7 @@ IString ENV("env"); IString STACKTOP("STACKTOP"); IString STACK_MAX("STACK_MAX"); IString INSTRUMENT("instrument"); +IString LENGTH("length"); IString MATH_IMUL("Math_imul"); IString MATH_ABS("Math_abs"); IString MATH_CEIL("Math_ceil"); @@ -111,6 +112,9 @@ IString SCRATCH_STORE_F64("wasm2js_scratch_store_f64"); IString MEMORY_INIT("wasm2js_memory_init"); IString MEMORY_FILL("wasm2js_memory_fill"); IString MEMORY_COPY("wasm2js_memory_copy"); +IString TABLE_GROW("wasm2js_table_grow"); +IString TABLE_FILL("wasm2js_table_fill"); +IString TABLE_COPY("wasm2js_table_copy"); IString DATA_DROP("wasm2js_data_drop"); IString ATOMIC_WAIT_I32("wasm2js_atomic_wait_i32"); IString ATOMIC_RMW_I64("wasm2js_atomic_rmw_i64"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index e199b1361d3..d48da560ec2 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -65,6 +65,7 @@ extern IString ENV; extern IString STACKTOP; extern IString STACK_MAX; extern IString INSTRUMENT; +extern IString LENGTH; extern IString MATH_IMUL; extern IString MATH_ABS; extern IString MATH_CLZ32; diff --git a/src/wasm2js.h b/src/wasm2js.h index 2084c04537c..dd4e61a51b3 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -672,12 +672,11 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { if (!table->imported()) { TableUtils::FlatTable flat(*wasm, *table); if (flat.valid) { - Name null("null"); for (auto& name : flat.names) { if (name.is()) { name = fromName(name, NameScope::Top); } else { - name = null; + name = NULL_; } ValueBuilder::appendToArray(theArray, ValueBuilder::makeName(name)); } @@ -2221,11 +2220,11 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, visit(curr->value, EXPRESSION_RESULT), visit(curr->size, EXPRESSION_RESULT)); } - Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName("null"); } + Ref visitRefNull(RefNull* curr) { return ValueBuilder::makeName(NULL_); } Ref visitRefIsNull(RefIsNull* curr) { return ValueBuilder::makeBinary(visit(curr->value, EXPRESSION_RESULT), EQ, - ValueBuilder::makeName("null")); + ValueBuilder::makeName(NULL_)); } Ref visitRefFunc(RefFunc* curr) { return ValueBuilder::makeName(fromName(curr->func, NameScope::Top)); @@ -2236,28 +2235,40 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, visit(curr->right, EXPRESSION_RESULT)); } Ref visitTableGet(TableGet* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), + visit(curr->index, EXPRESSION_RESULT)); } Ref visitTableSet(TableSet* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + auto sub = ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), + visit(curr->index, EXPRESSION_RESULT)); + auto value = visit(curr->value, EXPRESSION_RESULT); + return ValueBuilder::makeBinary(sub, SET, value); } Ref visitTableSize(TableSize* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + return ValueBuilder::makeDot(ValueBuilder::makeName(FUNCTION_TABLE), + ValueBuilder::makeName(LENGTH)); } Ref visitTableGrow(TableGrow* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_GROW); + // Also ensure fill, as grow calls fill internally. + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_GROW, + visit(curr->value, EXPRESSION_RESULT), + visit(curr->delta, EXPRESSION_RESULT)); } Ref visitTableFill(TableFill* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_FILL); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_FILL, + visit(curr->dest, EXPRESSION_RESULT), + visit(curr->value, EXPRESSION_RESULT), + visit(curr->size, EXPRESSION_RESULT)); } Ref visitTableCopy(TableCopy* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TABLE_COPY); + return ValueBuilder::makeCall(ABI::wasm2js::TABLE_COPY, + visit(curr->dest, EXPRESSION_RESULT), + visit(curr->source, EXPRESSION_RESULT), + visit(curr->size, EXPRESSION_RESULT)); } Ref visitTry(Try* curr) { unimplemented(curr); @@ -3024,6 +3035,36 @@ void Wasm2JSGlue::emitSpecialSupport() { function wasm2js_memory_copy(dest, source, size) { // TODO: traps on invalid things bufferView.copyWithin(dest, source, source + size); + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_GROW) { + out << R"( + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_FILL) { + out << R"( + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + )"; + } else if (import->base == ABI::wasm2js::TABLE_COPY) { + out << R"( + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } } )"; } else if (import->base == ABI::wasm2js::DATA_DROP) { diff --git a/test/wasm2js/tables.2asm.js b/test/wasm2js/tables.2asm.js new file mode 100644 index 00000000000..a7dd8fdd55e --- /dev/null +++ b/test/wasm2js/tables.2asm.js @@ -0,0 +1,89 @@ +import * as env from 'env'; + + + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } + } + +function asmFunc(imports) { + var env = imports.env; + var FUNCTION_TABLE = env.table; + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function table_get() { + return FUNCTION_TABLE[1]; + } + + function table_set() { + FUNCTION_TABLE[1] = table_set; + } + + function table_size() { + return FUNCTION_TABLE.length | 0; + } + + function table_grow() { + return wasm2js_table_grow(table_grow, 42) | 0; + } + + function table_fill(dest, value, size) { + dest = dest | 0; + size = size | 0; + wasm2js_table_fill(dest, value, size); + } + + function table_copy(dest, source, size) { + dest = dest | 0; + source = source | 0; + size = size | 0; + wasm2js_table_copy(dest, source, size); + } + + FUNCTION_TABLE[1] = table_get; + return { + "table_get": table_get, + "table_set": table_set, + "table_size": table_size, + "table_grow": table_grow, + "table_fill": table_fill, + "table_copy": table_copy + }; +} + +var retasmFunc = asmFunc({ + "env": env, +}); +export var table_get = retasmFunc.table_get; +export var table_set = retasmFunc.table_set; +export var table_size = retasmFunc.table_size; +export var table_grow = retasmFunc.table_grow; +export var table_fill = retasmFunc.table_fill; +export var table_copy = retasmFunc.table_copy; diff --git a/test/wasm2js/tables.2asm.js.opt b/test/wasm2js/tables.2asm.js.opt new file mode 100644 index 00000000000..f15b0cb1172 --- /dev/null +++ b/test/wasm2js/tables.2asm.js.opt @@ -0,0 +1,89 @@ +import * as env from 'env'; + + + function wasm2js_table_grow(value, delta) { + // TODO: traps on invalid things + var oldSize = FUNCTION_TABLE.length; + FUNCTION_TABLE.length = oldSize + delta; + if (newSize > oldSize) { + __wasm_table_fill(oldSize, value, delta) + } + return oldSize; + } + + function __wasm_table_fill(dest, value, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = value; + } + } + + function __wasm_table_copy(dest, source, size) { + // TODO: traps on invalid things + for (var i = 0; i < size; i++) { + FUNCTION_TABLE[dest + i] = FUNCTION_TABLE[source + i]; + } + } + +function asmFunc(imports) { + var env = imports.env; + var FUNCTION_TABLE = env.table; + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + function table_get() { + return FUNCTION_TABLE[1]; + } + + function table_set() { + FUNCTION_TABLE[1] = table_set; + } + + function table_size() { + return FUNCTION_TABLE.length | 0; + } + + function table_grow() { + return wasm2js_table_grow(table_grow, 42) | 0; + } + + function table_fill($0, $1, $2) { + $0 = $0 | 0; + $2 = $2 | 0; + wasm2js_table_fill($0, $1, $2); + } + + function table_copy($0, $1, $2) { + $0 = $0 | 0; + $1 = $1 | 0; + $2 = $2 | 0; + wasm2js_table_copy($0, $1, $2); + } + + FUNCTION_TABLE[1] = table_get; + return { + "table_get": table_get, + "table_set": table_set, + "table_size": table_size, + "table_grow": table_grow, + "table_fill": table_fill, + "table_copy": table_copy + }; +} + +var retasmFunc = asmFunc({ + "env": env, +}); +export var table_get = retasmFunc.table_get; +export var table_set = retasmFunc.table_set; +export var table_size = retasmFunc.table_size; +export var table_grow = retasmFunc.table_grow; +export var table_fill = retasmFunc.table_fill; +export var table_copy = retasmFunc.table_copy; diff --git a/test/wasm2js/tables.wast b/test/wasm2js/tables.wast new file mode 100644 index 00000000000..56e85e40d2f --- /dev/null +++ b/test/wasm2js/tables.wast @@ -0,0 +1,46 @@ +(module + (import "env" "table" (table $table 7 funcref)) + + (elem (i32.const 1) $table.get) + + (func $table.get (export "table.get") (result funcref) + (table.get $table + (i32.const 1) + ) + ) + + (func $table.set (export "table.set") + (table.set $table + (i32.const 1) + (ref.func $table.set) + ) + ) + + (func $table.size (export "table.size") (result i32) + (table.size $table) + ) + + (func $table.grow (export "table.grow") (result i32) + (table.grow $table + (ref.func $table.grow) + (i32.const 42) + ) + ) + + (func $table.fill (export "table.fill") (param $dest i32) (param $value funcref) (param $size i32) + (table.fill $table + (local.get $dest) + (local.get $value) + (local.get $size) + ) + ) + + (func $table.copy (export "table.copy") (param $dest i32) (param $source i32) (param $size i32) + (table.copy $table $table + (local.get $dest) + (local.get $source) + (local.get $size) + ) + ) +) + From 425ecc65dea1a26c5b3667a46926a9834834b5cc Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 11 Jun 2024 14:14:54 -0700 Subject: [PATCH 377/553] Fix wasm-split bug in absence of active element segments (#6651) The module splitting code incorrectly assumed that there would be at least one active element segment and failed to initialize the table slot manager with a function table if that was not the case. Fix the bug by setting the table even when there are no active segments and add a test. Fixes #6572 and #6637. --- src/ir/module-splitting.cpp | 20 +++++++---- test/lit/wasm-split/no-active-segment.wast | 41 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 test/lit/wasm-split/no-active-segment.wast diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 966fb677968..50809a9a4df 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -148,6 +148,8 @@ void TableSlotManager::addSlot(Name func, Slot slot) { TableSlotManager::TableSlotManager(Module& module) : module(module) { // TODO: Reject or handle passive element segments + // TODO: If reference types are enabled, just create a fresh table to make bad + // interactions with user code impossible. auto funcref = Type(HeapType::func, Nullable); auto it = std::find_if( module.tables.begin(), @@ -163,13 +165,17 @@ TableSlotManager::TableSlotManager(Module& module) : module(module) { activeTableSegments.push_back(segment); }); - // If there is exactly one table segment and that segment has a non-constant - // offset, append new items to the end of that segment. In all other cases, - // append new items at constant offsets after all existing items at constant - // offsets. - if (activeTableSegments.size() == 1 && - activeTableSegments[0]->type == funcref && - !activeTableSegments[0]->offset->is()) { + if (activeTableSegments.empty()) { + // There are no active segments, so we will lazily create one and start + // filling it at index 0. + activeBase = {activeTable->name, "", 0}; + } else if (activeTableSegments.size() == 1 && + activeTableSegments[0]->type == funcref && + !activeTableSegments[0]->offset->is()) { + // If there is exactly one table segment and that segment has a non-constant + // offset, append new items to the end of that segment. In all other cases, + // append new items at constant offsets after all existing items at constant + // offsets. assert(activeTableSegments[0]->offset->is() && "Unexpected initializer instruction"); activeSegment = activeTableSegments[0]; diff --git a/test/lit/wasm-split/no-active-segment.wast b/test/lit/wasm-split/no-active-segment.wast new file mode 100644 index 00000000000..ad83b0480a7 --- /dev/null +++ b/test/lit/wasm-split/no-active-segment.wast @@ -0,0 +1,41 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Test that splitting succeeds even if there are no active segments for the function table. + +;; RUN: wasm-split %s --split-funcs=foo -g -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY +;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY + +(module + (table 0 funcref) + (export "foo" (func $foo)) + ;; SECONDARY: (type $0 (func)) + + ;; SECONDARY: (import "primary" "table" (table $timport$0 1 funcref)) + + ;; SECONDARY: (elem $0 (i32.const 0) $foo) + + ;; SECONDARY: (func $foo + ;; SECONDARY-NEXT: (nop) + ;; SECONDARY-NEXT: ) + (func $foo + (nop) + ) +) +;; PRIMARY: (type $0 (func)) + +;; PRIMARY: (import "placeholder" "0" (func $placeholder_0)) + +;; PRIMARY: (table $0 1 funcref) + +;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0) + +;; PRIMARY: (export "foo" (func $0)) + +;; PRIMARY: (export "table" (table $0)) + +;; PRIMARY: (func $0 +;; PRIMARY-NEXT: (call_indirect (type $0) +;; PRIMARY-NEXT: (i32.const 0) +;; PRIMARY-NEXT: ) +;; PRIMARY-NEXT: ) From 475841dd5f0c50d7072f6dfc26dffd66e02abc10 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 11 Jun 2024 17:18:50 -0700 Subject: [PATCH 378/553] [Parser][NFC] Split parser into multiple compilation units (#6653) Because the parser has five stages, it requires instantiating all of the templates in parsers.h with up to five different contexts. Instantiating all those templates in a single compilation unit takes a long time. On my machine, a release build of wat-parser.cpp.o took 32 seconds. To reduce the time of incremental rebuilds on machines with many cores, split the code across several compilation units so that the templates need to be instantiated for just a single context in each unit. On my machine the longest compilation time after this splitting is 17 seconds. The time for a full release build also drops from 42 seconds to 33 seconds. On machines with fewer cores, the benefit may be smaller or even negative, though. --- src/parser/CMakeLists.txt | 5 + src/parser/parse-1-decls.cpp | 23 ++++ src/parser/parse-2-typedefs.cpp | 55 +++++++++ src/parser/parse-3-implicit-types.cpp | 35 ++++++ src/parser/parse-4-module-types.cpp | 41 +++++++ src/parser/parse-5-defs.cpp | 95 ++++++++++++++++ src/parser/parsers.h | 31 +----- src/parser/wat-parser-internal.h | 97 ++++++++++++++++ src/parser/wat-parser.cpp | 154 +++----------------------- 9 files changed, 369 insertions(+), 167 deletions(-) create mode 100644 src/parser/parse-1-decls.cpp create mode 100644 src/parser/parse-2-typedefs.cpp create mode 100644 src/parser/parse-3-implicit-types.cpp create mode 100644 src/parser/parse-4-module-types.cpp create mode 100644 src/parser/parse-5-defs.cpp create mode 100644 src/parser/wat-parser-internal.h diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index 9c54646e710..045948ba1bb 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -3,6 +3,11 @@ set(parser_SOURCES context-decls.cpp context-defs.cpp lexer.cpp + parse-1-decls.cpp + parse-2-typedefs.cpp + parse-3-implicit-types.cpp + parse-4-module-types.cpp + parse-5-defs.cpp wast-parser.cpp wat-parser.cpp ${parser_HEADERS} diff --git a/src/parser/parse-1-decls.cpp b/src/parser/parse-1-decls.cpp new file mode 100644 index 00000000000..1c753cc611a --- /dev/null +++ b/src/parser/parse-1-decls.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2024 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 "wat-parser-internal.h" + +namespace wasm::WATParser { + +Result<> parseDecls(ParseDeclsCtx& decls) { return module(decls); } + +} // namespace wasm::WATParser diff --git a/src/parser/parse-2-typedefs.cpp b/src/parser/parse-2-typedefs.cpp new file mode 100644 index 00000000000..90a84941d89 --- /dev/null +++ b/src/parser/parse-2-typedefs.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2024 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 "wat-parser-internal.h" + +namespace wasm::WATParser { + +Result<> parseTypeDefs( + ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map>& typeNames) { + TypeBuilder builder(decls.subtypeDefs.size()); + ParseTypeDefsCtx ctx(input, builder, typeIndices); + for (auto& typeDef : decls.typeDefs) { + WithPosition with(ctx, typeDef.pos); + CHECK_ERR(deftype(ctx)); + } + auto built = builder.build(); + if (auto* err = built.getError()) { + std::stringstream msg; + msg << "invalid type: " << err->reason; + return ctx.in.err(decls.typeDefs[err->index].pos, msg.str()); + } + types = *built; + // Record type names on the module and in typeNames. + for (size_t i = 0; i < types.size(); ++i) { + auto& names = ctx.names[i]; + auto& fieldNames = names.fieldNames; + if (names.name.is() || fieldNames.size()) { + decls.wasm.typeNames.insert({types[i], names}); + auto& fieldIdxMap = typeNames[types[i]]; + for (auto [idx, name] : fieldNames) { + fieldIdxMap.insert({name, idx}); + } + } + } + return Ok{}; +} + +} // namespace wasm::WATParser diff --git a/src/parser/parse-3-implicit-types.cpp b/src/parser/parse-3-implicit-types.cpp new file mode 100644 index 00000000000..3a3a867e151 --- /dev/null +++ b/src/parser/parse-3-implicit-types.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2024 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 "wat-parser-internal.h" + +namespace wasm::WATParser { + +Result<> +parseImplicitTypeDefs(ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes) { + ParseImplicitTypeDefsCtx ctx(input, types, implicitTypes, typeIndices); + for (Index pos : decls.implicitTypeDefs) { + WithPosition with(ctx, pos); + CHECK_ERR(typeuse(ctx)); + } + return Ok{}; +} + +} // namespace wasm::WATParser diff --git a/src/parser/parse-4-module-types.cpp b/src/parser/parse-4-module-types.cpp new file mode 100644 index 00000000000..04d8292d0bf --- /dev/null +++ b/src/parser/parse-4-module-types.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2024 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 "wat-parser-internal.h" + +namespace wasm::WATParser { + +Result<> parseModuleTypes(ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes) { + ParseModuleTypesCtx ctx(input, + decls.wasm, + types, + implicitTypes, + decls.implicitElemIndices, + typeIndices); + CHECK_ERR(parseDefs(ctx, decls.funcDefs, func)); + CHECK_ERR(parseDefs(ctx, decls.tableDefs, table)); + CHECK_ERR(parseDefs(ctx, decls.memoryDefs, memory)); + CHECK_ERR(parseDefs(ctx, decls.globalDefs, global)); + CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem)); + CHECK_ERR(parseDefs(ctx, decls.tagDefs, tag)); + return Ok{}; +} + +} // namespace wasm::WATParser diff --git a/src/parser/parse-5-defs.cpp b/src/parser/parse-5-defs.cpp new file mode 100644 index 00000000000..acc81bb75a4 --- /dev/null +++ b/src/parser/parse-5-defs.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2024 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 "wat-parser-internal.h" + +namespace wasm::WATParser { + +Result<> parseDefinitions( + ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes, + std::unordered_map>& typeNames) { + // Parse definitions. + // TODO: Parallelize this. + ParseDefsCtx ctx(input, + decls.wasm, + types, + implicitTypes, + typeNames, + decls.implicitElemIndices, + typeIndices); + CHECK_ERR(parseDefs(ctx, decls.tableDefs, table)); + CHECK_ERR(parseDefs(ctx, decls.globalDefs, global)); + CHECK_ERR(parseDefs(ctx, decls.startDefs, start)); + CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem)); + CHECK_ERR(parseDefs(ctx, decls.dataDefs, data)); + + for (Index i = 0; i < decls.funcDefs.size(); ++i) { + ctx.index = i; + auto* f = decls.wasm.functions[i].get(); + WithPosition with(ctx, decls.funcDefs[i].pos); + ctx.setSrcLoc(decls.funcDefs[i].annotations); + if (!f->imported()) { + CHECK_ERR(ctx.visitFunctionStart(f)); + } + if (auto parsed = func(ctx)) { + CHECK_ERR(parsed); + } else { + auto im = import_(ctx); + assert(im); + CHECK_ERR(im); + } + if (!f->imported()) { + auto end = ctx.irBuilder.visitEnd(); + if (auto* err = end.getErr()) { + return ctx.in.err(decls.funcDefs[i].pos, err->msg); + } + } + } + + // Parse exports. + // TODO: It would be more technically correct to interleave these properly + // with the implicit inline exports in other module field definitions. + for (auto pos : decls.exportDefs) { + WithPosition with(ctx, pos); + auto parsed = export_(ctx); + CHECK_ERR(parsed); + assert(parsed); + } + return Ok{}; +} + +Result parseConst(Lexer& lexer) { + Module wasm; + ParseDefsCtx ctx(lexer, wasm, {}, {}, {}, {}, {}); + auto inst = foldedinstr(ctx); + CHECK_ERR(inst); + auto expr = ctx.irBuilder.build(); + if (auto* err = expr.getErr()) { + return lexer.err(err->msg); + } + auto* e = *expr; + if (!e->is() && !e->is() && !e->is()) { + return lexer.err("expected constant"); + } + lexer = ctx.in; + return getLiteralFromConstExpression(e); +} + +} // namespace wasm::WATParser diff --git a/src/parser/parsers.h b/src/parser/parsers.h index ab990e7b0ac..c4eaf5fc60a 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -20,6 +20,7 @@ #include "common.h" #include "contexts.h" #include "lexer.h" +#include "wat-parser-internal.h" namespace wasm::WATParser { @@ -350,32 +351,6 @@ template MaybeResult<> tag(Ctx&); template MaybeResult<> modulefield(Ctx&); template Result<> module(Ctx&); -// ========= -// Utilities -// ========= - -// RAII utility for temporarily changing the parsing position of a parsing -// context. -template struct WithPosition { - Ctx& ctx; - Index original; - std::vector annotations; - - WithPosition(Ctx& ctx, Index pos) - : ctx(ctx), original(ctx.in.getPos()), - annotations(ctx.in.takeAnnotations()) { - ctx.in.setPos(pos); - } - - ~WithPosition() { - ctx.in.setPos(original); - ctx.in.setAnnotations(std::move(annotations)); - } -}; - -// Deduction guide to satisfy -Wctad-maybe-unsupported. -template WithPosition(Ctx& ctx, Index) -> WithPosition; - // ===== // Types // ===== @@ -2699,7 +2674,7 @@ Result typeuse(Ctx& ctx, bool allowNames) { } // ('(' 'import' mod:name nm:name ')')? -MaybeResult inlineImport(Lexer& in) { +inline MaybeResult inlineImport(Lexer& in) { if (!in.takeSExprStart("import"sv)) { return {}; } @@ -2719,7 +2694,7 @@ MaybeResult inlineImport(Lexer& in) { } // ('(' 'export' name ')')* -Result> inlineExports(Lexer& in) { +inline Result> inlineExports(Lexer& in) { std::vector exports; while (in.takeSExprStart("export"sv)) { auto name = in.takeName(); diff --git a/src/parser/wat-parser-internal.h b/src/parser/wat-parser-internal.h new file mode 100644 index 00000000000..00c96abd42e --- /dev/null +++ b/src/parser/wat-parser-internal.h @@ -0,0 +1,97 @@ +/* + * Copyright 2024 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 "contexts.h" +#include "parsers.h" + +#ifndef parser_wat_parser_internal_h +#define parser_wat_parser_internal_h + +namespace wasm::WATParser { + +Result<> parseDecls(ParseDeclsCtx& decls); + +Result<> parseTypeDefs( + ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map>& typeNames); + +Result<> +parseImplicitTypeDefs(ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes); + +Result<> parseModuleTypes(ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes); + +Result<> parseDefinitions( + ParseDeclsCtx& decls, + Lexer& input, + IndexMap& typeIndices, + std::vector& types, + std::unordered_map& implicitTypes, + std::unordered_map>& typeNames); + +// RAII utility for temporarily changing the parsing position of a parsing +// context. +template struct WithPosition { + Ctx& ctx; + Index original; + std::vector annotations; + + WithPosition(Ctx& ctx, Index pos) + : ctx(ctx), original(ctx.in.getPos()), + annotations(ctx.in.takeAnnotations()) { + ctx.in.setPos(pos); + } + + ~WithPosition() { + ctx.in.setPos(original); + ctx.in.setAnnotations(std::move(annotations)); + } +}; + +template +Result<> parseDefs(Ctx& ctx, + const std::vector& defs, + MaybeResult<> (*parser)(Ctx&)) { + for (auto& def : defs) { + ctx.index = def.index; + WithPosition with(ctx, def.pos); + if (auto parsed = parser(ctx)) { + CHECK_ERR(parsed); + } else { + auto im = import_(ctx); + assert(im); + CHECK_ERR(im); + } + } + return Ok{}; +} + +// Deduction guide to satisfy -Wctad-maybe-unsupported. +template WithPosition(Ctx& ctx, Index) -> WithPosition; + +} // namespace wasm::WATParser + +#endif // parser_wat_parser_internal_h diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp index 4763c69eccd..975cbd3c35b 100644 --- a/src/parser/wat-parser.cpp +++ b/src/parser/wat-parser.cpp @@ -18,10 +18,10 @@ #include "contexts.h" #include "ir/names.h" #include "lexer.h" -#include "parsers.h" #include "pass.h" #include "wasm-type.h" #include "wasm.h" +#include "wat-parser-internal.h" // The WebAssembly text format is recursive in the sense that elements may be // referred to before they are declared. Furthermore, elements may be referred @@ -73,24 +73,6 @@ Result createIndexMap(Lexer& in, const std::vector& defs) { return indices; } -template -Result<> parseDefs(Ctx& ctx, - const std::vector& defs, - MaybeResult<> (*parser)(Ctx&)) { - for (auto& def : defs) { - ctx.index = def.index; - WithPosition with(ctx, def.pos); - if (auto parsed = parser(ctx)) { - CHECK_ERR(parsed); - } else { - auto im = import_(ctx); - assert(im); - CHECK_ERR(im); - } - } - return Ok{}; -} - void propagateDebugLocations(Module& wasm) { // Copy debug locations from parents or previous siblings to expressions that // do not already have their own debug locations. @@ -101,10 +83,16 @@ void propagateDebugLocations(Module& wasm) { runner.run(); } +// Parse module-level declarations. + +// Parse type definitions. + +// Parse implicit type definitions and map typeuses without explicit types to +// the correct types. + Result<> doParseModule(Module& wasm, Lexer& input, bool allowExtra) { - // Parse module-level declarations. ParseDeclsCtx decls(input, wasm); - CHECK_ERR(module(decls)); + CHECK_ERR(parseDecls(decls)); if (!allowExtra && !decls.in.empty()) { return decls.in.err("Unexpected tokens after module"); } @@ -112,113 +100,18 @@ Result<> doParseModule(Module& wasm, Lexer& input, bool allowExtra) { auto typeIndices = createIndexMap(decls.in, decls.subtypeDefs); CHECK_ERR(typeIndices); - // Parse type definitions. std::vector types; std::unordered_map> typeNames; - { - TypeBuilder builder(decls.subtypeDefs.size()); - ParseTypeDefsCtx ctx(input, builder, *typeIndices); - for (auto& typeDef : decls.typeDefs) { - WithPosition with(ctx, typeDef.pos); - CHECK_ERR(deftype(ctx)); - } - auto built = builder.build(); - if (auto* err = built.getError()) { - std::stringstream msg; - msg << "invalid type: " << err->reason; - return ctx.in.err(decls.typeDefs[err->index].pos, msg.str()); - } - types = *built; - // Record type names on the module and in typeNames. - for (size_t i = 0; i < types.size(); ++i) { - auto& names = ctx.names[i]; - auto& fieldNames = names.fieldNames; - if (names.name.is() || fieldNames.size()) { - wasm.typeNames.insert({types[i], names}); - auto& fieldIdxMap = typeNames[types[i]]; - for (auto [idx, name] : fieldNames) { - fieldIdxMap.insert({name, idx}); - } - } - } - } + CHECK_ERR(parseTypeDefs(decls, input, *typeIndices, types, typeNames)); - // Parse implicit type definitions and map typeuses without explicit types to - // the correct types. std::unordered_map implicitTypes; + CHECK_ERR( + parseImplicitTypeDefs(decls, input, *typeIndices, types, implicitTypes)); - { - ParseImplicitTypeDefsCtx ctx(input, types, implicitTypes, *typeIndices); - for (Index pos : decls.implicitTypeDefs) { - WithPosition with(ctx, pos); - CHECK_ERR(typeuse(ctx)); - } - } - - { - // Parse module-level types. - ParseModuleTypesCtx ctx(input, - wasm, - types, - implicitTypes, - decls.implicitElemIndices, - *typeIndices); - CHECK_ERR(parseDefs(ctx, decls.funcDefs, func)); - CHECK_ERR(parseDefs(ctx, decls.tableDefs, table)); - CHECK_ERR(parseDefs(ctx, decls.memoryDefs, memory)); - CHECK_ERR(parseDefs(ctx, decls.globalDefs, global)); - CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem)); - CHECK_ERR(parseDefs(ctx, decls.tagDefs, tag)); - } - { - // Parse definitions. - // TODO: Parallelize this. - ParseDefsCtx ctx(input, - wasm, - types, - implicitTypes, - typeNames, - decls.implicitElemIndices, - *typeIndices); - CHECK_ERR(parseDefs(ctx, decls.tableDefs, table)); - CHECK_ERR(parseDefs(ctx, decls.globalDefs, global)); - CHECK_ERR(parseDefs(ctx, decls.startDefs, start)); - CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem)); - CHECK_ERR(parseDefs(ctx, decls.dataDefs, data)); - - for (Index i = 0; i < decls.funcDefs.size(); ++i) { - ctx.index = i; - auto* f = wasm.functions[i].get(); - WithPosition with(ctx, decls.funcDefs[i].pos); - ctx.setSrcLoc(decls.funcDefs[i].annotations); - if (!f->imported()) { - CHECK_ERR(ctx.visitFunctionStart(f)); - } - if (auto parsed = func(ctx)) { - CHECK_ERR(parsed); - } else { - auto im = import_(ctx); - assert(im); - CHECK_ERR(im); - } - if (!f->imported()) { - auto end = ctx.irBuilder.visitEnd(); - if (auto* err = end.getErr()) { - return ctx.in.err(decls.funcDefs[i].pos, err->msg); - } - } - } + CHECK_ERR(parseModuleTypes(decls, input, *typeIndices, types, implicitTypes)); - // Parse exports. - // TODO: It would be more technically correct to interleave these properly - // with the implicit inline exports in other module field definitions. - for (auto pos : decls.exportDefs) { - WithPosition with(ctx, pos); - auto parsed = export_(ctx); - CHECK_ERR(parsed); - assert(parsed); - } - } + CHECK_ERR(parseDefinitions( + decls, input, *typeIndices, types, implicitTypes, typeNames)); propagateDebugLocations(wasm); input = decls.in; @@ -237,21 +130,4 @@ Result<> parseModule(Module& wasm, Lexer& lexer) { return doParseModule(wasm, lexer, true); } -Result parseConst(Lexer& lexer) { - Module wasm; - ParseDefsCtx ctx(lexer, wasm, {}, {}, {}, {}, {}); - auto inst = foldedinstr(ctx); - CHECK_ERR(inst); - auto expr = ctx.irBuilder.build(); - if (auto* err = expr.getErr()) { - return lexer.err(err->msg); - } - auto* e = *expr; - if (!e->is() && !e->is() && !e->is()) { - return lexer.err("expected constant"); - } - lexer = ctx.in; - return getLiteralFromConstExpression(e); -} - } // namespace wasm::WATParser From ac21c8cc9204e09fab070d2fd915e7ab583a5dac Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Jun 2024 11:05:28 -0700 Subject: [PATCH 379/553] [DebugInfo] Copy debug info in call-utils.h (#6652) We automatically copy debuginfo in replaceCurrent(), but there are a few places that do other operations than simple replacements. call-utils.h will turn a call_ref with a select target into two direct calls, and we were missing the logic to copy debuginfo from the call_ref to the calls. To make this work, refactor out the copying logic from wasm-traversal, into debuginfo.h, and use it in call-utils.h. debuginfo.h itself is renamed from debug.h (as now this needs to be included from wasm-traversal, which nearly everything does, and it turns out some files have internal stuff like a debug() helper that ends up conflicing with the old debug namespace). Also rename the old copyDebugInfo function to copyDebugInfoBetweenFunctions which is more explicit. That is also moved from the header to a cpp file because it depends on wasm-traversal (so we'd end up with recursive headers otherwise). That is fine, as that method is called after copying a function, which is not that frequent. The new copyDebugInfoToReplacement (which was refactored out of wasm-traversal) is in the header because it can be called very frequently (every single instruction we optimize) and we want it to get inlined. --- src/ir/CMakeLists.txt | 1 + src/ir/{debug.h => debuginfo.cpp} | 21 +++--- src/ir/debuginfo.h | 72 +++++++++++++++++++ src/ir/module-utils.cpp | 4 +- src/passes/Inlining.cpp | 4 +- src/passes/call-utils.h | 14 ++-- src/wasm-traversal.h | 33 +-------- .../optimize-instructions-call_ref.wast | 25 ++++++- 8 files changed, 120 insertions(+), 54 deletions(-) rename src/ir/{debug.h => debuginfo.cpp} (79%) create mode 100644 src/ir/debuginfo.h diff --git a/src/ir/CMakeLists.txt b/src/ir/CMakeLists.txt index 279a1468c9e..996daa56416 100644 --- a/src/ir/CMakeLists.txt +++ b/src/ir/CMakeLists.txt @@ -2,6 +2,7 @@ FILE(GLOB ir_HEADERS *.h) set(ir_SOURCES ExpressionAnalyzer.cpp ExpressionManipulator.cpp + debuginfo.cpp drop.cpp effects.cpp eh-utils.cpp diff --git a/src/ir/debug.h b/src/ir/debuginfo.cpp similarity index 79% rename from src/ir/debug.h rename to src/ir/debuginfo.cpp index 04838137e63..a5fe92d54f4 100644 --- a/src/ir/debug.h +++ b/src/ir/debuginfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 WebAssembly Community Group participants + * Copyright 2024 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. @@ -14,16 +14,13 @@ * limitations under the License. */ -#ifndef wasm_ir_debug_h -#define wasm_ir_debug_h +#include "ir/debuginfo.h" +#include "wasm-traversal.h" +#include "wasm.h" -#include +namespace wasm::debuginfo { -namespace wasm::debug { - -// Given an expression and a copy of it in another function, copy the debug -// info into the second function. -inline void copyDebugInfo(Expression* origin, +void copyBetweenFunctions(Expression* origin, Expression* copy, Function* originFunc, Function* copyFunc) { @@ -52,8 +49,6 @@ inline void copyDebugInfo(Expression* origin, copyDebug[copyList.list[i]] = location; } } -}; - -} // namespace wasm::debug +} -#endif // wasm_ir_debug_h +} // namespace wasm::debuginfo diff --git a/src/ir/debuginfo.h b/src/ir/debuginfo.h new file mode 100644 index 00000000000..96c4d8c2a92 --- /dev/null +++ b/src/ir/debuginfo.h @@ -0,0 +1,72 @@ +/* + * Copyright 2019 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. + */ + +#ifndef wasm_ir_debuginfo_h +#define wasm_ir_debuginfo_h + +#include "wasm.h" + +namespace wasm::debuginfo { + +// Given an original expression and another that replaces it, copy the debuginfo +// from the former to the latter. Note the expression may not be an exclusive +// replacement of the other (the other may be replaced by several expressions, +// all of whom may end up with the same debug info). +inline void copyOriginalToReplacement(Expression* original, + Expression* replacement, + Function* func) { + auto& debugLocations = func->debugLocations; + // Early exit if there is no debug info at all. Also, leave if we already + // have debug info on the new replacement, which we don't want to trample: + // if there is no debug info we do want to copy, as a replacement operation + // suggests the new code plays the same role (it is an optimized version of + // the old), but if the code is already annotated, trust that. + if (debugLocations.empty() || debugLocations.count(replacement)) { + return; + } + + auto iter = debugLocations.find(original); + if (iter != debugLocations.end()) { + debugLocations[replacement] = iter->second; + // Note that we do *not* erase the debug info of the expression being + // replaced, because it may still exist: we might replace + // + // (call + // (block .. + // + // with + // + // (block + // (call .. + // + // We still want the call here to have its old debug info. + // + // (In most cases, of course, we do remove the replaced expression, + // which means we accumulate unused garbage in debugLocations, but + // that's not that bad; we use arena allocation for Expressions, after + // all.) + } +} + +// Given an expression and a copy of it in another function, copy the debug +// info into the second function. +void copyBetweenFunctions(Expression* origin, + Expression* copy, + Function* originFunc, + Function* copyFunc); +} // namespace wasm::debuginfo + +#endif // wasm_ir_debuginfo_h diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 99652ceff8d..5791ed77c66 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -15,7 +15,7 @@ */ #include "module-utils.h" -#include "ir/debug.h" +#include "ir/debuginfo.h" #include "ir/intrinsics.h" #include "ir/manipulation.h" #include "ir/properties.h" @@ -54,7 +54,7 @@ Function* copyFunction(Function* func, ret->localNames = func->localNames; ret->localIndices = func->localIndices; ret->body = ExpressionManipulator::copy(func->body, out); - debug::copyDebugInfo(func->body, ret->body, func, ret.get()); + debuginfo::copyBetweenFunctions(func->body, ret->body, func, ret.get()); ret->prologLocation = func->prologLocation; ret->epilogLocation = func->epilogLocation; // Update file indices if needed diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 04bc6d78a19..9e0d3eb6740 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -31,7 +31,7 @@ #include #include "ir/branch-utils.h" -#include "ir/debug.h" +#include "ir/debuginfo.h" #include "ir/drop.h" #include "ir/eh-utils.h" #include "ir/element-utils.h" @@ -579,7 +579,7 @@ static Expression* doInlining(Module* module, // Generate and update the inlined contents auto* contents = ExpressionManipulator::copy(from->body, *module); - debug::copyDebugInfo(from->body, contents, from, into); + debuginfo::copyBetweenFunctions(from->body, contents, from, into); updater.walk(contents); block->list.push_back(contents); block->type = retType; diff --git a/src/passes/call-utils.h b/src/passes/call-utils.h index 7f2ebfda300..10106a75658 100644 --- a/src/passes/call-utils.h +++ b/src/passes/call-utils.h @@ -19,6 +19,7 @@ #include +#include "ir/debuginfo.h" #include "ir/type-updating.h" #include "wasm.h" @@ -130,14 +131,17 @@ convertToDirectCalls(T* curr, }; auto makeCall = [&](IndirectCallInfo info) -> Expression* { + Expression* ret; if (std::get_if(&info)) { - return builder.makeUnreachable(); + ret = builder.makeUnreachable(); } else { - return builder.makeCall(std::get(info).target, - getOperands(), - curr->type, - curr->isReturn); + ret = builder.makeCall(std::get(info).target, + getOperands(), + curr->type, + curr->isReturn); } + debuginfo::copyOriginalToReplacement(curr, ret, &func); + return ret; }; auto* ifTrueCall = makeCall(ifTrueCallInfo); auto* ifFalseCall = makeCall(ifFalseCallInfo); diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 8e99749b655..db9d1c1c4f9 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -27,6 +27,7 @@ #ifndef wasm_wasm_traversal_h #define wasm_wasm_traversal_h +#include "ir/debuginfo.h" #include "support/small_vector.h" #include "support/threads.h" #include "wasm.h" @@ -123,36 +124,8 @@ struct Walker : public VisitorType { Expression* replaceCurrent(Expression* expression) { // Copy debug info, if present. if (currFunction) { - auto& debugLocations = currFunction->debugLocations; - // Early exit if there is no debug info at all. Also, leave if we already - // have debug info on the new expression, which we don't want to trample: - // if there is no debug info we do want to copy, as a replacement - // operation suggests the new code plays the same role (it is an optimized - // version of the old), but if the code is already annotated, trust that. - if (!debugLocations.empty() && !debugLocations.count(expression)) { - auto* curr = getCurrent(); - auto iter = debugLocations.find(curr); - if (iter != debugLocations.end()) { - debugLocations[expression] = iter->second; - // Note that we do *not* erase the debug info of the expression being - // replaced, because it may still exist: we might replace - // - // (call - // (block .. - // - // with - // - // (block - // (call .. - // - // We still want the call here to have its old debug info. - // - // (In most cases, of course, we do remove the replaced expression, - // which means we accumulate unused garbage in debugLocations, but - // that's not that bad; we use arena allocation for Expressions, after - // all.) - } - } + debuginfo::copyOriginalToReplacement( + getCurrent(), expression, currFunction); } return *replacep = expression; } diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast index 94c61433fb2..91aba5fed8e 100644 --- a/test/lit/passes/optimize-instructions-call_ref.wast +++ b/test/lit/passes/optimize-instructions-call_ref.wast @@ -44,13 +44,16 @@ ) ;; CHECK: (func $call_ref-to-direct (type $i32_i32_=>_none) (param $x i32) (param $y i32) + ;; CHECK-NEXT: ;;@ file.cpp:10:1 ;; CHECK-NEXT: (call $foo ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call_ref-to-direct (param $x i32) (param $y i32) - ;; This call_ref should become a direct call. + ;; This call_ref should become a direct call. The debuginfo should transfer as + ;; well. + ;;@ file.cpp:10:1 (call_ref $i32_i32_=>_none (local.get $x) (local.get $y) @@ -253,29 +256,42 @@ ;; CHECK: (func $call_ref-to-select (type $5) (param $x i32) (param $y i32) (param $z i32) (param $f (ref $i32_i32_=>_none)) ;; CHECK-NEXT: (local $4 i32) ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: ;;@ file.cpp:20:2 ;; CHECK-NEXT: (block + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: ;;@ file.cpp:20:2 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: ;;@ file.cpp:20:2 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (if + ;; CHECK-NEXT: ;;@ file.cpp:20:2 ;; CHECK-NEXT: (local.get $z) ;; CHECK-NEXT: (then ;; CHECK-NEXT: (call $foo + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (else + ;; CHECK-NEXT: ;;@ file.cpp:20:2 ;; CHECK-NEXT: (call $bar + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ;;@ ;; CHECK-NEXT: (local.get $5) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ;;@ file.cpp:30:3 ;; CHECK-NEXT: (call_ref $i32_i32_=>_none ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (local.get $y) @@ -287,7 +303,11 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $call_ref-to-select (param $x i32) (param $y i32) (param $z i32) (param $f (ref $i32_i32_=>_none)) - ;; This call_ref should become an if over two direct calls. + ;; This call_ref should become an if over two direct calls. The debuginfo + ;; should transfer as well to the two new calls (and some of the new helper + ;; code that is generated, but the critical part is the call_ref is being + ;; replaced by two calls, which should have the same info). + ;;@ file.cpp:20:2 (call_ref $i32_i32_=>_none (local.get $x) (local.get $y) @@ -299,6 +319,7 @@ ) ;; But here one arm is not constant, so we do not optimize. + ;;@ file.cpp:30:3 (call_ref $i32_i32_=>_none (local.get $x) (local.get $y) From 0e1187664ebf93bd268ba7d77813441a4874d998 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 12 Jun 2024 12:30:28 -0700 Subject: [PATCH 380/553] [threads] Parse, build, and print shared composite types (#6654) Parse the text format for shared composite types as described in the shared-everything thread proposal. Update the parser to use 'comptype' instead of 'strtype' to match the final GC spec and add the new syntactic class 'sharecomptype'. Update the type canonicalization logic to take sharedness into account to avoid merging shared and unshared types. Make the same change in the TypeMerging pass. Ensure that shared and unshared types cannot be in a subtype relationship with each other. Follow-up PRs will add shared abstract heap types, binary parsing and emitting for shared types, and fuzzer support for shared types. --- src/ir/type-updating.cpp | 1 + src/parser/contexts.h | 3 + src/parser/parsers.h | 36 ++++++++---- src/passes/TypeMerging.cpp | 4 ++ src/wasm-type.h | 11 +++- src/wasm/wasm-type.cpp | 28 +++++++++ test/gtest/type-builder.cpp | 34 +++++++++++ test/lit/passes/type-merging-shared.wast | 74 ++++++++++++++++++++++++ 8 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 test/lit/passes/type-merging-shared.wast diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 520408d449f..d9935ee32d8 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -90,6 +90,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( i = 0; for (auto [type, _] : typeIndices) { typeBuilder[i].setOpen(type.isOpen()); + typeBuilder[i].setShared(type.isShared()); if (type.isSignature()) { auto sig = type.getSignature(); TypeList newParams, newResults; diff --git a/src/parser/contexts.h b/src/parser/contexts.h index bce051a934c..7c1a07b5361 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -907,6 +907,7 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { void addStructType(StructT) {} void addArrayType(ArrayT) {} void setOpen() {} + void setShared() {} Result<> addSubtype(Index) { return Ok{}; } void finishSubtype(Name name, Index pos) { // TODO: type annotations @@ -1077,6 +1078,8 @@ struct ParseTypeDefsCtx : TypeParserCtx { void setOpen() { builder[index].setOpen(); } + void setShared() { builder[index].setShared(); } + Result<> addSubtype(Index super) { if (super >= builder.size()) { return in.err("supertype index out of bounds"); diff --git a/src/parser/parsers.h b/src/parser/parsers.h index c4eaf5fc60a..a3fe5e5eb57 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -331,7 +331,8 @@ template Result typeuse(Ctx&, bool allowNames = true); MaybeResult inlineImport(Lexer&); Result> inlineExports(Lexer&); -template Result<> strtype(Ctx&); +template Result<> comptype(Ctx&); +template Result<> sharecomptype(Ctx&); template MaybeResult subtype(Ctx&); template MaybeResult<> deftype(Ctx&); template MaybeResult locals(Ctx&); @@ -2709,11 +2710,11 @@ inline Result> inlineExports(Lexer& in) { return exports; } -// strtype ::= ft:functype => ft -// | ct:conttype => ct -// | st:structtype => st -// | at:arraytype => at -template Result<> strtype(Ctx& ctx) { +// comptype ::= ft:functype => ft +// | ct:conttype => ct +// | st:structtype => st +// | at:arraytype => at +template Result<> comptype(Ctx& ctx) { if (auto type = functype(ctx)) { CHECK_ERR(type); ctx.addFuncType(*type); @@ -2737,8 +2738,23 @@ template Result<> strtype(Ctx& ctx) { return ctx.in.err("expected type description"); } -// subtype ::= '(' 'type' id? '(' 'sub' typeidx? strtype ')' ')' -// | '(' 'type' id? strtype ')' +// sharecomptype ::= '(' 'shared' t:comptype ')' => shared t +// | t:comptype => unshared t +template Result<> sharecomptype(Ctx& ctx) { + if (ctx.in.takeSExprStart("shared"sv)) { + ctx.setShared(); + CHECK_ERR(comptype(ctx)); + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of shared comptype"); + } + } else { + CHECK_ERR(comptype(ctx)); + } + return Ok{}; +} + +// subtype ::= '(' 'type' id? '(' 'sub' typeidx? sharecomptype ')' ')' +// | '(' 'type' id? sharecomptype ')' template MaybeResult<> subtype(Ctx& ctx) { auto pos = ctx.in.getPos(); @@ -2760,13 +2776,13 @@ template MaybeResult<> subtype(Ctx& ctx) { CHECK_ERR(ctx.addSubtype(*super)); } - CHECK_ERR(strtype(ctx)); + CHECK_ERR(sharecomptype(ctx)); if (!ctx.in.takeRParen()) { return ctx.in.err("expected end of subtype definition"); } } else { - CHECK_ERR(strtype(ctx)); + CHECK_ERR(sharecomptype(ctx)); } if (!ctx.in.takeRParen()) { diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index f827e097c46..e5ac7888bdd 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -541,6 +541,9 @@ bool shapeEq(HeapType a, HeapType b) { if (a.isOpen() != b.isOpen()) { return false; } + if (a.isShared() != b.isShared()) { + return false; + } if (a.isStruct() && b.isStruct()) { return shapeEq(a.getStruct(), b.getStruct()); } @@ -555,6 +558,7 @@ bool shapeEq(HeapType a, HeapType b) { size_t shapeHash(HeapType a) { size_t digest = hash(a.isOpen()); + rehash(digest, a.isShared()); if (a.isStruct()) { rehash(digest, 0); hash_combine(digest, shapeHash(a.getStruct())); diff --git a/src/wasm-type.h b/src/wasm-type.h index b02484ae3fa..3e9fa4db342 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -377,6 +377,7 @@ class HeapType { bool isString() const; bool isBottom() const; bool isOpen() const; + bool isShared() const; Signature getSignature() const; Continuation getContinuation() const; @@ -614,9 +615,8 @@ struct TypeBuilder { Type getTempTupleType(const Tuple&); Type getTempRefType(HeapType heapType, Nullability nullable); - // In nominal mode, or for nominal types, declare the HeapType being built at - // index `i` to be an immediate subtype of the given HeapType. Does nothing - // for equirecursive types. + // Declare the HeapType being built at index `i` to be an immediate subtype of + // the given HeapType. void setSubType(size_t i, HeapType super); // Create a new recursion group covering slots [i, i + length). Groups must @@ -624,6 +624,7 @@ struct TypeBuilder { void createRecGroup(size_t i, size_t length); void setOpen(size_t i, bool open = true); + void setShared(size_t i, bool shared = true); enum class ErrorReason { // There is a cycle in the supertype relation. @@ -696,6 +697,10 @@ struct TypeBuilder { builder.setOpen(index, open); return *this; } + Entry& setShared(bool shared = true) { + builder.setShared(index, shared); + return *this; + } }; Entry operator[](size_t i) { return Entry{*this, i}; } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 3e215b23ac9..83bf47107a5 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -86,6 +86,7 @@ struct HeapTypeInfo { // global store. bool isTemp = false; bool isOpen = false; + bool isShared = false; // The supertype of this HeapType, if it exists. HeapTypeInfo* supertype = nullptr; // The recursion group of this type or null if the recursion group is trivial @@ -1251,6 +1252,15 @@ bool HeapType::isOpen() const { } } +bool HeapType::isShared() const { + if (isBasic()) { + // TODO: shared basic heap types + return false; + } else { + return getHeapTypeInfo(*this)->isShared; + } +} + Signature HeapType::getSignature() const { assert(isSignature()); return getHeapTypeInfo(*this)->signature; @@ -1953,6 +1963,9 @@ std::ostream& TypePrinter::print(HeapType type) { os << ' '; } } + if (type.isShared()) { + os << "(shared "; + } if (type.isSignature()) { print(type.getSignature()); } else if (type.isContinuation()) { @@ -1964,6 +1977,9 @@ std::ostream& TypePrinter::print(HeapType type) { } else { WASM_UNREACHABLE("unexpected type"); } + if (type.isShared()) { + os << ')'; + } if (useSub) { os << ')'; } @@ -2121,6 +2137,7 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const { hash_combine(digest, hash(HeapType(uintptr_t(info.supertype)))); } wasm::rehash(digest, info.isOpen); + wasm::rehash(digest, info.isShared); wasm::rehash(digest, info.kind); switch (info.kind) { case HeapTypeInfo::SignatureKind: @@ -2257,6 +2274,9 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const { if (a.isOpen != b.isOpen) { return false; } + if (a.isShared != b.isShared) { + return false; + } if (a.kind != b.kind) { return false; } @@ -2532,12 +2552,20 @@ void TypeBuilder::setOpen(size_t i, bool open) { impl->entries[i].info->isOpen = open; } +void TypeBuilder::setShared(size_t i, bool shared) { + assert(i < size() && "index out of bounds"); + impl->entries[i].info->isShared = shared; +} + namespace { bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { if (!super.isOpen) { return false; } + if (sub.isShared != super.isShared) { + return false; + } if (sub.kind != super.kind) { return false; } diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index 443a7ee66bb..c0a27b22923 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -273,6 +273,40 @@ TEST_F(TypeTest, InvalidFinalSupertype) { EXPECT_EQ(error->index, 1u); } +TEST_F(TypeTest, InvalidSharedSupertype) { + TypeBuilder builder(2); + builder[0] = Struct{}; + builder[1] = Struct{}; + builder[0].setShared(true); + builder[1].setShared(false); + builder[1].subTypeOf(builder[0]); + + auto result = builder.build(); + EXPECT_FALSE(result); + + const auto* error = result.getError(); + ASSERT_TRUE(error); + EXPECT_EQ(error->reason, TypeBuilder::ErrorReason::InvalidSupertype); + EXPECT_EQ(error->index, 1u); +} + +TEST_F(TypeTest, InvalidUnsharedSupertype) { + TypeBuilder builder(2); + builder[0] = Struct{}; + builder[1] = Struct{}; + builder[0].setShared(false); + builder[1].setShared(true); + builder[1].subTypeOf(builder[0]); + + auto result = builder.build(); + EXPECT_FALSE(result); + + const auto* error = result.getError(); + ASSERT_TRUE(error); + EXPECT_EQ(error->reason, TypeBuilder::ErrorReason::InvalidSupertype); + EXPECT_EQ(error->index, 1u); +} + TEST_F(TypeTest, ForwardReferencedChild) { TypeBuilder builder(3); builder.createRecGroup(0, 2); diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast new file mode 100644 index 00000000000..aefeccc3b1f --- /dev/null +++ b/test/lit/passes/type-merging-shared.wast @@ -0,0 +1,74 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: foreach %s %t wasm-opt --closed-world --type-merging --remove-unused-types -all -S -o - | filecheck %s + +(module + ;; Shared and non-shared types are not merged. + ;; CHECK: (rec + ;; CHECK-NEXT: (type $C' (shared (func))) + + ;; CHECK: (type $B' (shared (array i8))) + + ;; CHECK: (type $B (array i8)) + + ;; CHECK: (type $A' (shared (struct ))) + + ;; CHECK: (type $A (struct )) + (type $A (struct)) + (type $A' (shared (struct))) + (type $B (array i8)) + (type $B' (shared (array i8))) + ;; CHECK: (type $C (func)) + (type $C (func)) + (type $C' (shared (func))) + + ;; CHECK: (func $foo (type $C) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $a' (ref null $A')) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $b' (ref null $B')) + ;; CHECK-NEXT: (local $c (ref null $C)) + ;; CHECK-NEXT: (local $c' (ref null $C')) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + (local $a (ref null $A)) + (local $a' (ref null $A')) + (local $b (ref null $B)) + (local $b' (ref null $B')) + (local $c (ref null $C)) + (local $c' (ref null $C')) + ) +) + +(module + ;; But two shared types can be merged. + ;; CHECK: (rec + ;; CHECK-NEXT: (type $B (shared (array i8))) + + ;; CHECK: (type $A (shared (struct ))) + (type $A (shared (struct))) + (type $A' (shared (struct))) + (type $B (shared (array i8))) + (type $B' (shared (array i8))) + ;; CHECK: (type $C (shared (func))) + (type $C (shared (func))) + (type $C' (shared (func))) + + ;; CHECK: (func $foo (type $C) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $a' (ref null $A)) + ;; CHECK-NEXT: (local $b (ref null $B)) + ;; CHECK-NEXT: (local $b' (ref null $B)) + ;; CHECK-NEXT: (local $c (ref null $C)) + ;; CHECK-NEXT: (local $c' (ref null $C)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + (local $a (ref null $A)) + (local $a' (ref null $A')) + (local $b (ref null $B)) + (local $b' (ref null $B')) + (local $c (ref null $C)) + (local $c' (ref null $C')) + ) +) From 34686197f5a05854c0723214f3fdffbc9b19a7d5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Jun 2024 14:25:50 -0700 Subject: [PATCH 381/553] wasm2js: Fix null handling and RefAsNonNull (#6656) --- src/emscripten-optimizer/optimizer-shared.cpp | 12 ++--- src/wasm2js.h | 46 +++++++++++-------- test/wasm2js/refs.2asm.js | 20 +++++++- test/wasm2js/refs.2asm.js.opt | 20 +++++++- test/wasm2js/refs.wast | 19 ++++++++ 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/emscripten-optimizer/optimizer-shared.cpp b/src/emscripten-optimizer/optimizer-shared.cpp index 773c5d9fc27..f4482aa0911 100644 --- a/src/emscripten-optimizer/optimizer-shared.cpp +++ b/src/emscripten-optimizer/optimizer-shared.cpp @@ -17,6 +17,7 @@ #include #include "optimizer.h" +#include "shared-constants.h" #include "support/safe_integer.h" using namespace cashew; @@ -33,17 +34,14 @@ Ref makeJsCoercedZero(JsType type) { switch (type) { case JS_INT: return ValueBuilder::makeNum(0); - break; case JS_DOUBLE: return ValueBuilder::makeUnary(PLUS, ValueBuilder::makeNum(0)); - break; case JS_FLOAT: { if (!JS_FLOAT_ZERO.isNull()) { return ValueBuilder::makeName(JS_FLOAT_ZERO); } else { return ValueBuilder::makeCall(MATH_FROUND, ValueBuilder::makeNum(0)); } - break; } case JS_FLOAT32X4: { return ValueBuilder::makeCall(SIMD_FLOAT32X4, @@ -51,12 +49,10 @@ Ref makeJsCoercedZero(JsType type) { ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); - break; } case JS_FLOAT64X2: { return ValueBuilder::makeCall( SIMD_FLOAT64X2, ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); - break; } case JS_INT8X16: { return ValueBuilder::makeCall(SIMD_INT8X16, @@ -76,7 +72,6 @@ Ref makeJsCoercedZero(JsType type) { ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); - break; } case JS_INT16X8: { return ValueBuilder::makeCall(SIMD_INT16X8, @@ -88,7 +83,6 @@ Ref makeJsCoercedZero(JsType type) { ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); - break; } case JS_INT32X4: { return ValueBuilder::makeCall(SIMD_INT32X4, @@ -96,7 +90,9 @@ Ref makeJsCoercedZero(JsType type) { ValueBuilder::makeNum(0), ValueBuilder::makeNum(0), ValueBuilder::makeNum(0)); - break; + } + case JS_REF: { + return ValueBuilder::makeName(wasm::NULL_); } default: assert(0); diff --git a/src/wasm2js.h b/src/wasm2js.h index dd4e61a51b3..034212b79d7 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -846,44 +846,45 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { } void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) { - if (auto* const_ = global->init->dynCast()) { - Ref theValue; + Ref theVar = ValueBuilder::makeVar(); + ast->push_back(theVar); + + auto* init = global->init; + Ref value; + + if (auto* const_ = init->dynCast()) { TODO_SINGLE_COMPOUND(const_->type); switch (const_->type.getBasic()) { case Type::i32: { - theValue = ValueBuilder::makeInt(const_->value.geti32()); + value = ValueBuilder::makeInt(const_->value.geti32()); break; } case Type::f32: { - theValue = ValueBuilder::makeCall( + value = ValueBuilder::makeCall( MATH_FROUND, makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf32()), JS_DOUBLE)); break; } case Type::f64: { - theValue = makeJsCoercion( - ValueBuilder::makeDouble(const_->value.getf64()), JS_DOUBLE); + value = makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf64()), + JS_DOUBLE); break; } default: { assert(false && "Top const type not supported"); } } - Ref theVar = ValueBuilder::makeVar(); - ast->push_back(theVar); - ValueBuilder::appendToVar( - theVar, fromName(global->name, NameScope::Top), theValue); - } else if (auto* get = global->init->dynCast()) { - Ref theVar = ValueBuilder::makeVar(); - ast->push_back(theVar); - ValueBuilder::appendToVar( - theVar, - fromName(global->name, NameScope::Top), - ValueBuilder::makeName(fromName(get->name, NameScope::Top))); + } else if (auto* get = init->dynCast()) { + value = ValueBuilder::makeName(fromName(get->name, NameScope::Top)); + } else if (init->is()) { + value = ValueBuilder::makeName(NULL_); } else { assert(false && "Top init type not supported"); } + + ValueBuilder::appendToVar( + theVar, fromName(global->name, NameScope::Top), value); } Ref Wasm2JSBuilder::processFunction(Module* m, @@ -2415,8 +2416,15 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, WASM_UNREACHABLE("unimp"); } Ref visitRefAs(RefAs* curr) { - unimplemented(curr); - WASM_UNREACHABLE("unimp"); + // TODO: support others + assert(curr->op == RefAsNonNull); + + // value || trap() + ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::TRAP); + return ValueBuilder::makeBinary( + visit(curr->value, EXPRESSION_RESULT), + IString("||"), + ValueBuilder::makeCall(ABI::wasm2js::TRAP)); } Ref visitContBind(ContBind* curr) { diff --git a/test/wasm2js/refs.2asm.js b/test/wasm2js/refs.2asm.js index 0133159b9e9..f538df6d6df 100644 --- a/test/wasm2js/refs.2asm.js +++ b/test/wasm2js/refs.2asm.js @@ -1,4 +1,6 @@ +function wasm2js_trap() { throw new Error('abort'); } + function asmFunc(imports) { var Math_imul = Math.imul; var Math_fround = Math.fround; @@ -10,6 +12,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; + var global = null; function null_() { return null; } @@ -28,11 +31,24 @@ function asmFunc(imports) { return x == y | 0; } + function ref_as(x) { + return x || wasm2js_trap(); + } + + function use_global(x) { + var temp = null; + temp = global; + global = x; + return temp; + } + return { "null_": null_, "is_null": is_null, "ref_func": ref_func, - "ref_eq": ref_eq + "ref_eq": ref_eq, + "ref_as": ref_as, + "use_global": use_global }; } @@ -42,3 +58,5 @@ export var null_ = retasmFunc.null_; export var is_null = retasmFunc.is_null; export var ref_func = retasmFunc.ref_func; export var ref_eq = retasmFunc.ref_eq; +export var ref_as = retasmFunc.ref_as; +export var use_global = retasmFunc.use_global; diff --git a/test/wasm2js/refs.2asm.js.opt b/test/wasm2js/refs.2asm.js.opt index e38afe1cf6f..251e63475e1 100644 --- a/test/wasm2js/refs.2asm.js.opt +++ b/test/wasm2js/refs.2asm.js.opt @@ -1,4 +1,6 @@ +function wasm2js_trap() { throw new Error('abort'); } + function asmFunc(imports) { var Math_imul = Math.imul; var Math_fround = Math.fround; @@ -10,6 +12,7 @@ function asmFunc(imports) { var Math_ceil = Math.ceil; var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; + var global = null; function null_() { return null; } @@ -26,11 +29,24 @@ function asmFunc(imports) { return $0 == $1 | 0; } + function ref_as($0) { + return $0 || wasm2js_trap(); + } + + function use_global($0) { + var $1 = null; + $1 = global; + global = $0; + return $1; + } + return { "null_": null_, "is_null": is_null, "ref_func": ref_func, - "ref_eq": ref_eq + "ref_eq": ref_eq, + "ref_as": ref_as, + "use_global": use_global }; } @@ -40,3 +56,5 @@ export var null_ = retasmFunc.null_; export var is_null = retasmFunc.is_null; export var ref_func = retasmFunc.ref_func; export var ref_eq = retasmFunc.ref_eq; +export var ref_as = retasmFunc.ref_as; +export var use_global = retasmFunc.use_global; diff --git a/test/wasm2js/refs.wast b/test/wasm2js/refs.wast index 4e133c03efe..964d0a60c97 100644 --- a/test/wasm2js/refs.wast +++ b/test/wasm2js/refs.wast @@ -1,4 +1,6 @@ (module + (global $global (mut anyref) (ref.null any)) + (func $null (export "null") (result anyref) (ref.null any) ) @@ -30,4 +32,21 @@ (local.get $y) ) ) + + (func $ref.as (export "ref.as") (param $x anyref) (result anyref) + (ref.as_non_null + (local.get $x) + ) + ) + + (func $use-global (export "use-global") (param $x anyref) (result anyref) + (local $temp anyref) + (local.set $temp + (global.get $global) + ) + (global.set $global + (local.get $x) + ) + (local.get $temp) + ) ) From 66610d84bc466d0826803d8e2951af48ca2f1bae Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 13 Jun 2024 10:28:32 -0700 Subject: [PATCH 382/553] Add local.set/tee local type annotations to BINARYEN_PRINT_FULL (#6657) With this we now print e.g. (local.set $temp (; local type: i32 ;) ... This can be nice in large functions to avoid needing to scroll up to see the local type, e.g. when debugging why unsubtyping doesn't work somewhere. Also avoid [ ] in this mode, in favor of the standard (; ;), and put those at the end rather than at the start. --- src/passes/Print.cpp | 37 ++++++++++++++++++++---------- test/lit/debug/full.wat | 30 ++++++++++++------------- test/lit/debug/replace-keep.wat | 40 ++++++++++++++++----------------- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index c57ab29c36d..4ca5f722b76 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -48,13 +48,18 @@ static std::ostream& printStackIR(StackIR* ir, PrintSExpression&); namespace { -bool isFullForced() { +bool checkIsFullForced() { if (getenv("BINARYEN_PRINT_FULL")) { return std::stoi(getenv("BINARYEN_PRINT_FULL")) != 0; } return false; } +bool isFullForced() { + static bool full = checkIsFullForced(); + return full; +} + std::ostream& printMemoryName(Name name, std::ostream& o, Module* wasm) { if (!wasm || wasm->memories.size() > 1) { o << ' '; @@ -409,11 +414,12 @@ struct PrintExpressionContents Function* currFunction = nullptr; std::ostream& o; FeatureSet features; + bool full; PrintExpressionContents(PrintSExpression& parent) : parent(parent), wasm(parent.currModule), currFunction(parent.currFunction), o(parent.o), - features(wasm ? wasm->features : FeatureSet::All) {} + features(wasm ? wasm->features : FeatureSet::All), full(isFullForced()) {} std::ostream& printType(Type type) { return parent.printType(type); } @@ -517,6 +523,11 @@ struct PrintExpressionContents printMedium(o, "local.set "); } printLocal(curr->index, currFunction, o); + if (full && currFunction) { + o << " (; local type: "; + printType(currFunction->getLocalType(curr->index)); + o << " ;)"; + } } void visitGlobalGet(GlobalGet* curr) { printMedium(o, "global.get "); @@ -2463,12 +2474,12 @@ void PrintSExpression::printFullLine(Expression* expression) { if (!minify) { doIndent(o, indent); } + visit(expression); if (full) { - o << "["; + o << " (; "; printTypeOrName(expression->type, o, currModule); - o << "] "; + o << " ;)"; } - visit(expression); o << maybeNewLine; } @@ -2508,13 +2519,13 @@ void PrintSExpression::visitBlock(Block* curr) { printDebugLocation(curr); } stack.push_back(curr); + o << '('; + printExpressionContents(curr); if (full) { - o << "["; + o << " (; "; printTypeOrName(curr->type, o, currModule); - o << "]"; + o << " ;)"; } - o << '('; - printExpressionContents(curr); incIndent(); if (curr->list.size() > 0 && curr->list[0]->is()) { // recurse into the first element @@ -3370,11 +3381,13 @@ static std::ostream& printExpression(Expression* expression, print.currModule = wasm; if (full || isFullForced()) { print.setFull(true); - o << "["; - printTypeOrName(expression->type, o, wasm); - o << "] "; } print.visit(expression); + if (full || isFullForced()) { + o << " (; "; + printTypeOrName(expression->type, o, wasm); + o << " ;)"; + } return o; } diff --git a/test/lit/debug/full.wat b/test/lit/debug/full.wat index 3ea86161179..3e0efca11fd 100644 --- a/test/lit/debug/full.wat +++ b/test/lit/debug/full.wat @@ -27,24 +27,24 @@ ;; NRML-NEXT: ) ;; NRML-NEXT: ) ;; FULL: (func $a - ;; FULL-NEXT: [none] ;;@ src.cpp:1:2 - ;; FULL-NEXT: [none](block $block - ;; FULL-NEXT: [none] ;;@ src.cpp:1:2 + ;; FULL-NEXT: ;;@ src.cpp:1:2 + ;; FULL-NEXT: (block $block (; none ;) + ;; FULL-NEXT: ;;@ src.cpp:1:2 ;; FULL-NEXT: (drop - ;; FULL-NEXT: [i32] ;;@ src.cpp:1:2 - ;; FULL-NEXT: (i32.const 0) - ;; FULL-NEXT: ) - ;; FULL-NEXT: [none] ;;@ src.cpp:3:4 + ;; FULL-NEXT: ;;@ src.cpp:1:2 + ;; FULL-NEXT: (i32.const 0) (; i32 ;) + ;; FULL-NEXT: ) (; none ;) + ;; FULL-NEXT: ;;@ src.cpp:3:4 ;; FULL-NEXT: (drop - ;; FULL-NEXT: [i32] ;;@ src.cpp:3:4 - ;; FULL-NEXT: (i32.const 1) - ;; FULL-NEXT: ) - ;; FULL-NEXT: [none] ;;@ src.cpp:3:4 + ;; FULL-NEXT: ;;@ src.cpp:3:4 + ;; FULL-NEXT: (i32.const 1) (; i32 ;) + ;; FULL-NEXT: ) (; none ;) + ;; FULL-NEXT: ;;@ src.cpp:3:4 ;; FULL-NEXT: (drop - ;; FULL-NEXT: [i32] ;;@ src.cpp:3:4 - ;; FULL-NEXT: (i32.const 2) - ;; FULL-NEXT: ) - ;; FULL-NEXT: ) ;; end block block + ;; FULL-NEXT: ;;@ src.cpp:3:4 + ;; FULL-NEXT: (i32.const 2) (; i32 ;) + ;; FULL-NEXT: ) (; none ;) + ;; FULL-NEXT: ) ;; end block block (; none ;) ;; FULL-NEXT: ) (func $a ;;@ src.cpp:1:2 diff --git a/test/lit/debug/replace-keep.wat b/test/lit/debug/replace-keep.wat index 4c073aeab50..f8fc64f6532 100644 --- a/test/lit/debug/replace-keep.wat +++ b/test/lit/debug/replace-keep.wat @@ -9,16 +9,16 @@ (module ;; CHECK: (func $test ;; CHECK-NEXT: (local $temp i32) - ;; CHECK-NEXT: [none] ;;@ src.cpp:200:2 - ;; CHECK-NEXT: [none](block - ;; CHECK-NEXT: [none] ;;@ src.cpp:200:2 - ;; CHECK-NEXT: (call $test) - ;; CHECK-NEXT: [none] ;;@ src.cpp:200:2 - ;; CHECK-NEXT: (local.set $temp - ;; CHECK-NEXT: [i32] ;;@ src.cpp:200:2 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; end block + ;; CHECK-NEXT: ;;@ src.cpp:200:2 + ;; CHECK-NEXT: (block (; none ;) + ;; CHECK-NEXT: ;;@ src.cpp:200:2 + ;; CHECK-NEXT: (call $test) (; none ;) + ;; CHECK-NEXT: ;;@ src.cpp:200:2 + ;; CHECK-NEXT: (local.set $temp (; local type: i32 ;) + ;; CHECK-NEXT: ;;@ src.cpp:200:2 + ;; CHECK-NEXT: (i32.const 1) (; i32 ;) + ;; CHECK-NEXT: ) (; none ;) + ;; CHECK-NEXT: ) ;; end block (; none ;) ;; CHECK-NEXT: ) (func $test (local $temp i32) @@ -40,16 +40,16 @@ ;; CHECK: (func $test-no-trample ;; CHECK-NEXT: (local $temp i32) - ;; CHECK-NEXT: [none] ;;@ src.cpp:300:3 - ;; CHECK-NEXT: [none](block - ;; CHECK-NEXT: [none] ;;@ src.cpp:400:4 - ;; CHECK-NEXT: (call $test) - ;; CHECK-NEXT: [none] ;;@ src.cpp:200:2 - ;; CHECK-NEXT: (local.set $temp - ;; CHECK-NEXT: [i32] ;;@ src.cpp:500:5 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) ;; end block + ;; CHECK-NEXT: ;;@ src.cpp:300:3 + ;; CHECK-NEXT: (block (; none ;) + ;; CHECK-NEXT: ;;@ src.cpp:400:4 + ;; CHECK-NEXT: (call $test) (; none ;) + ;; CHECK-NEXT: ;;@ src.cpp:200:2 + ;; CHECK-NEXT: (local.set $temp (; local type: i32 ;) + ;; CHECK-NEXT: ;;@ src.cpp:500:5 + ;; CHECK-NEXT: (i32.const 1) (; i32 ;) + ;; CHECK-NEXT: ) (; none ;) + ;; CHECK-NEXT: ) ;; end block (; none ;) ;; CHECK-NEXT: ) (func $test-no-trample (local $temp i32) From 000fa2a8ac8dd66b8ca53b0451702966d59da4d0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 13 Jun 2024 12:03:09 -0700 Subject: [PATCH 383/553] wasm2js: Generalize global initializer code to use the main codegen logic (#6659) This avoids special-casing particular global init forms. After this we should support everything in global inits that we support anywhere else. --- src/wasm2js.h | 67 ++++++++++------------------------- test/wasm2js/refs.2asm.js | 12 ++++++- test/wasm2js/refs.2asm.js.opt | 12 ++++++- test/wasm2js/refs.wast | 13 +++++++ 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 034212b79d7..34260547d25 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -192,7 +192,10 @@ class Wasm2JSBuilder { // The second pass on an expression: process it fully, generating // JS - Ref processFunctionBody(Module* m, Function* func, bool standalone); + Ref processExpression(Expression* curr, + Module* m, + Function* func = nullptr, + bool standalone = false); Index getDataIndex(Name segment) { auto it = dataIndices.find(segment); @@ -323,7 +326,7 @@ class Wasm2JSBuilder { void addTable(Ref ast, Module* wasm); void addStart(Ref ast, Module* wasm); void addExports(Ref ast, Module* wasm); - void addGlobal(Ref ast, Global* global); + void addGlobal(Ref ast, Global* global, Module* module); void addMemoryFuncs(Ref ast, Module* wasm); void addMemoryGrowFunc(Ref ast, Module* wasm); @@ -503,7 +506,7 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) { // globals bool generateFetchHighBits = false; ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) { - addGlobal(asmFunc[3], global); + addGlobal(asmFunc[3], global, wasm); if (flags.allowAsserts && global->name == INT64_TO_32_HIGH_BITS) { generateFetchHighBits = true; } @@ -845,46 +848,12 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { ValueBuilder::makeStatement(ValueBuilder::makeReturn(exports))); } -void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) { +void Wasm2JSBuilder::addGlobal(Ref ast, Global* global, Module* module) { Ref theVar = ValueBuilder::makeVar(); ast->push_back(theVar); - - auto* init = global->init; - Ref value; - - if (auto* const_ = init->dynCast()) { - TODO_SINGLE_COMPOUND(const_->type); - switch (const_->type.getBasic()) { - case Type::i32: { - value = ValueBuilder::makeInt(const_->value.geti32()); - break; - } - case Type::f32: { - value = ValueBuilder::makeCall( - MATH_FROUND, - makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf32()), - JS_DOUBLE)); - break; - } - case Type::f64: { - value = makeJsCoercion(ValueBuilder::makeDouble(const_->value.getf64()), - JS_DOUBLE); - break; - } - default: { - assert(false && "Top const type not supported"); - } - } - } else if (auto* get = init->dynCast()) { - value = ValueBuilder::makeName(fromName(get->name, NameScope::Top)); - } else if (init->is()) { - value = ValueBuilder::makeName(NULL_); - } else { - assert(false && "Top init type not supported"); - } - + Ref init = processExpression(global->init, module); ValueBuilder::appendToVar( - theVar, fromName(global->name, NameScope::Top), value); + theVar, fromName(global->name, NameScope::Top), init); } Ref Wasm2JSBuilder::processFunction(Module* m, @@ -934,7 +903,8 @@ Ref Wasm2JSBuilder::processFunction(Module* m, size_t theVarIndex = ret[3]->size(); ret[3]->push_back(theVar); // body - flattenAppend(ret, processFunctionBody(m, func, standaloneFunction)); + flattenAppend(ret, + processExpression(func->body, m, func, standaloneFunction)); // vars, including new temp vars for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) { ValueBuilder::appendToVar( @@ -952,9 +922,10 @@ Ref Wasm2JSBuilder::processFunction(Module* m, return ret; } -Ref Wasm2JSBuilder::processFunctionBody(Module* m, - Function* func, - bool standaloneFunction) { +Ref Wasm2JSBuilder::processExpression(Expression* curr, + Module* m, + Function* func, + bool standaloneFunction) { // Switches are tricky to handle - in wasm they often come with // massively-nested "towers" of blocks, which if naively translated // to JS may exceed parse recursion limits of VMs. Therefore even when @@ -1092,9 +1063,9 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, : parent(parent), func(func), module(m), standaloneFunction(standaloneFunction) {} - Ref process() { - switchProcessor.walk(func->body); - return visit(func->body, NO_RESULT); + Ref process(Expression* curr) { + switchProcessor.walk(curr); + return visit(curr, NO_RESULT); } // A scoped temporary variable. @@ -2460,7 +2431,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, } }; - return ExpressionProcessor(this, m, func, standaloneFunction).process(); + return ExpressionProcessor(this, m, func, standaloneFunction).process(curr); } void Wasm2JSBuilder::addMemoryFuncs(Ref ast, Module* wasm) { diff --git a/test/wasm2js/refs.2asm.js b/test/wasm2js/refs.2asm.js index f538df6d6df..f1d60af6cc6 100644 --- a/test/wasm2js/refs.2asm.js +++ b/test/wasm2js/refs.2asm.js @@ -13,6 +13,7 @@ function asmFunc(imports) { var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; var global = null; + var global_ref = use_global_ref; function null_() { return null; } @@ -42,13 +43,21 @@ function asmFunc(imports) { return temp; } + function use_global_ref(x) { + var temp = null; + temp = global_ref; + global_ref = x; + return temp; + } + return { "null_": null_, "is_null": is_null, "ref_func": ref_func, "ref_eq": ref_eq, "ref_as": ref_as, - "use_global": use_global + "use_global": use_global, + "use_global_ref": use_global_ref }; } @@ -60,3 +69,4 @@ export var ref_func = retasmFunc.ref_func; export var ref_eq = retasmFunc.ref_eq; export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; +export var use_global_ref = retasmFunc.use_global_ref; diff --git a/test/wasm2js/refs.2asm.js.opt b/test/wasm2js/refs.2asm.js.opt index 251e63475e1..fa1947215a8 100644 --- a/test/wasm2js/refs.2asm.js.opt +++ b/test/wasm2js/refs.2asm.js.opt @@ -13,6 +13,7 @@ function asmFunc(imports) { var Math_trunc = Math.trunc; var Math_sqrt = Math.sqrt; var global = null; + var global_ref = use_global_ref; function null_() { return null; } @@ -40,13 +41,21 @@ function asmFunc(imports) { return $1; } + function use_global_ref($0) { + var $1 = null; + $1 = global_ref; + global_ref = $0; + return $1; + } + return { "null_": null_, "is_null": is_null, "ref_func": ref_func, "ref_eq": ref_eq, "ref_as": ref_as, - "use_global": use_global + "use_global": use_global, + "use_global_ref": use_global_ref }; } @@ -58,3 +67,4 @@ export var ref_func = retasmFunc.ref_func; export var ref_eq = retasmFunc.ref_eq; export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; +export var use_global_ref = retasmFunc.use_global_ref; diff --git a/test/wasm2js/refs.wast b/test/wasm2js/refs.wast index 964d0a60c97..244cf2e974e 100644 --- a/test/wasm2js/refs.wast +++ b/test/wasm2js/refs.wast @@ -1,6 +1,8 @@ (module (global $global (mut anyref) (ref.null any)) + (global $global-ref (mut funcref) (ref.func $use-global-ref)) + (func $null (export "null") (result anyref) (ref.null any) ) @@ -49,4 +51,15 @@ ) (local.get $temp) ) + + (func $use-global-ref (export "use-global-ref") (param $x funcref) (result funcref) + (local $temp funcref) + (local.set $temp + (global.get $global-ref) + ) + (global.set $global-ref + (local.get $x) + ) + (local.get $temp) + ) ) From 0fa99fb09b881985cf94e74b8c0b339bdef61be6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 12:07:44 -0700 Subject: [PATCH 384/553] [threads] Add a "shared-everything" feature (#6658) Add the feature and flags to enable and disable it. Require the new feature to be enabled for shared heap types to validate. To make the test work, update the validator to actually check features for global types. --- src/tools/tool-options.h | 1 + src/wasm-binary.h | 1 + src/wasm-features.h | 13 ++++++++++++- src/wasm/wasm-binary.cpp | 11 +++++++++-- src/wasm/wasm-type.cpp | 13 ++++++++++--- src/wasm/wasm-validator.cpp | 19 +++++++++++++++++++ src/wasm/wasm.cpp | 1 + test/binaryen.js/kitchen-sink.js.txt | 2 +- test/example/c-api-kitchen-sink.txt | 2 +- test/lit/help/wasm-as.test | 4 ++++ test/lit/help/wasm-ctor-eval.test | 4 ++++ test/lit/help/wasm-dis.test | 4 ++++ test/lit/help/wasm-emscripten-finalize.test | 4 ++++ test/lit/help/wasm-merge.test | 4 ++++ test/lit/help/wasm-metadce.test | 4 ++++ test/lit/help/wasm-opt.test | 5 +++++ test/lit/help/wasm-reduce.test | 4 ++++ test/lit/help/wasm-split.test | 4 ++++ test/lit/help/wasm2js.test | 5 +++++ test/lit/validation/shared-struct.wast | 12 ++++++++++++ ..._roundtrip_print-features_all-features.txt | 1 + test/unit/test_features.py | 1 + 22 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 test/lit/validation/shared-struct.wast diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h index 599b3b22cc3..10a03acc785 100644 --- a/src/tools/tool-options.h +++ b/src/tools/tool-options.h @@ -94,6 +94,7 @@ struct ToolOptions : public Options { .addFeature(FeatureSet::Strings, "strings") .addFeature(FeatureSet::MultiMemory, "multimemory") .addFeature(FeatureSet::TypedContinuations, "typed continuations") + .addFeature(FeatureSet::SharedEverything, "shared-everything threads") .add("--enable-typed-function-references", "", "Deprecated compatibility flag", diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 71de2f91579..ebfc27b1fed 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -428,6 +428,7 @@ extern const char* ExtendedConstFeature; extern const char* StringsFeature; extern const char* MultiMemoryFeature; extern const char* TypedContinuationsFeature; +extern const char* SharedEverythingFeature; enum Subsection { NameModule = 0, diff --git a/src/wasm-features.h b/src/wasm-features.h index 2ace67c27fd..cda3ce447ef 100644 --- a/src/wasm-features.h +++ b/src/wasm-features.h @@ -45,11 +45,12 @@ struct FeatureSet { Strings = 1 << 14, MultiMemory = 1 << 15, TypedContinuations = 1 << 16, + SharedEverything = 1 << 17, MVP = None, // Keep in sync with llvm default features: // https://github.com/llvm/llvm-project/blob/c7576cb89d6c95f03968076e902d3adfd1996577/clang/lib/Basic/Targets/WebAssembly.cpp#L150-L153 Default = SignExt | MutableGlobals, - All = (1 << 17) - 1, + All = (1 << 18) - 1, }; static std::string toString(Feature f) { @@ -88,6 +89,8 @@ struct FeatureSet { return "multimemory"; case TypedContinuations: return "typed-continuations"; + case SharedEverything: + return "shared-everything"; default: WASM_UNREACHABLE("unexpected feature"); } @@ -135,6 +138,9 @@ struct FeatureSet { bool hasTypedContinuations() const { return (features & TypedContinuations) != 0; } + bool hasSharedEverything() const { + return (features & SharedEverything) != 0; + } bool hasAll() const { return (features & All) != 0; } void set(FeatureSet f, bool v = true) { @@ -157,6 +163,7 @@ struct FeatureSet { void setStrings(bool v = true) { set(Strings, v); } void setMultiMemory(bool v = true) { set(MultiMemory, v); } void setTypedContinuations(bool v = true) { set(TypedContinuations, v); } + void setSharedEverything(bool v = true) { set(SharedEverything, v); } void setMVP() { features = MVP; } void setAll() { features = All; } @@ -186,6 +193,10 @@ struct FeatureSet { return *this; } + FeatureSet operator-(FeatureSet& other) const { + return features & ~other.features; + } + uint32_t features; }; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 32dcc883aab..7b88bdd76a0 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1319,9 +1319,14 @@ void WasmBinaryWriter::writeFeaturesSection() { return BinaryConsts::CustomSections::MultiMemoryFeature; case FeatureSet::TypedContinuations: return BinaryConsts::CustomSections::TypedContinuationsFeature; - default: - WASM_UNREACHABLE("unexpected feature flag"); + case FeatureSet::SharedEverything: + return BinaryConsts::CustomSections::SharedEverythingFeature; + case FeatureSet::None: + case FeatureSet::Default: + case FeatureSet::All: + break; } + WASM_UNREACHABLE("unexpected feature flag"); }; std::vector features; @@ -3825,6 +3830,8 @@ void WasmBinaryReader::readFeatures(size_t payloadLen) { } else if (name == BinaryConsts::CustomSections::TypedContinuationsFeature) { feature = FeatureSet::TypedContinuations; + } else if (name == BinaryConsts::CustomSections::SharedEverythingFeature) { + feature = FeatureSet::SharedEverything; } else { // Silently ignore unknown features (this may be and old binaryen running // on a new wasm). diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 83bf47107a5..532ebb9136f 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -932,10 +932,17 @@ FeatureSet Type::getFeatures() const { } } - if (heapType->isStruct() || heapType->isArray() || - heapType->getRecGroup().size() > 1 || + if (heapType->getRecGroup().size() > 1 || heapType->getDeclaredSuperType() || heapType->isOpen()) { feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; + } + + if (heapType->isShared()) { + feats |= FeatureSet::SharedEverything; + } + + if (heapType->isStruct() || heapType->isArray()) { + feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; } else if (heapType->isSignature()) { // This is a function reference, which requires reference types and // possibly also multivalue (if it has multiple returns). Note that @@ -969,7 +976,7 @@ FeatureSet Type::getFeatures() const { collector.noteChild(&heapType); return collector.feats; } - TODO_SINGLE_COMPOUND(t); + switch (t.getBasic()) { case Type::v128: return FeatureSet::SIMD; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 689872a196e..f8bd08e1dec 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3701,6 +3701,25 @@ static void validateGlobals(Module& module, ValidationInfo& info) { seen.insert(curr); } }); + + // Check that globals have allowed types. + for (auto& g : module.globals) { + auto globalFeats = g->type.getFeatures(); + if (!info.shouldBeTrue(globalFeats <= module.features, g->name, "")) { + auto& stream = info.getStream(nullptr); + stream << "global type requires additional features ["; + bool first = true; + (globalFeats - module.features).iterFeatures([&](FeatureSet feat) { + if (first) { + first = false; + } else { + stream << " "; + } + stream << "--enable-" << feat.toString(); + }); + stream << "]\n"; + } + } } static void validateMemories(Module& module, ValidationInfo& info) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index cae41339763..ed05e9b4766 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -54,6 +54,7 @@ const char* ExtendedConstFeature = "extended-const"; const char* StringsFeature = "strings"; const char* MultiMemoryFeature = "multimemory"; const char* TypedContinuationsFeature = "typed-continuations"; +const char* SharedEverythingFeature = "shared-everything"; } // namespace CustomSections } // namespace BinaryConsts diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index a3e88703e4f..28922c2a0ab 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -33,7 +33,7 @@ Features.RelaxedSIMD: 4096 Features.ExtendedConst: 8192 Features.Strings: 16384 Features.MultiMemory: 32768 -Features.All: 131071 +Features.All: 262143 InvalidId: 0 BlockId: 1 IfId: 2 diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 7231ded9a47..d79b34e6662 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -47,7 +47,7 @@ BinaryenFeatureMemory64: 2048 BinaryenFeatureRelaxedSIMD: 4096 BinaryenFeatureExtendedConst: 8192 BinaryenFeatureStrings: 16384 -BinaryenFeatureAll: 131071 +BinaryenFeatureAll: 262143 (f32.neg (f32.const -33.61199951171875) ) diff --git a/test/lit/help/wasm-as.test b/test/lit/help/wasm-as.test index 09e5b7c9da2..114064576a2 100644 --- a/test/lit/help/wasm-as.test +++ b/test/lit/help/wasm-as.test @@ -108,6 +108,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-ctor-eval.test b/test/lit/help/wasm-ctor-eval.test index e511ef0b9a2..93b5654ed60 100644 --- a/test/lit/help/wasm-ctor-eval.test +++ b/test/lit/help/wasm-ctor-eval.test @@ -115,6 +115,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-dis.test b/test/lit/help/wasm-dis.test index 2dffcc945d9..06dda9e96af 100644 --- a/test/lit/help/wasm-dis.test +++ b/test/lit/help/wasm-dis.test @@ -101,6 +101,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-emscripten-finalize.test b/test/lit/help/wasm-emscripten-finalize.test index a4ba48b1608..1b31e1e44cf 100644 --- a/test/lit/help/wasm-emscripten-finalize.test +++ b/test/lit/help/wasm-emscripten-finalize.test @@ -143,6 +143,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-merge.test b/test/lit/help/wasm-merge.test index c87be5edf1a..293bdbff041 100644 --- a/test/lit/help/wasm-merge.test +++ b/test/lit/help/wasm-merge.test @@ -131,6 +131,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index f0889eb81f7..453328df107 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -156,6 +156,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 727d1ab2195..9dd38e03e57 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -721,6 +721,11 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything +;; CHECK-NEXT: threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-reduce.test b/test/lit/help/wasm-reduce.test index a98b8a1995b..39795285537 100644 --- a/test/lit/help/wasm-reduce.test +++ b/test/lit/help/wasm-reduce.test @@ -137,6 +137,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test index fcd919ea88d..333864bcbbf 100644 --- a/test/lit/help/wasm-split.test +++ b/test/lit/help/wasm-split.test @@ -217,6 +217,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index d8768f35e2b..72efcd223f5 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -675,6 +675,11 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything +;; CHECK-NEXT: threads +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/validation/shared-struct.wast b/test/lit/validation/shared-struct.wast new file mode 100644 index 00000000000..ee25b6f24a0 --- /dev/null +++ b/test/lit/validation/shared-struct.wast @@ -0,0 +1,12 @@ +;; Test that shared structs require shared-everything threads + +;; RUN: not wasm-opt %s 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED + +;; NO-SHARED: global type requires additional features [--enable-reference-types --enable-gc --enable-shared-everything] +;; SHARED: (type $t (shared (struct ))) + +(module + (type $t (shared (struct))) + (global (import "" "") (ref null $t)) +) diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt index a15210d05e1..2c6523e6d92 100644 --- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt +++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt @@ -15,6 +15,7 @@ --enable-strings --enable-multimemory --enable-typed-continuations +--enable-shared-everything (module (type $0 (func (result v128 externref))) (func $foo (type $0) (result v128 externref) diff --git a/test/unit/test_features.py b/test/unit/test_features.py index 4ce42627572..3bd9ac127a4 100644 --- a/test/unit/test_features.py +++ b/test/unit/test_features.py @@ -425,4 +425,5 @@ def test_emit_all_features(self): '--enable-strings', '--enable-multimemory', '--enable-typed-continuations', + '--enable-shared-everything', ], p2.stdout.splitlines()) From 027128dccf76692ca4e000c6dbb489b348b12c73 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 14:46:47 -0700 Subject: [PATCH 385/553] [NFC] Add constexpr HeapTypes for basic heap types (#6662) Since the BasicHeapTypes are in an enum, calling HeapType methods on them requires something like `HeapType(HeapType::func).someMethod()`. This is unnecessarily verbose, so add a new `HeapTypes` namespace that contains constexpr HeapType globals that can be used instead, shorting this to `HeapTypes::func.someMethod()`. --- src/wasm-type.h | 20 ++++++++++ test/example/typeinfo.cpp | 8 ++-- test/gtest/type-builder.cpp | 76 ++++++++++++++++++------------------- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index 3e9fa4db342..2a74e4a6009 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -458,6 +458,26 @@ class HeapType { inline bool Type::isNull() const { return isRef() && getHeapType().isBottom(); } +namespace HeapTypes { + +constexpr HeapType ext = HeapType::ext; +constexpr HeapType func = HeapType::func; +constexpr HeapType cont = HeapType::cont; +constexpr HeapType any = HeapType::any; +constexpr HeapType eq = HeapType::eq; +constexpr HeapType i31 = HeapType::i31; +constexpr HeapType struct_ = HeapType::struct_; +constexpr HeapType array = HeapType::array; +constexpr HeapType exn = HeapType::exn; +constexpr HeapType string = HeapType::string; +constexpr HeapType none = HeapType::none; +constexpr HeapType noext = HeapType::noext; +constexpr HeapType nofunc = HeapType::nofunc; +constexpr HeapType nocont = HeapType::nocont; +constexpr HeapType noexn = HeapType::noexn; + +} // namespace HeapTypes + // A recursion group consisting of one or more HeapTypes. HeapTypes with single // members are encoded without using any additional memory, which is why // `getHeapTypes` has to return a vector by value; it might have to create one diff --git a/test/example/typeinfo.cpp b/test/example/typeinfo.cpp index 4edf1cc5d85..a8035545b87 100644 --- a/test/example/typeinfo.cpp +++ b/test/example/typeinfo.cpp @@ -96,16 +96,16 @@ void test_compound() { void test_printing() { { std::cout << ";; Heap types\n"; - std::cout << HeapType(HeapType::func) << "\n"; + std::cout << HeapTypes::func << "\n"; std::cout << Type(HeapType::func, Nullable) << "\n"; std::cout << Type(HeapType::func, NonNullable) << "\n"; - std::cout << HeapType(HeapType::any) << "\n"; + std::cout << HeapTypes::any << "\n"; std::cout << Type(HeapType::any, Nullable) << "\n"; std::cout << Type(HeapType::any, NonNullable) << "\n"; - std::cout << HeapType(HeapType::eq) << "\n"; + std::cout << HeapTypes::eq << "\n"; std::cout << Type(HeapType::eq, Nullable) << "\n"; std::cout << Type(HeapType::eq, NonNullable) << "\n"; - std::cout << HeapType(HeapType::i31) << "\n"; + std::cout << HeapTypes::i31 << "\n"; std::cout << Type(HeapType::i31, Nullable) << "\n"; std::cout << Type(HeapType::i31, NonNullable) << "\n"; std::cout << Signature(Type::none, Type::none) << "\n"; diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index c0a27b22923..b72b78c9ede 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -1058,30 +1058,30 @@ TEST_F(TypeTest, TestDepth) { } // any :> eq :> array :> specific array types - EXPECT_EQ(HeapType(HeapType::any).getDepth(), 0U); - EXPECT_EQ(HeapType(HeapType::eq).getDepth(), 1U); - EXPECT_EQ(HeapType(HeapType::array).getDepth(), 2U); - EXPECT_EQ(HeapType(HeapType::struct_).getDepth(), 2U); + EXPECT_EQ(HeapTypes::any.getDepth(), 0U); + EXPECT_EQ(HeapTypes::eq.getDepth(), 1U); + EXPECT_EQ(HeapTypes::array.getDepth(), 2U); + EXPECT_EQ(HeapTypes::struct_.getDepth(), 2U); EXPECT_EQ(A.getDepth(), 3U); EXPECT_EQ(B.getDepth(), 4U); EXPECT_EQ(C.getDepth(), 3U); // Signature types are subtypes of func. - EXPECT_EQ(HeapType(HeapType::func).getDepth(), 0U); + EXPECT_EQ(HeapTypes::func.getDepth(), 0U); EXPECT_EQ(sig.getDepth(), 1U); // Continuation types are subtypes of cont. - EXPECT_EQ(HeapType(HeapType::cont).getDepth(), 0U); + EXPECT_EQ(HeapTypes::cont.getDepth(), 0U); EXPECT_EQ(HeapType(Continuation(sig)).getDepth(), 1U); - EXPECT_EQ(HeapType(HeapType::ext).getDepth(), 0U); + EXPECT_EQ(HeapTypes::ext.getDepth(), 0U); - EXPECT_EQ(HeapType(HeapType::i31).getDepth(), 2U); - EXPECT_EQ(HeapType(HeapType::string).getDepth(), 2U); + EXPECT_EQ(HeapTypes::i31.getDepth(), 2U); + EXPECT_EQ(HeapTypes::string.getDepth(), 2U); - EXPECT_EQ(HeapType(HeapType::none).getDepth(), size_t(-1)); - EXPECT_EQ(HeapType(HeapType::nofunc).getDepth(), size_t(-1)); - EXPECT_EQ(HeapType(HeapType::noext).getDepth(), size_t(-1)); + EXPECT_EQ(HeapTypes::none.getDepth(), size_t(-1)); + EXPECT_EQ(HeapTypes::nofunc.getDepth(), size_t(-1)); + EXPECT_EQ(HeapTypes::noext.getDepth(), size_t(-1)); } // Test .iterSubTypes() helper. @@ -1135,34 +1135,34 @@ TEST_F(TypeTest, TestIterSubTypes) { // Test supertypes TEST_F(TypeTest, TestSupertypes) { // Basic types: getDeclaredSuperType always returns nothing. - ASSERT_FALSE(HeapType(HeapType::ext).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::func).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::cont).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::any).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::eq).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::i31).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::struct_).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::array).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::string).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::none).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::noext).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::nofunc).getDeclaredSuperType()); - ASSERT_FALSE(HeapType(HeapType::nocont).getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::ext.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::func.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::cont.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::any.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::eq.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::i31.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::struct_.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::array.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::string.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::none.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::noext.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::nofunc.getDeclaredSuperType()); + ASSERT_FALSE(HeapTypes::nocont.getDeclaredSuperType()); // Basic types: getSuperType does return a super, when there is one. - ASSERT_FALSE(HeapType(HeapType::ext).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::func).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::cont).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::any).getSuperType()); - ASSERT_EQ(HeapType(HeapType::eq).getSuperType(), HeapType::any); - ASSERT_EQ(HeapType(HeapType::i31).getSuperType(), HeapType::eq); - ASSERT_EQ(HeapType(HeapType::struct_).getSuperType(), HeapType::eq); - ASSERT_EQ(HeapType(HeapType::array).getSuperType(), HeapType::eq); - ASSERT_FALSE(HeapType(HeapType::string).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::none).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::noext).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::nofunc).getSuperType()); - ASSERT_FALSE(HeapType(HeapType::nocont).getSuperType()); + ASSERT_FALSE(HeapTypes::ext.getSuperType()); + ASSERT_FALSE(HeapTypes::func.getSuperType()); + ASSERT_FALSE(HeapTypes::cont.getSuperType()); + ASSERT_FALSE(HeapTypes::any.getSuperType()); + ASSERT_EQ(HeapTypes::eq.getSuperType(), HeapType::any); + ASSERT_EQ(HeapTypes::i31.getSuperType(), HeapType::eq); + ASSERT_EQ(HeapTypes::struct_.getSuperType(), HeapType::eq); + ASSERT_EQ(HeapTypes::array.getSuperType(), HeapType::eq); + ASSERT_FALSE(HeapTypes::string.getSuperType()); + ASSERT_FALSE(HeapTypes::none.getSuperType()); + ASSERT_FALSE(HeapTypes::noext.getSuperType()); + ASSERT_FALSE(HeapTypes::nofunc.getSuperType()); + ASSERT_FALSE(HeapTypes::nocont.getSuperType()); // Non-basic types. HeapType struct1, struct2, array1, array2, sig1, sig2; From eacea8060a29acefdd9cb45fdf95d73afa76c656 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 14:47:27 -0700 Subject: [PATCH 386/553] [Parser][NFC] Make typeidx and maybeTypeidx return consistent types (#6663) Since the BasicHeapTypes are in an enum, calling HeapType methods on them requires something like `HeapType(HeapType::func).someMethod()`. This is unnecessarily verbose, so add a new `HeapTypes` namespace that contains constexpr HeapType globals that can be used instead, shorting this to `HeapTypes::func.someMethod()`. --- src/parser/contexts.h | 9 +++------ src/parser/parsers.h | 16 +++++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 7c1a07b5361..351f6a208b3 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -908,7 +908,7 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { void addArrayType(ArrayT) {} void setOpen() {} void setShared() {} - Result<> addSubtype(Index) { return Ok{}; } + Result<> addSubtype(HeapTypeT) { return Ok{}; } void finishSubtype(Name name, Index pos) { // TODO: type annotations subtypeDefs.push_back({name, pos, Index(subtypeDefs.size()), {}}); @@ -1080,11 +1080,8 @@ struct ParseTypeDefsCtx : TypeParserCtx { void setShared() { builder[index].setShared(); } - Result<> addSubtype(Index super) { - if (super >= builder.size()) { - return in.err("supertype index out of bounds"); - } - builder[index].subTypeOf(builder[super]); + Result<> addSubtype(HeapTypeT super) { + builder[index].subTypeOf(super); return Ok{}; } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index a3fe5e5eb57..e56efb529a0 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -305,7 +305,8 @@ Result<> ignore(Ctx&, Index, const std::vector&) { } // Modules -template MaybeResult maybeTypeidx(Ctx& ctx); +template +MaybeResult maybeTypeidx(Ctx& ctx); template Result typeidx(Ctx&); template Result fieldidx(Ctx&, typename Ctx::HeapTypeT); @@ -2436,23 +2437,24 @@ makeSuspend(Ctx& ctx, Index pos, const std::vector& annotations) { // typeidx ::= x:u32 => x // | v:id => x (if types[x] = v) -template MaybeResult maybeTypeidx(Ctx& ctx) { +template +MaybeResult maybeTypeidx(Ctx& ctx) { if (auto x = ctx.in.takeU32()) { - return *x; + return ctx.getHeapTypeFromIdx(*x); } if (auto id = ctx.in.takeID()) { // TODO: Fix position to point to start of id, not next element. auto idx = ctx.getTypeIndex(*id); CHECK_ERR(idx); - return *idx; + return ctx.getHeapTypeFromIdx(*idx); } return {}; } template Result typeidx(Ctx& ctx) { - if (auto idx = maybeTypeidx(ctx)) { - CHECK_ERR(idx); - return ctx.getHeapTypeFromIdx(*idx); + if (auto t = maybeTypeidx(ctx)) { + CHECK_ERR(t); + return *t; } return ctx.in.err("expected type index or identifier"); } From 881fe6a9df3ed89630e184de5fbee62013b37e2f Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 14:54:15 -0700 Subject: [PATCH 387/553] [threads] Binary reading and writing of shared composite types (#6664) Also update the parser so that implicit type uses are not matched with shared function types. --- scripts/fuzz_opt.py | 4 ++ src/parser/contexts.h | 3 +- src/wasm-binary.h | 1 + src/wasm/wasm-binary.cpp | 7 ++++ test/lit/basic/shared-types.wast | 47 ++++++++++++++++++++++++ test/lit/passes/type-merging-shared.wast | 9 +++-- 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 test/lit/basic/shared-types.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 2a97af64a63..0804c0387e1 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -350,6 +350,10 @@ def is_git_repo(): 'exception-handling.wast', 'translate-to-new-eh.wast', 'rse-eh.wast', + # Shared types implementation in progress + 'type-merging-shared.wast', + 'shared-types.wast', + 'shared-struct.wast', ] diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 351f6a208b3..4acfc981a0e 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -1118,7 +1118,8 @@ struct ParseImplicitTypeDefsCtx : TypeParserCtx { : TypeParserCtx(typeIndices), in(in), types(types), implicitTypes(implicitTypes) { for (auto type : types) { - if (type.isSignature() && type.getRecGroup().size() == 1) { + if (type.isSignature() && type.getRecGroup().size() == 1 && + !type.isShared()) { sigTypes.insert({type.getSignature(), type}); } } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index ebfc27b1fed..9a79a4c8b89 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -377,6 +377,7 @@ enum EncodedType { Array = -0x22, // 0x5e Sub = -0x30, // 0x50 SubFinal = -0x31, // 0x4f + Shared = -0x24, // 0x65 // isorecursive recursion groups Rec = -0x32, // 0x4e // block_type diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7b88bdd76a0..924bf1601ed 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -285,6 +285,9 @@ void WasmBinaryWriter::writeTypes() { o << U32LEB(0); } } + if (type.isShared()) { + o << S32LEB(BinaryConsts::EncodedType::Shared); + } if (type.isSignature()) { o << S32LEB(BinaryConsts::EncodedType::Func); auto sig = type.getSignature(); @@ -2391,6 +2394,10 @@ void WasmBinaryReader::readTypes() { } form = getS32LEB(); } + if (form == BinaryConsts::Shared) { + builder[i].setShared(); + form = getS32LEB(); + } if (form == BinaryConsts::EncodedType::Func) { builder[i] = readSignatureDef(); } else if (form == BinaryConsts::EncodedType::Cont) { diff --git a/test/lit/basic/shared-types.wast b/test/lit/basic/shared-types.wast new file mode 100644 index 00000000000..d3720c2e90c --- /dev/null +++ b/test/lit/basic/shared-types.wast @@ -0,0 +1,47 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s + +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $final (shared (struct ))) + (type $final (shared (struct))) + ;; CHECK: (type $top (sub (shared (struct )))) + (type $top (sub (shared (struct)))) + ;; CHECK: (type $mid (sub $top (shared (struct (field i32))))) + (type $mid (sub $top (shared (struct i32)))) + ;; CHECK: (type $bot (sub final $mid (shared (struct (field i32) (field i32))))) + (type $bot (sub final $mid (shared (struct i32 i32)))) + + ;; CHECK: (type $func (shared (func))) + (type $func (shared (func))) + ;; CHECK: (type $array (shared (array i8))) + (type $array (shared (array i8))) + ;; CHECK: (type $cont (shared (cont $func))) + (type $cont (shared (cont $func))) + ) + + ;; CHECK: (type $7 (func)) + + ;; CHECK: (func $use-types (type $7) + ;; CHECK-NEXT: (local $0 (ref $final)) + ;; CHECK-NEXT: (local $1 (ref $top)) + ;; CHECK-NEXT: (local $2 (ref $mid)) + ;; CHECK-NEXT: (local $3 (ref $bot)) + ;; CHECK-NEXT: (local $4 (ref $func)) + ;; CHECK-NEXT: (local $5 (ref $array)) + ;; CHECK-NEXT: (local $6 (ref $cont)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $use-types + (local (ref $final)) + (local (ref $top)) + (local (ref $mid)) + (local (ref $bot)) + (local (ref $func)) + (local (ref $array)) + (local (ref $cont)) + ) +) diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast index aefeccc3b1f..2d3bcdc2137 100644 --- a/test/lit/passes/type-merging-shared.wast +++ b/test/lit/passes/type-merging-shared.wast @@ -43,18 +43,21 @@ (module ;; But two shared types can be merged. ;; CHECK: (rec - ;; CHECK-NEXT: (type $B (shared (array i8))) + ;; CHECK-NEXT: (type $C (shared (func))) + + ;; CHECK: (type $B (shared (array i8))) ;; CHECK: (type $A (shared (struct ))) (type $A (shared (struct))) (type $A' (shared (struct))) (type $B (shared (array i8))) (type $B' (shared (array i8))) - ;; CHECK: (type $C (shared (func))) (type $C (shared (func))) (type $C' (shared (func))) - ;; CHECK: (func $foo (type $C) + ;; CHECK: (type $3 (func)) + + ;; CHECK: (func $foo (type $3) ;; CHECK-NEXT: (local $a (ref null $A)) ;; CHECK-NEXT: (local $a' (ref null $A)) ;; CHECK-NEXT: (local $b (ref null $B)) From 2c758c54db0eb730af8fc858ddb42604e26b0a5b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 16:00:48 -0700 Subject: [PATCH 388/553] [Parser] Update requirements for implicit type uses (#6665) As an abbreviation, a `typeuse` can be given as just a list of parameters and results, in which case it corresponds to the index of the first function type with the same parameters and results. That function type must also be an MVP function type, i.e. it cannot have a nontrivial rec group, be non-final, or have a declared supertype. The parser did not previously implement all of these rules. --- src/parser/contexts.h | 2 +- test/lit/passes/optimize-instructions-gc.wast | 146 ++++----- test/lit/passes/type-generalizing.wast | 4 +- test/lit/wat-kitchen-sink.wast | 302 +++++++++--------- 4 files changed, 228 insertions(+), 226 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 4acfc981a0e..6dabfca3d78 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -1119,7 +1119,7 @@ struct ParseImplicitTypeDefsCtx : TypeParserCtx { types(types), implicitTypes(implicitTypes) { for (auto type : types) { if (type.isSignature() && type.getRecGroup().size() == 1 && - !type.isShared()) { + !type.getDeclaredSuperType() && !type.isOpen() && !type.isShared()) { sigTypes.insert({type.getSignature(), type}); } } diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index ce4f2cedb8d..14db70f3b98 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -22,13 +22,13 @@ ;; CHECK: (type $B (sub $A (struct (field i32) (field i32) (field f32)))) (type $B (sub $A (struct (field i32) (field i32) (field f32)))) - ;; CHECK: (type $void (sub (func))) - ;; CHECK: (type $B-child (sub $B (struct (field i32) (field i32) (field f32) (field i64)))) (type $B-child (sub $B (struct (field i32) (field i32) (field f32) (field i64)))) (type $empty (struct)) + ;; CHECK: (type $void (sub (func))) + ;; CHECK: (type $void2 (sub $void (func))) ;; CHECK: (type $C (sub $A (struct (field i32) (field i32) (field f64)))) @@ -50,7 +50,7 @@ ;; These functions test if an `if` with subtyped arms is correctly folded ;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold) - ;; CHECK: (func $if-arms-subtype-fold (type $27) (result anyref) + ;; CHECK: (func $if-arms-subtype-fold (type $28) (result anyref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) (func $if-arms-subtype-fold (result anyref) @@ -65,7 +65,7 @@ ) ) ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold) - ;; CHECK: (func $if-arms-subtype-nofold (type $28) (param $i31ref i31ref) (result anyref) + ;; CHECK: (func $if-arms-subtype-nofold (type $29) (param $i31ref i31ref) (result anyref) ;; CHECK-NEXT: (if (result anyref) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -122,7 +122,7 @@ ) ;; Similar, but for arrays. - ;; CHECK: (func $store-trunc2 (type $14) (param $x (ref null $array)) + ;; CHECK: (func $store-trunc2 (type $15) (param $x (ref null $array)) ;; CHECK-NEXT: (array.set $array ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (i32.const 0) @@ -139,7 +139,7 @@ ;; ref.is_null is not needed on a non-nullable value, and if something is ;; cast to its own type, we don't need that either, etc. - ;; CHECK: (func $unneeded_test (type $15) (param $struct (ref $struct)) (param $func (ref func)) (param $i31 (ref i31)) + ;; CHECK: (func $unneeded_test (type $16) (param $struct (ref $struct)) (param $func (ref func)) (param $i31 (ref i31)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop @@ -182,7 +182,7 @@ ;; similar to $unneeded_is, but the values are nullable. we can at least ;; leave just the null check. - ;; CHECK: (func $unneeded_test_null (type $16) (param $struct (ref null $struct)) (param $func funcref) (param $i31 i31ref) + ;; CHECK: (func $unneeded_test_null (type $17) (param $struct (ref null $struct)) (param $func funcref) (param $i31 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $struct) @@ -223,7 +223,7 @@ ;; ref.as_non_null is not needed on a non-nullable value, and if something is ;; a func we don't need that either etc., and can just return the value. - ;; CHECK: (func $unneeded_cast (type $15) (param $struct (ref $struct)) (param $func (ref func)) (param $i31 (ref i31)) + ;; CHECK: (func $unneeded_cast (type $16) (param $struct (ref $struct)) (param $func (ref func)) (param $i31 (ref i31)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) @@ -251,7 +251,7 @@ ;; similar to $unneeded_cast, but the values are nullable. we can turn the ;; more specific things into ref.as_non_null. - ;; CHECK: (func $unneeded_cast_null (type $16) (param $struct (ref null $struct)) (param $func funcref) (param $i31 i31ref) + ;; CHECK: (func $unneeded_cast_null (type $17) (param $struct (ref null $struct)) (param $func funcref) (param $i31 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $struct) @@ -283,7 +283,7 @@ ) ) - ;; CHECK: (func $unneeded_unreachability (type $void) + ;; CHECK: (func $unneeded_unreachability (type $5) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test (ref func) ;; CHECK-NEXT: (unreachable) @@ -308,7 +308,7 @@ ) ) - ;; CHECK: (func $redundant-non-null-casts (type $29) (param $x (ref null $struct)) (param $y (ref null $array)) (param $f (ref null $void)) + ;; CHECK: (func $redundant-non-null-casts (type $30) (param $x (ref null $struct)) (param $y (ref null $array)) (param $f (ref null $void)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $x) @@ -395,7 +395,7 @@ ) ) - ;; CHECK: (func $get-eqref (type $30) (result eqref) + ;; CHECK: (func $get-eqref (type $31) (result eqref) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $get-eqref (result eqref) @@ -471,12 +471,12 @@ ) ) - ;; CHECK: (func $nothing (type $void) + ;; CHECK: (func $nothing (type $5) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $nothing) - ;; CHECK: (func $ref-eq-corner-cases (type $5) (param $x eqref) + ;; CHECK: (func $ref-eq-corner-cases (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (block (result eqref) @@ -563,7 +563,7 @@ ) ) - ;; CHECK: (func $ref-eq-ref-cast (type $5) (param $x eqref) + ;; CHECK: (func $ref-eq-ref-cast (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $x) @@ -586,7 +586,7 @@ ) ) - ;; CHECK: (func $flip-cast-of-as-non-null (type $17) (param $x anyref) + ;; CHECK: (func $flip-cast-of-as-non-null (type $18) (param $x anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $struct) ;; CHECK-NEXT: (local.get $x) @@ -639,7 +639,7 @@ ) ) ) - ;; CHECK: (func $flip-tee-of-as-non-null (type $17) (param $x anyref) + ;; CHECK: (func $flip-tee-of-as-non-null (type $18) (param $x anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.tee $x @@ -659,7 +659,7 @@ ) ) - ;; CHECK: (func $flip-tee-of-as-non-null-non-nullable (type $31) (param $x (ref any)) (param $y anyref) + ;; CHECK: (func $flip-tee-of-as-non-null-non-nullable (type $32) (param $x (ref any)) (param $y anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $x ;; CHECK-NEXT: (ref.as_non_null @@ -680,7 +680,7 @@ ) ) ) - ;; CHECK: (func $ternary-identical-arms (type $32) (param $x i32) (param $y (ref null $struct)) (param $z (ref null $struct)) + ;; CHECK: (func $ternary-identical-arms (type $33) (param $x i32) (param $y (ref null $struct)) (param $z (ref null $struct)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (if (result (ref null $struct)) @@ -708,7 +708,7 @@ ) ) ) - ;; CHECK: (func $select-identical-arms-but-side-effect (type $18) (param $x (ref null $struct)) (param $y (ref null $struct)) (param $z i32) + ;; CHECK: (func $select-identical-arms-but-side-effect (type $19) (param $x (ref null $struct)) (param $y (ref null $struct)) (param $z i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (select ;; CHECK-NEXT: (struct.get_u $struct $i8 @@ -735,7 +735,7 @@ ) ) ) - ;; CHECK: (func $ternary-identical-arms-no-side-effect (type $33) (param $x (ref $struct)) (param $y (ref $struct)) (param $z i32) + ;; CHECK: (func $ternary-identical-arms-no-side-effect (type $34) (param $x (ref $struct)) (param $y (ref $struct)) (param $z i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get_u $struct $i8 ;; CHECK-NEXT: (select (result (ref $struct)) @@ -760,7 +760,7 @@ ) ) ) - ;; CHECK: (func $if-identical-arms-with-side-effect (type $18) (param $x (ref null $struct)) (param $y (ref null $struct)) (param $z i32) + ;; CHECK: (func $if-identical-arms-with-side-effect (type $19) (param $x (ref null $struct)) (param $y (ref null $struct)) (param $z i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get_u $struct $i8 ;; CHECK-NEXT: (if (result (ref null $struct)) @@ -795,7 +795,7 @@ ) ) - ;; CHECK: (func $ref-cast-squared (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-squared (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $struct) ;; CHECK-NEXT: (local.get $x) @@ -812,7 +812,7 @@ ) ) ) - ;; CHECK: (func $ref-cast-squared-fallthrough (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-squared-fallthrough (type $4) (param $x eqref) ;; CHECK-NEXT: (local $1 (ref null $struct)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref null $struct)) @@ -841,7 +841,7 @@ ) ) ) - ;; CHECK: (func $ref-cast-cubed (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-cubed (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $struct) ;; CHECK-NEXT: (local.get $x) @@ -860,7 +860,7 @@ ) ) ) - ;; CHECK: (func $ref-cast-squared-different (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-squared-different (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (local.get $x) @@ -879,7 +879,7 @@ ) ) - ;; CHECK: (func $ref-eq-null (type $5) (param $x eqref) + ;; CHECK: (func $ref-eq-null (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $x) @@ -1087,7 +1087,7 @@ ) ) - ;; CHECK: (func $hoist-LUB-danger (type $34) (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32) + ;; CHECK: (func $hoist-LUB-danger (type $35) (param $x i32) (param $b (ref $B)) (param $c (ref $C)) (result i32) ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (then @@ -1126,7 +1126,7 @@ ) ) - ;; CHECK: (func $incompatible-cast-of-non-null (type $35) (param $struct (ref $struct)) + ;; CHECK: (func $incompatible-cast-of-non-null (type $36) (param $struct (ref $struct)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop @@ -1244,7 +1244,7 @@ ) ) - ;; CHECK: (func $subtype-compatible (type $20) (param $A (ref null $A)) (param $B (ref null $B)) + ;; CHECK: (func $subtype-compatible (type $21) (param $A (ref null $A)) (param $B (ref null $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test (ref $B) ;; CHECK-NEXT: (local.get $A) @@ -1324,7 +1324,7 @@ ) ) - ;; CHECK: (func $compatible-test-separate-fallthrough (type $11) (param $eqref eqref) (result i32) + ;; CHECK: (func $compatible-test-separate-fallthrough (type $12) (param $eqref eqref) (result i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $eqref ;; CHECK-NEXT: (block (result eqref) @@ -1358,7 +1358,7 @@ ) ) - ;; CHECK: (func $improvable-test-separate-fallthrough (type $11) (param $eqref eqref) (result i32) + ;; CHECK: (func $improvable-test-separate-fallthrough (type $12) (param $eqref eqref) (result i32) ;; CHECK-NEXT: (ref.test (ref i31) ;; CHECK-NEXT: (block (result eqref) ;; CHECK-NEXT: (ref.as_non_null @@ -1379,7 +1379,7 @@ ) ) - ;; CHECK: (func $incompatible-test-separate-fallthrough (type $11) (param $eqref eqref) (result i32) + ;; CHECK: (func $incompatible-test-separate-fallthrough (type $12) (param $eqref eqref) (result i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $eqref ;; CHECK-NEXT: (block (result eqref) @@ -1538,7 +1538,7 @@ ) ) - ;; CHECK: (func $ref.test-unreachable (type $36) (param $A (ref null $A)) + ;; CHECK: (func $ref.test-unreachable (type $37) (param $A (ref null $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test (ref $A) ;; CHECK-NEXT: (unreachable) @@ -1565,7 +1565,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-null (type $void) + ;; CHECK: (func $ref-cast-static-null (type $5) ;; CHECK-NEXT: (local $a (ref null $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.null none) @@ -1661,7 +1661,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-general (type $20) (param $a (ref null $A)) (param $b (ref null $B)) + ;; CHECK: (func $ref-cast-static-general (type $21) (param $a (ref null $A)) (param $b (ref null $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: ) @@ -1708,7 +1708,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-squared (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-squared (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $A) ;; CHECK-NEXT: (local.get $x) @@ -1751,7 +1751,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-many (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-many (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $B-child) ;; CHECK-NEXT: (local.get $x) @@ -1842,7 +1842,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-very-many (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-very-many (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $B-child) ;; CHECK-NEXT: (local.get $x) @@ -1880,7 +1880,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-fallthrough-remaining (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-fallthrough-remaining (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref null $B)) ;; CHECK-NEXT: (call $ref-cast-static-fallthrough-remaining @@ -1915,7 +1915,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-fallthrough-remaining-child (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-fallthrough-remaining-child (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref null $B) ;; CHECK-NEXT: (block (result eqref) @@ -1947,7 +1947,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-fallthrough-remaining-impossible (type $21) (param $x (ref eq)) + ;; CHECK: (func $ref-cast-static-fallthrough-remaining-impossible (type $22) (param $x (ref eq)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop @@ -1982,7 +1982,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-fallthrough-remaining-nonnull (type $21) (param $x (ref eq)) + ;; CHECK: (func $ref-cast-static-fallthrough-remaining-nonnull (type $22) (param $x (ref eq)) ;; CHECK-NEXT: (local $1 (ref $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $B)) @@ -2021,7 +2021,7 @@ ) ) - ;; CHECK: (func $ref-cast-static-squared-impossible (type $5) (param $x eqref) + ;; CHECK: (func $ref-cast-static-squared-impossible (type $4) (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (local.get $x) @@ -2091,7 +2091,7 @@ ) ) - ;; CHECK: (func $ref-test-static-same-type (type $22) (param $nullable (ref null $A)) (param $non-nullable (ref $A)) + ;; CHECK: (func $ref-test-static-same-type (type $23) (param $nullable (ref null $A)) (param $non-nullable (ref $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (ref.is_null @@ -2124,7 +2124,7 @@ ) ) - ;; CHECK: (func $ref-test-static-subtype (type $12) (param $nullable (ref null $B)) (param $non-nullable (ref $B)) + ;; CHECK: (func $ref-test-static-subtype (type $13) (param $nullable (ref null $B)) (param $non-nullable (ref $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (ref.is_null @@ -2155,7 +2155,7 @@ ) ) - ;; CHECK: (func $ref-test-static-supertype (type $22) (param $nullable (ref null $A)) (param $non-nullable (ref $A)) + ;; CHECK: (func $ref-test-static-supertype (type $23) (param $nullable (ref null $A)) (param $non-nullable (ref $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test (ref $B) ;; CHECK-NEXT: (local.get $nullable) @@ -2182,7 +2182,7 @@ ) ) - ;; CHECK: (func $ref-test-static-impossible (type $37) (param $nullable (ref null $array)) (param $non-nullable (ref $array)) + ;; CHECK: (func $ref-test-static-impossible (type $38) (param $nullable (ref null $array)) (param $non-nullable (ref $array)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop @@ -2262,14 +2262,14 @@ ) ) - ;; CHECK: (func $impossible (type $38) (result (ref none)) + ;; CHECK: (func $impossible (type $39) (result (ref none)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $impossible (result (ref none)) (unreachable) ) - ;; CHECK: (func $bottom-type-accessors (type $39) (param $bot (ref none)) (param $null nullref) + ;; CHECK: (func $bottom-type-accessors (type $40) (param $bot (ref none)) (param $null nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) @@ -2311,7 +2311,7 @@ ) ) - ;; CHECK: (func $ref-cast-heap-type (type $12) (param $null-b (ref null $B)) (param $b (ref $B)) + ;; CHECK: (func $ref-cast-heap-type (type $13) (param $null-b (ref null $B)) (param $b (ref $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $b) ;; CHECK-NEXT: ) @@ -2358,7 +2358,7 @@ ) ) - ;; CHECK: (func $ref-cast-heap-type-incompatible (type $12) (param $null-b (ref null $B)) (param $b (ref $B)) + ;; CHECK: (func $ref-cast-heap-type-incompatible (type $13) (param $null-b (ref null $B)) (param $b (ref $B)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop @@ -2417,7 +2417,7 @@ ) ) - ;; CHECK: (func $compatible-cast-separate-fallthrough (type $23) (param $eqref eqref) (result (ref i31)) + ;; CHECK: (func $compatible-cast-separate-fallthrough (type $24) (param $eqref eqref) (result (ref i31)) ;; CHECK-NEXT: (local $1 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $eqref @@ -2457,7 +2457,7 @@ ) ) - ;; CHECK: (func $compatible-cast-fallthrough-null-check (type $23) (param $eqref eqref) (result (ref i31)) + ;; CHECK: (func $compatible-cast-fallthrough-null-check (type $24) (param $eqref eqref) (result (ref i31)) ;; CHECK-NEXT: (local $1 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $eqref @@ -2489,7 +2489,7 @@ ) ) - ;; CHECK: (func $compatible-cast-separate-fallthrough-multiple-options-1 (type $24) (param $eqref eqref) (result (ref eq)) + ;; CHECK: (func $compatible-cast-separate-fallthrough-multiple-options-1 (type $25) (param $eqref eqref) (result (ref eq)) ;; CHECK-NEXT: (local $1 i31ref) ;; CHECK-NEXT: (block $outer (result (ref eq)) ;; CHECK-NEXT: (block (result (ref i31)) @@ -2547,7 +2547,7 @@ ) ) - ;; CHECK: (func $compatible-cast-separate-fallthrough-multiple-options-2 (type $24) (param $eqref eqref) (result (ref eq)) + ;; CHECK: (func $compatible-cast-separate-fallthrough-multiple-options-2 (type $25) (param $eqref eqref) (result (ref eq)) ;; CHECK-NEXT: (local $1 (ref i31)) ;; CHECK-NEXT: (block $outer (result (ref eq)) ;; CHECK-NEXT: (block (result (ref i31)) @@ -2602,7 +2602,7 @@ ) ) - ;; CHECK: (func $incompatible-cast-separate-fallthrough (type $40) (param $eqref eqref) (result structref) + ;; CHECK: (func $incompatible-cast-separate-fallthrough (type $41) (param $eqref eqref) (result structref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $eqref ;; CHECK-NEXT: (block (result (ref i31)) @@ -2739,7 +2739,7 @@ ) ) - ;; CHECK: (func $as_of_unreachable (type $41) (result (ref $A)) + ;; CHECK: (func $as_of_unreachable (type $42) (result (ref $A)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) (func $as_of_unreachable (result (ref $A)) @@ -2753,7 +2753,7 @@ ) ) - ;; CHECK: (func $cast-internalized-extern (type $42) (param $externref externref) + ;; CHECK: (func $cast-internalized-extern (type $43) (param $externref externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $A) ;; CHECK-NEXT: (extern.internalize @@ -2775,7 +2775,7 @@ ) ) - ;; CHECK: (func $struct.set.null.fallthrough (type $void) + ;; CHECK: (func $struct.set.null.fallthrough (type $5) ;; CHECK-NEXT: (local $temp (ref null $struct)) ;; CHECK-NEXT: (block ;; (replaces unreachable StructSet we can't emit) ;; CHECK-NEXT: (drop @@ -2804,7 +2804,7 @@ ) ) - ;; CHECK: (func $set.array.null (type $void) + ;; CHECK: (func $set.array.null (type $5) ;; CHECK-NEXT: (local $temp (ref none)) ;; CHECK-NEXT: (block ;; (replaces unreachable ArraySet we can't emit) ;; CHECK-NEXT: (drop @@ -2862,7 +2862,7 @@ ) ) - ;; CHECK: (func $refinalize.select.arm.flip (type $void) + ;; CHECK: (func $refinalize.select.arm.flip (type $5) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $void2) ;; CHECK-NEXT: (ref.func $refinalize.select.arm) @@ -2882,7 +2882,7 @@ ) ) - ;; CHECK: (func $refinalize.select.arm.unknown (type $25) (param $x i32) + ;; CHECK: (func $refinalize.select.arm.unknown (type $26) (param $x i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $void2) ;; CHECK-NEXT: (ref.func $refinalize.select.arm) @@ -2902,7 +2902,7 @@ ) ) - ;; CHECK: (func $non-null-bottom-ref (type $43) (result (ref func)) + ;; CHECK: (func $non-null-bottom-ref (type $44) (result (ref func)) ;; CHECK-NEXT: (local $0 funcref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $0 @@ -2930,7 +2930,7 @@ ) ) - ;; CHECK: (func $non-null-bottom-cast (type $44) (result (ref nofunc)) + ;; CHECK: (func $non-null-bottom-cast (type $45) (result (ref nofunc)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $non-null-bottom-cast) ;; CHECK-NEXT: ) @@ -3000,7 +3000,7 @@ ) ) - ;; CHECK: (func $ref.test-fallthrough (type $void) + ;; CHECK: (func $ref.test-fallthrough (type $5) ;; CHECK-NEXT: (local $A (ref $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test (ref $B) @@ -3088,7 +3088,7 @@ ) ) - ;; CHECK: (func $gc_to_unreachable_in_added_constants (type $void) + ;; CHECK: (func $gc_to_unreachable_in_added_constants (type $5) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.wrap_i64 ;; CHECK-NEXT: (i64.add @@ -3129,7 +3129,7 @@ (unreachable) ) - ;; CHECK: (func $array-copy-non-null (type $14) (param $x (ref null $array)) + ;; CHECK: (func $array-copy-non-null (type $15) (param $x (ref null $array)) ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (array.copy $array $array ;; CHECK-NEXT: (ref.as_non_null @@ -3178,7 +3178,7 @@ ) ) - ;; CHECK: (func $struct.new (type $void) + ;; CHECK: (func $struct.new (type $5) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $struct)) ;; CHECK-NEXT: (drop @@ -3263,7 +3263,7 @@ ) ) - ;; CHECK: (func $array.new (type $void) + ;; CHECK: (func $array.new (type $5) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $array)) ;; CHECK-NEXT: (drop @@ -3332,7 +3332,7 @@ ) ) - ;; CHECK: (func $array.new_fixed (type $void) + ;; CHECK: (func $array.new_fixed (type $5) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop @@ -3440,7 +3440,7 @@ ) ) - ;; CHECK: (func $array.new_fixed_fallthrough (type $void) + ;; CHECK: (func $array.new_fixed_fallthrough (type $5) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3556,7 +3556,7 @@ ) ) - ;; CHECK: (func $array.new_fixed_fallthrough_local (type $25) (param $x i32) + ;; CHECK: (func $array.new_fixed_fallthrough_local (type $26) (param $x i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) diff --git a/test/lit/passes/type-generalizing.wast b/test/lit/passes/type-generalizing.wast index 604561349c6..8278549d083 100644 --- a/test/lit/passes/type-generalizing.wast +++ b/test/lit/passes/type-generalizing.wast @@ -943,7 +943,9 @@ (type $mid (sub $top (func (result eqref)))) (type $bot (sub $mid (func (result i31ref)))) - ;; CHECK: (func $call-ref-no-limit (type $top) (result anyref) + ;; CHECK: (type $1 (func (result anyref))) + + ;; CHECK: (func $call-ref-no-limit (type $1) (result anyref) ;; CHECK-NEXT: (local $f (ref null $top)) ;; CHECK-NEXT: (call_ref $top ;; CHECK-NEXT: (local.get $f) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 527bfdd059d..170c962aa33 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -5,7 +5,7 @@ (module $parse ;; types - ;; CHECK: (type $void (sub (func))) + ;; CHECK: (type $0 (func)) ;; CHECK: (type $1 (func (result i32))) @@ -17,19 +17,21 @@ ;; CHECK: (type $4 (func (result i32 i64))) - ;; CHECK: (type $5 (func (param i32 i64))) + ;; CHECK: (type $void (sub (func))) + + ;; CHECK: (type $6 (func (param i32 i64))) ;; CHECK: (type $a2 (array (mut f32))) ;; CHECK: (type $a1 (array i64)) - ;; CHECK: (type $8 (func (param anyref))) + ;; CHECK: (type $9 (func (param anyref))) ;; CHECK: (type $simple (func (param i32 i64) (result f32))) ;; CHECK: (type $simple-cont (cont $simple)) - ;; CHECK: (type $11 (func (param i32 i64 v128))) + ;; CHECK: (type $12 (func (param i32 i64 v128))) ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct )) @@ -40,8 +42,6 @@ (rec) - ;; CHECK: (type $14 (func)) - ;; CHECK: (type $packed-i8 (array (mut i8))) ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) @@ -296,7 +296,7 @@ ;; globals (global (mut i32) i32.const 0) - ;; CHECK: (import "mod" "f5" (func $fimport$0 (type $void))) + ;; CHECK: (import "mod" "f5" (func $fimport$0 (type $0))) ;; CHECK: (import "mod" "imported-f" (func $fimport$1 (type $4) (result i32 i64))) @@ -474,7 +474,7 @@ ;; functions (func) - ;; CHECK: (func $2 (type $void) + ;; CHECK: (func $2 (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -500,12 +500,12 @@ ;; CHECK-NEXT: ) (func $f4 (type 18) (local i32 i64) (local $l f32)) - ;; CHECK: (func $"[quoted_name]" (type $void) + ;; CHECK: (func $"[quoted_name]" (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $"[quoted_name]") - ;; CHECK: (func $nop-skate (type $void) + ;; CHECK: (func $nop-skate (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (unreachable) @@ -520,7 +520,7 @@ nop ) - ;; CHECK: (func $nop-ski (type $void) + ;; CHECK: (func $nop-ski (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -544,7 +544,7 @@ (nop) ) - ;; CHECK: (func $nop-sled (type $void) + ;; CHECK: (func $nop-sled (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (nop) @@ -871,7 +871,7 @@ unreachable ) - ;; CHECK: (func $big-stack (type $void) + ;; CHECK: (func $big-stack (type $0) ;; CHECK-NEXT: (local $scratch f64) ;; CHECK-NEXT: (local $scratch_1 i64) ;; CHECK-NEXT: (local $scratch_2 f32) @@ -967,7 +967,7 @@ drop ) - ;; CHECK: (func $tuple-locals (type $void) + ;; CHECK: (func $tuple-locals (type $0) ;; CHECK-NEXT: (local $0 (tuple i32 i64)) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (local.tee $0 @@ -991,7 +991,7 @@ local.set 0 ) - ;; CHECK: (func $block (type $void) + ;; CHECK: (func $block (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (nop) @@ -1008,7 +1008,7 @@ end $l ) - ;; CHECK: (func $block-folded (type $void) + ;; CHECK: (func $block-folded (type $0) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (tuple.drop 2 ;; CHECK-NEXT: (block $l (type $ret2) (result i32 i32) @@ -1029,7 +1029,7 @@ unreachable ) - ;; CHECK: (func $block-mix (type $void) + ;; CHECK: (func $block-mix (type $0) ;; CHECK-NEXT: (local $scratch i32) ;; CHECK-NEXT: (local $scratch_1 (tuple i32 i32)) ;; CHECK-NEXT: (local $scratch_2 i32) @@ -1114,7 +1114,7 @@ end ) - ;; CHECK: (func $if-else (type $void) + ;; CHECK: (func $if-else (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1134,7 +1134,7 @@ end ) - ;; CHECK: (func $if-else-empty (type $void) + ;; CHECK: (func $if-else-empty (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1152,7 +1152,7 @@ end ) - ;; CHECK: (func $if-else-many (type $void) + ;; CHECK: (func $if-else-many (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1176,7 +1176,7 @@ end ) - ;; CHECK: (func $if-else-single-nested (type $void) + ;; CHECK: (func $if-else-single-nested (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1202,7 +1202,7 @@ end ) - ;; CHECK: (func $if-else-folded-body (type $void) + ;; CHECK: (func $if-else-folded-body (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1230,7 +1230,7 @@ end ) - ;; CHECK: (func $if-else-labeled (type $void) + ;; CHECK: (func $if-else-labeled (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) @@ -1252,7 +1252,7 @@ end $l ) - ;; CHECK: (func $if-no-else (type $void) + ;; CHECK: (func $if-no-else (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1309,7 +1309,7 @@ end ) - ;; CHECK: (func $if-else-folded (type $void) + ;; CHECK: (func $if-else-folded (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1332,7 +1332,7 @@ ) ) - ;; CHECK: (func $if-else-folded-empty (type $void) + ;; CHECK: (func $if-else-folded-empty (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1351,7 +1351,7 @@ ) ) - ;; CHECK: (func $if-else-folded-many (type $void) + ;; CHECK: (func $if-else-folded-many (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1378,7 +1378,7 @@ ) ) - ;; CHECK: (func $if-else-folded-single-nested (type $void) + ;; CHECK: (func $if-else-folded-single-nested (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.eqz ;; CHECK-NEXT: (i32.const 0) @@ -1413,7 +1413,7 @@ ) ) - ;; CHECK: (func $if-else-folded-labeled (type $void) + ;; CHECK: (func $if-else-folded-labeled (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) @@ -1438,7 +1438,7 @@ ) ) - ;; CHECK: (func $if-no-else-folded (type $void) + ;; CHECK: (func $if-no-else-folded (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1503,7 +1503,7 @@ ) ) -;; CHECK: (func $if-else-atypical-condition (type $void) +;; CHECK: (func $if-else-atypical-condition (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (then @@ -1531,7 +1531,7 @@ (if (i32.const 0) (i32.eqz) (then) (else)) ) - ;; CHECK: (func $if-else-mixed (type $void) + ;; CHECK: (func $if-else-mixed (type $0) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (i32.const 0) @@ -1596,7 +1596,7 @@ end ) - ;; CHECK: (func $if-else-brs (type $void) + ;; CHECK: (func $if-else-brs (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (if ;; CHECK-NEXT: (i32.const 0) @@ -1646,7 +1646,7 @@ end ) - ;; CHECK: (func $loop (type $void) + ;; CHECK: (func $loop (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1657,7 +1657,7 @@ end ) - ;; CHECK: (func $loop-empty (type $void) + ;; CHECK: (func $loop-empty (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1667,7 +1667,7 @@ end ) - ;; CHECK: (func $loop-many (type $void) + ;; CHECK: (func $loop-many (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1680,7 +1680,7 @@ end ) - ;; CHECK: (func $loop-nested (type $void) + ;; CHECK: (func $loop-nested (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) @@ -1694,7 +1694,7 @@ end ) - ;; CHECK: (func $loop-folded-body (type $void) + ;; CHECK: (func $loop-folded-body (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.const 0) @@ -1709,7 +1709,7 @@ end ) - ;; CHECK: (func $loop-labeled (type $void) + ;; CHECK: (func $loop-labeled (type $0) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1742,7 +1742,7 @@ end $l ) - ;; CHECK: (func $loop-folded (type $void) + ;; CHECK: (func $loop-folded (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1753,7 +1753,7 @@ ) ) - ;; CHECK: (func $loop-folded-empty (type $void) + ;; CHECK: (func $loop-folded-empty (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1762,7 +1762,7 @@ (loop) ) - ;; CHECK: (func $loop-folded-many (type $void) + ;; CHECK: (func $loop-folded-many (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) @@ -1775,7 +1775,7 @@ ) ) - ;; CHECK: (func $loop-folded-nested (type $void) + ;; CHECK: (func $loop-folded-nested (type $0) ;; CHECK-NEXT: (loop ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (f32.const 0) @@ -1790,7 +1790,7 @@ ) ) - ;; CHECK: (func $loop-folded-labeled (type $void) + ;; CHECK: (func $loop-folded-labeled (type $0) ;; CHECK-NEXT: (loop $l ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -1823,7 +1823,7 @@ ) ) - ;; CHECK: (func $try (type $void) + ;; CHECK: (func $try (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -1836,7 +1836,7 @@ end ) - ;; CHECK: (func $try-catch (type $void) + ;; CHECK: (func $try-catch (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -1895,7 +1895,7 @@ end ) - ;; CHECK: (func $try-catch_all (type $void) + ;; CHECK: (func $try-catch_all (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -1911,7 +1911,7 @@ end ) - ;; CHECK: (func $try-catch-catch_all (type $void) + ;; CHECK: (func $try-catch-catch_all (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -1935,7 +1935,7 @@ end ) - ;; CHECK: (func $try-delegate (type $void) + ;; CHECK: (func $try-delegate (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -1948,7 +1948,7 @@ delegate 0 ) - ;; CHECK: (func $try-delegate-nested-func-direct (type $void) + ;; CHECK: (func $try-delegate-nested-func-direct (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do @@ -1965,7 +1965,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-func-indirect-index (type $void) + ;; CHECK: (func $try-delegate-nested-func-indirect-index (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do @@ -1982,7 +1982,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-func-indirect-name (type $void) + ;; CHECK: (func $try-delegate-nested-func-indirect-name (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do @@ -1999,7 +1999,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-try-direct-index (type $void) + ;; CHECK: (func $try-delegate-nested-try-direct-index (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (try @@ -2020,7 +2020,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-try-direct-name (type $void) + ;; CHECK: (func $try-delegate-nested-try-direct-name (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (try @@ -2041,7 +2041,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-try-indirect-index (type $void) + ;; CHECK: (func $try-delegate-nested-try-indirect-index (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (try @@ -2062,7 +2062,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-try-indirect-name (type $void) + ;; CHECK: (func $try-delegate-nested-try-indirect-name (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (block $l @@ -2085,7 +2085,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-try-shadowing (type $void) + ;; CHECK: (func $try-delegate-nested-try-shadowing (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (block $l0 @@ -2108,7 +2108,7 @@ end $l ) - ;; CHECK: (func $try-delegate-nested-catch-shadowing (type $void) + ;; CHECK: (func $try-delegate-nested-catch-shadowing (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (try $l0 @@ -2138,7 +2138,7 @@ end ) - ;; CHECK: (func $try-delegate-nested-catch_all-shadowing (type $void) + ;; CHECK: (func $try-delegate-nested-catch_all-shadowing (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (try $l0 @@ -2168,7 +2168,7 @@ end ) - ;; CHECK: (func $try-br-index (type $void) + ;; CHECK: (func $try-br-index (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do @@ -2193,7 +2193,7 @@ end ) - ;; CHECK: (func $try-br-name (type $void) + ;; CHECK: (func $try-br-name (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do @@ -2218,7 +2218,7 @@ end $l ) - ;; CHECK: (func $try-folded (type $void) + ;; CHECK: (func $try-folded (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2259,7 +2259,7 @@ ) ) - ;; CHECK: (func $try-delegate-folded (type $void) + ;; CHECK: (func $try-delegate-folded (type $0) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2274,7 +2274,7 @@ ) ) - ;; CHECK: (func $rethrow (type $void) + ;; CHECK: (func $rethrow (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2291,7 +2291,7 @@ end ) - ;; CHECK: (func $rethrow-named (type $void) + ;; CHECK: (func $rethrow-named (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2308,7 +2308,7 @@ end ) - ;; CHECK: (func $rethrow-nested (type $void) + ;; CHECK: (func $rethrow-nested (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2337,7 +2337,7 @@ end ) - ;; CHECK: (func $rethrow-nested-named (type $void) + ;; CHECK: (func $rethrow-nested-named (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2366,7 +2366,7 @@ end ) - ;; CHECK: (func $rethrow-try-nested (type $void) + ;; CHECK: (func $rethrow-try-nested (type $0) ;; CHECK-NEXT: (try $label ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2393,7 +2393,7 @@ end ) - ;; CHECK: (func $rethrow-try-nested-named (type $void) + ;; CHECK: (func $rethrow-try-nested-named (type $0) ;; CHECK-NEXT: (try $l ;; CHECK-NEXT: (do ;; CHECK-NEXT: (nop) @@ -2418,7 +2418,7 @@ end ) - ;; CHECK: (func $try-table (type $void) + ;; CHECK: (func $try-table (type $0) ;; CHECK-NEXT: (try_table ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -2429,7 +2429,7 @@ end ) - ;; CHECK: (func $try-table-catch (type $void) + ;; CHECK: (func $try-table-catch (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try_table (catch $empty $label) ;; CHECK-NEXT: (nop) @@ -2455,7 +2455,7 @@ end ) - ;; CHECK: (func $try-table-catch-all (type $void) + ;; CHECK: (func $try-table-catch-all (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try_table (catch_all $label) ;; CHECK-NEXT: (nop) @@ -2481,7 +2481,7 @@ end ) - ;; CHECK: (func $try-table-all (type $void) + ;; CHECK: (func $try-table-all (type $0) ;; CHECK-NEXT: (block $catch ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $catch_ref (result exnref) @@ -2523,7 +2523,7 @@ end $catch ) - ;; CHECK: (func $try-table-folded (type $void) + ;; CHECK: (func $try-table-folded (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $try (result i32) @@ -2552,7 +2552,7 @@ throw_ref ) - ;; CHECK: (func $label-siblings (type $void) + ;; CHECK: (func $label-siblings (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (br $l) ;; CHECK-NEXT: ) @@ -2581,7 +2581,7 @@ end ) - ;; CHECK: (func $label-shadowed (type $void) + ;; CHECK: (func $label-shadowed (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (br $l) ;; CHECK-NEXT: (loop $l0 @@ -2614,7 +2614,7 @@ end ) - ;; CHECK: (func $label-index (type $void) + ;; CHECK: (func $label-index (type $0) ;; CHECK-NEXT: (block $block1 ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (block $block0 @@ -2643,7 +2643,7 @@ end ) - ;; CHECK: (func $label-func (type $void) + ;; CHECK: (func $label-func (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (br $label) ;; CHECK-NEXT: (block $a @@ -2728,7 +2728,7 @@ br 0 ) - ;; CHECK: (func $br_if (type $void) + ;; CHECK: (func $br_if (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (br_if $l ;; CHECK-NEXT: (i32.const 0) @@ -2742,7 +2742,7 @@ end ) - ;; CHECK: (func $br_if-index (type $void) + ;; CHECK: (func $br_if-index (type $0) ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (br_if $block ;; CHECK-NEXT: (i32.const 0) @@ -2756,7 +2756,7 @@ end ) - ;; CHECK: (func $br_if-return (type $void) + ;; CHECK: (func $br_if-return (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (br_if $label ;; CHECK-NEXT: (i32.const 0) @@ -2824,7 +2824,7 @@ end ) - ;; CHECK: (func $br-table (type $void) + ;; CHECK: (func $br-table (type $0) ;; CHECK-NEXT: (block $a ;; CHECK-NEXT: (block $b ;; CHECK-NEXT: (block $c @@ -2850,7 +2850,7 @@ end ) - ;; CHECK: (func $br-table-index (type $void) + ;; CHECK: (func $br-table-index (type $0) ;; CHECK-NEXT: (block $block ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (block $block1 @@ -2876,7 +2876,7 @@ end ) - ;; CHECK: (func $br-table-return (type $void) + ;; CHECK: (func $br-table-return (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (br_table $label $label $label $label $label $label $label $label ;; CHECK-NEXT: (i32.const 0) @@ -3073,7 +3073,7 @@ drop ) - ;; CHECK: (func $memory-size (type $void) + ;; CHECK: (func $memory-size (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.size $mimport$0) ;; CHECK-NEXT: ) @@ -3093,7 +3093,7 @@ drop ) - ;; CHECK: (func $memory-grow (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $memory-grow (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.grow $mimport$0 ;; CHECK-NEXT: (local.get $0) @@ -3122,7 +3122,7 @@ drop ) - ;; CHECK: (func $globals (type $void) + ;; CHECK: (func $globals (type $0) ;; CHECK-NEXT: (global.set $g-imported ;; CHECK-NEXT: (global.get $i32) ;; CHECK-NEXT: ) @@ -3132,7 +3132,7 @@ global.set 4 ) - ;; CHECK: (func $tuple-globals (type $void) + ;; CHECK: (func $tuple-globals (type $0) ;; CHECK-NEXT: (global.set $pair ;; CHECK-NEXT: (global.get $pair) ;; CHECK-NEXT: ) @@ -3151,7 +3151,7 @@ global.set $pair ) - ;; CHECK: (func $load (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $load (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load $mimport$0 offset=42 ;; CHECK-NEXT: (local.get $0) @@ -3180,7 +3180,7 @@ drop ) - ;; CHECK: (func $store (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $store (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (i32.store $mimport$0 offset=42 align=1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 0) @@ -3206,7 +3206,7 @@ f32.store $mem-i64 ) - ;; CHECK: (func $atomic-rmw (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $atomic-rmw (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.atomic.rmw16.add_u $mimport$0 ;; CHECK-NEXT: (local.get $0) @@ -3231,7 +3231,7 @@ drop ) - ;; CHECK: (func $atomic-cmpxchg (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $atomic-cmpxchg (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u $mem ;; CHECK-NEXT: (local.get $0) @@ -3260,7 +3260,7 @@ drop ) - ;; CHECK: (func $atomic-wait (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $atomic-wait (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.atomic.wait32 $mimport$0 ;; CHECK-NEXT: (local.get $0) @@ -3289,7 +3289,7 @@ drop ) - ;; CHECK: (func $atomic-notify (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $atomic-notify (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (memory.atomic.notify $mimport$0 offset=8 ;; CHECK-NEXT: (local.get $0) @@ -3314,14 +3314,14 @@ drop ) - ;; CHECK: (func $atomic-fence (type $void) + ;; CHECK: (func $atomic-fence (type $0) ;; CHECK-NEXT: (atomic.fence) ;; CHECK-NEXT: ) (func $atomic-fence atomic.fence ) - ;; CHECK: (func $simd-const (type $void) + ;; CHECK: (func $simd-const (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.const i32x4 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c) ;; CHECK-NEXT: ) @@ -3416,7 +3416,7 @@ i8x16.shl ) - ;; CHECK: (func $simd-load (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $simd-load (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load8x8_s $mimport$0 offset=8 ;; CHECK-NEXT: (local.get $0) @@ -3437,7 +3437,7 @@ drop ) - ;; CHECK: (func $simd-load-store-lane (type $11) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $simd-load-store-lane (type $12) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load16_lane $mimport$0 7 ;; CHECK-NEXT: (local.get $0) @@ -3491,7 +3491,7 @@ memory.init 0 ) - ;; CHECK: (func $data-drop (type $void) + ;; CHECK: (func $data-drop (type $0) ;; CHECK-NEXT: (data.drop $implicit-data) ;; CHECK-NEXT: (data.drop $passive) ;; CHECK-NEXT: ) @@ -3532,7 +3532,7 @@ memory.copy $mem-i64 5 ) - ;; CHECK: (func $memory-fill (type $5) (param $0 i32) (param $1 i64) + ;; CHECK: (func $memory-fill (type $6) (param $0 i32) (param $1 i64) ;; CHECK-NEXT: (memory.fill $mimport$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (i32.const 1) @@ -3564,7 +3564,7 @@ memory.fill $mem-i64 ) - ;; CHECK: (func $return-none (type $void) + ;; CHECK: (func $return-none (type $0) ;; CHECK-NEXT: (return) ;; CHECK-NEXT: ) (func $return-none @@ -3658,7 +3658,7 @@ ref.is_null ) - ;; CHECK: (func $ref-func (type $void) + ;; CHECK: (func $ref-func (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $ref-func) ;; CHECK-NEXT: ) @@ -3673,7 +3673,7 @@ drop ) - ;; CHECK: (func $throw (type $void) + ;; CHECK: (func $throw (type $0) ;; CHECK-NEXT: (throw $timport$1) ;; CHECK-NEXT: (throw $tag-i32 ;; CHECK-NEXT: (i32.const 0) @@ -3704,7 +3704,7 @@ ref.eq ) - ;; CHECK: (func $table-get (type $void) + ;; CHECK: (func $table-get (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.get $timport$0 ;; CHECK-NEXT: (i32.const 0) @@ -3733,7 +3733,7 @@ drop ) - ;; CHECK: (func $table-set (type $void) + ;; CHECK: (func $table-set (type $0) ;; CHECK-NEXT: (table.set $timport$0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (ref.null nofunc) @@ -3759,7 +3759,7 @@ table.set $table-any ) - ;; CHECK: (func $table-size (type $void) + ;; CHECK: (func $table-size (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.size $timport$0) ;; CHECK-NEXT: ) @@ -3779,7 +3779,7 @@ drop ) - ;; CHECK: (func $table-grow (type $void) + ;; CHECK: (func $table-grow (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (table.grow $timport$0 ;; CHECK-NEXT: (ref.null nofunc) @@ -3814,7 +3814,7 @@ drop ) - ;; CHECK: (func $table-fill (type $void) + ;; CHECK: (func $table-fill (type $0) ;; CHECK-NEXT: (table.fill $timport$0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (ref.null nofunc) @@ -3846,7 +3846,7 @@ table.fill $table-any ) - ;; CHECK: (func $table-copy (type $void) + ;; CHECK: (func $table-copy (type $0) ;; CHECK-NEXT: (table.copy $timport$0 $timport$0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i32.const 1) @@ -3900,7 +3900,7 @@ drop ) - ;; CHECK: (func $call-ref (type $void) + ;; CHECK: (func $call-ref (type $0) ;; CHECK-NEXT: (local $0 (ref null $void)) ;; CHECK-NEXT: (local $1 (ref null $ret2)) ;; CHECK-NEXT: (local $2 (ref null $many)) @@ -3972,7 +3972,7 @@ drop ) - ;; CHECK: (func $ref-test (type $8) (param $0 anyref) + ;; CHECK: (func $ref-test (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.test i31ref ;; CHECK-NEXT: (local.get $0) @@ -3993,7 +3993,7 @@ drop ) - ;; CHECK: (func $ref-cast (type $8) (param $0 anyref) + ;; CHECK: (func $ref-cast (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast i31ref ;; CHECK-NEXT: (local.get $0) @@ -4014,7 +4014,7 @@ drop ) - ;; CHECK: (func $br-on-null (type $8) (param $0 anyref) + ;; CHECK: (func $br-on-null (type $9) (param $0 anyref) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_on_null $label @@ -4029,7 +4029,7 @@ drop ) - ;; CHECK: (func $br-on-non-null (type $8) (param $0 anyref) + ;; CHECK: (func $br-on-non-null (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $block (result (ref any)) ;; CHECK-NEXT: (br_on_non_null $block @@ -4048,7 +4048,7 @@ drop ) - ;; CHECK: (func $br-on-cast (type $8) (param $0 anyref) + ;; CHECK: (func $br-on-cast (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $block (result i31ref) ;; CHECK-NEXT: (drop @@ -4073,7 +4073,7 @@ drop ) - ;; CHECK: (func $br-on-cast-fail (type $8) (param $0 anyref) + ;; CHECK: (func $br-on-cast-fail (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $block (result (ref any)) ;; CHECK-NEXT: (drop @@ -4217,7 +4217,7 @@ array.new_data $a1 0 ) - ;; CHECK: (func $array-new-fixed (type $void) + ;; CHECK: (func $array-new-fixed (type $0) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (array.new_fixed $a0 0) ;; CHECK-NEXT: ) @@ -4365,7 +4365,7 @@ array.init_elem $any-array $passive-2 ) - ;; CHECK: (func $ref-as-non-null (type $8) (param $0 anyref) + ;; CHECK: (func $ref-as-non-null (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $0) @@ -4391,7 +4391,7 @@ drop ) - ;; CHECK: (func $extern-convert-any (type $8) (param $0 anyref) + ;; CHECK: (func $extern-convert-any (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.externalize ;; CHECK-NEXT: (local.get $0) @@ -4561,14 +4561,14 @@ return_call $return_call ) - ;; CHECK: (func $call-indirect (type $11) (param $0 i32) (param $1 i64) (param $2 v128) - ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK: (func $call-indirect (type $12) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) @@ -4580,13 +4580,13 @@ ;; CHECK-NEXT: (call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -4623,14 +4623,14 @@ drop ) - ;; CHECK: (func $call-indirect-folded (type $11) (param $0 i32) (param $1 i64) (param $2 v128) - ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK: (func $call-indirect-folded (type $12) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) @@ -4642,13 +4642,13 @@ ;; CHECK-NEXT: (call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -4696,14 +4696,14 @@ ) ) - ;; CHECK: (func $return-call-indirect (type $11) (param $0 i32) (param $1 i64) (param $2 v128) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK: (func $return-call-indirect (type $12) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) @@ -4715,13 +4715,13 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $31) @@ -4755,14 +4755,14 @@ return_call_indirect (param i64 v128) ) - ;; CHECK: (func $return-call-indirect-folded (type $11) (param $0 i32) (param $1 i64) (param $2 v128) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK: (func $return-call-indirect-folded (type $12) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) @@ -4774,13 +4774,13 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $0) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $31) @@ -4899,7 +4899,7 @@ suspend $tag-pair-to-pair ) - ;; CHECK: (func $source-maps (type $void) + ;; CHECK: (func $source-maps (type $0) ;; CHECK-NEXT: ;;@ src.cpp:40:1 ;; CHECK-NEXT: (drop ;; CHECK-NEXT: ;;@ src.cpp:30:1 @@ -4960,7 +4960,7 @@ end ) - ;; CHECK: (func $source-map-propagation (type $void) + ;; CHECK: (func $source-map-propagation (type $0) ;; CHECK-NEXT: ;;@ src.cpp:20:1 ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add @@ -5050,7 +5050,7 @@ (i32.const 1) ) - ;; CHECK: (func $try-br-catch-all-return (type $void) + ;; CHECK: (func $try-br-catch-all-return (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do @@ -5073,7 +5073,7 @@ ) ) - ;; CHECK: (func $try-br-catch-return (type $void) + ;; CHECK: (func $try-br-catch-return (type $0) ;; CHECK-NEXT: (block $label ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do From cf2725b434c724fdcac89f5c2a21e09f33f5a121 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 14 Jun 2024 16:28:45 -0700 Subject: [PATCH 389/553] [Parser] Fix error message on required reftype (#6666) Not all uses of the `reftype` parser handled the fact that it returned a `MaybeResult`. Change its name to `maybeReftype`, add a new `reftype` parser that returns an error if there is no reftype, and update all the use sites. Fixes #6655. --- src/parser/parsers.h | 24 +++++++++++++++--------- test/spec/ref_cast.wast | 5 +++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/parser/parsers.h b/src/parser/parsers.h index e56efb529a0..1c329aecb94 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -28,7 +28,8 @@ using namespace std::string_view_literals; // Types template Result heaptype(Ctx&); -template MaybeResult reftype(Ctx&); +template MaybeResult maybeRefType(Ctx&); +template Result reftype(Ctx&); template MaybeResult tupletype(Ctx&); template Result valtype(Ctx&); template @@ -419,7 +420,7 @@ template Result heaptype(Ctx& ctx) { // | 'structref' => structref // | 'arrayref' => arrayref // | '(' ref null? t:heaptype ')' => ref null? t -template MaybeResult reftype(Ctx& ctx) { +template MaybeResult maybeReftype(Ctx& ctx) { if (ctx.in.takeKeyword("funcref"sv)) { return ctx.makeRefType(ctx.makeFuncType(), Nullable); } @@ -482,6 +483,14 @@ template MaybeResult reftype(Ctx& ctx) { return ctx.makeRefType(*type, nullability); } +template Result reftype(Ctx& ctx) { + if (auto t = maybeReftype(ctx)) { + CHECK_ERR(t); + return *t; + } + return ctx.in.err("expected reftype"); +} + // tupletype ::= '(' 'tuple' valtype* ')' template MaybeResult tupletype(Ctx& ctx) { if (!ctx.in.takeSExprStart("tuple"sv)) { @@ -520,7 +529,7 @@ template Result singlevaltype(Ctx& ctx) { return ctx.makeF64(); } else if (ctx.in.takeKeyword("v128"sv)) { return ctx.makeV128(); - } else if (auto type = reftype(ctx)) { + } else if (auto type = maybeReftype(ctx)) { CHECK_ERR(type); return *type; } else { @@ -788,10 +797,6 @@ Result tabletypeContinued(Ctx& ctx, Type indexType) { CHECK_ERR(limits); auto type = reftype(ctx); CHECK_ERR(type); - - if (!type) { - return ctx.in.err("expected reftype"); - } return ctx.makeTableType(indexType, *limits, *type); } @@ -2999,7 +3004,7 @@ template MaybeResult<> table(Ctx& ctx) { } // Reftype if we have inline elements. - auto type = reftype(ctx); + auto type = maybeReftype(ctx); CHECK_ERR(type); std::optional ttype; @@ -3246,7 +3251,8 @@ MaybeResult maybeElemexpr(Ctx& ctx) { // | funcidx* (iff the tableuse is omitted) template Result elemlist(Ctx& ctx, bool legacy) { - if (auto type = reftype(ctx)) { + if (auto type = maybeReftype(ctx)) { + CHECK_ERR(type); auto res = ctx.makeElemList(*type); while (auto elem = maybeElemexpr(ctx)) { CHECK_ERR(elem); diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast index b46622a40aa..927d82ebcaf 100644 --- a/test/spec/ref_cast.wast +++ b/test/spec/ref_cast.wast @@ -169,3 +169,8 @@ ) "common supertype" ) + +(assert_malformed + (module quote "(func (ref.cast i32 (unreachable)))") + "expected reftype" +) From d849a43040dfc21d1593283ad38a12a3bd80e17c Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 17 Jun 2024 11:16:20 -0700 Subject: [PATCH 390/553] Enable more spec tests (#6669) Re-triage all the disabled spec tests and re-enable many of them. Improve the module splitting logic to correctly handle (by skipping) quoted modules and their associated assertions. --- check.py | 48 ++++++++++++++------------------- scripts/test/shared.py | 60 +++++++++++++---------------------------- scripts/test/support.py | 13 ++++++++- test/spec/stack.wast | 51 ++++++++++++++++++++++------------- 4 files changed, 83 insertions(+), 89 deletions(-) diff --git a/check.py b/check.py index 946e3a0cf27..66493dd3c6f 100755 --- a/check.py +++ b/check.py @@ -221,38 +221,30 @@ def check_expected(actual, expected): check_expected(actual, expected) - # skip binary checks for tests that reuse previous modules by name, as that's a wast-only feature - if 'exports.wast' in base: # FIXME - continue - run_spec_test(wast) # check binary format. here we can verify execution of the final # result, no need for an output verification - # some wast files cannot be split: - # * comments.wast: contains characters that are not valid utf-8, - # so our string splitting code fails there - - # FIXME Remove reference type tests from this list after nullref is - # implemented in V8 - if base not in ['comments.wast', 'ref_null.wast', 'ref_is_null.wast', 'ref_func.wast', 'old_select.wast']: - split_num = 0 - actual = '' - with open('spec.wast', 'w') as transformed_spec_file: - for module, asserts in support.split_wast(wast): - print(' testing split module', split_num) - split_num += 1 - support.write_wast('split.wast', module) - run_opt_test('split.wast') # also that our optimizer doesn't break on it - result_wast_file = shared.binary_format_check('split.wast', verify_final_result=False) - with open(result_wast_file) as f: - result_wast = f.read() - # add the asserts, and verify that the test still passes - transformed_spec_file.write(result_wast + '\n' + '\n'.join(asserts)) - - # compare all the outputs to the expected output - actual = run_spec_test('spec.wast') - check_expected(actual, os.path.join(shared.get_test_dir('spec'), 'expected-output', base + '.log')) + split_num = 0 + actual = '' + with open('spec.wast', 'w') as transformed_spec_file: + for module, asserts in support.split_wast(wast): + if not module: + # Skip any initial assertions that don't have a module + continue + print(' testing split module', split_num) + split_num += 1 + support.write_wast('split.wast', module) + run_opt_test('split.wast') # also that our optimizer doesn't break on it + result_wast_file = shared.binary_format_check('split.wast', verify_final_result=False) + with open(result_wast_file) as f: + result_wast = f.read() + # add the asserts, and verify that the test still passes + transformed_spec_file.write(result_wast + '\n' + '\n'.join(asserts)) + + # compare all the outputs to the expected output + actual = run_spec_test('spec.wast') + check_expected(actual, os.path.join(shared.get_test_dir('spec'), 'expected-output', base + '.log')) def run_validator_tests(): diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 68c8b9d9404..847dd9de5cf 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -399,57 +399,33 @@ def get_tests(test_dir, extensions=[], recursive=False): # delete the old file, make sure you rename the corresponding .wast.log file in # expected-output/ if any. SPEC_TESTS_TO_SKIP = [ - # Stacky code / notation - 'block.wast', - 'call.wast', - 'float_exprs.wast', + # Malformed module accepted 'globals.wast', - 'loop.wast', - 'nop.wast', - 'select.wast', - 'stack.wast', - 'unwind.wast', - - # Binary module - 'binary.wast', 'binary-leb128.wast', - 'custom.wast', - - # Empty 'then' or 'else' in 'if' - 'if.wast', - 'local_set.wast', - 'store.wast', - - # No module in a file - 'token.wast', 'utf8-custom-section-id.wast', 'utf8-import-field.wast', 'utf8-import-module.wast', 'utf8-invalid-encoding.wast', + 'const.wast', + 'address.wast', + 'custom.wast', # invalid section ID accepted as Custom, triggering UBSan - # 'register' command + # Unlinkable module accepted 'linking.wast', - # Misc. unsupported constructs - 'call_indirect.wast', # Empty (param) and (result) - 'const.wast', # Unparenthesized expression - 'data.wast', # Various unsupported (data) notations - 'elem.wast', # Unsupported 'offset' syntax in (elem) - 'exports.wast', # Multiple inlined exports for a function - 'func.wast', # Forward named type reference - 'skip-stack-guard-page.wast', # Hexadecimal style (0x..) in memory offset - - # Untriaged: We don't know the cause of the error yet - 'address.wast', # wasm2js 'assert_return' failure - 'br_if.wast', # Validation error - 'float_literals.wast', # 'assert_return' failure - 'int_literals.wast', # 'assert_return' failure - 'local_tee.wast', # Validation failure - 'memory_grow.wast', # 'assert_return' failure - 'start.wast', # Assertion failure - 'type.wast', # 'assertion_invalid' failure - 'unreachable.wast', # Validation failure - 'unreached-invalid.wast' # 'assert_invalid' failure + # Invalid module accepted + 'func.wast', + 'type.wast', + 'unreached-invalid.wast', + + # WAT parser error + 'unwind.wast', + + # WAST parser error + 'binary.wast', + + # Test invalid + 'elem.wast', ] options.spec_tests = [t for t in options.spec_tests if os.path.basename(t) not in SPEC_TESTS_TO_SKIP] diff --git a/scripts/test/support.py b/scripts/test/support.py index 3a6ed9bc25d..43bd00fe8a0 100644 --- a/scripts/test/support.py +++ b/scripts/test/support.py @@ -14,6 +14,7 @@ import filecmp import os +import re import shutil import subprocess import sys @@ -87,6 +88,9 @@ def untar(tarfile, outdir): shutil.rmtree(tmpdir) +QUOTED = re.compile(r'\(module\s*(\$\S*)?\s+(quote|binary)') + + def split_wast(wastFile): # if it's a binary, leave it as is, we can't split it wast = None @@ -124,6 +128,7 @@ def to_end(j): return j i = 0 + ignoring_quoted = False while i >= 0: start = wast.find('(', i) if start >= 0 and wast[start + 1] == ';': @@ -141,11 +146,17 @@ def to_end(j): break i = to_end(start + 1) chunk = wast[start:i] + if QUOTED.match(chunk): + # There may be assertions after this quoted module, but we aren't + # returning the module, so we need to skip the assertions as well. + ignoring_quoted = True + continue if chunk.startswith('(module'): + ignoring_quoted = False ret += [(chunk, [])] elif chunk.startswith('(assert_invalid'): continue - elif chunk.startswith(('(assert', '(invoke', '(register')): + elif chunk.startswith(('(assert', '(invoke', '(register')) and not ignoring_quoted: # ret may be empty if there are some asserts before the first # module. in that case these are asserts *without* a module, which # are valid (they may check something that doesn't refer to a module diff --git a/test/spec/stack.wast b/test/spec/stack.wast index a8c79b6986e..5da5043c8e9 100644 --- a/test/spec/stack.wast +++ b/test/spec/stack.wast @@ -34,17 +34,15 @@ (i64.eq) (if (then (br $done)) - (then - (else - (local.get $i) - (local.get $res) - (i64.mul) - (local.set $res) - (local.get $i) - (i64.const 1) - (i64.sub) - (local.set $i) - ) + (else + (local.get $i) + (local.get $res) + (i64.mul) + (local.set $res) + (local.get $i) + (i64.const 1) + (i64.sub) + (local.set $i) ) ) (br $loop) @@ -93,13 +91,11 @@ (i64.eq (local.get $i) (i64.const 0)) (if (then (br $done)) - (then - (else - (i64.mul (local.get $i) (local.get $res)) - (local.set $res) - (i64.sub (local.get $i) (i64.const 1)) - (local.set $i) - ) + (else + (i64.mul (local.get $i) (local.get $res)) + (local.set $res) + (i64.sub (local.get $i) (i64.const 1)) + (local.set $i) ) ) (br $loop) @@ -129,12 +125,31 @@ end local.get $res ) + + (global $temp (mut i32) (i32.const 0)) + (func $add_one_to_global (result i32) + (local i32) + (global.set $temp (i32.add (i32.const 1) (global.get $temp))) + (global.get $temp) + ) + (func $add_one_to_global_and_drop + (drop (call $add_one_to_global)) + ) + (func (export "not-quite-a-tree") (result i32) + call $add_one_to_global + call $add_one_to_global + call $add_one_to_global_and_drop + i32.add + ) ) (assert_return (invoke "fac-expr" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-stack" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-mixed" (i64.const 25)) (i64.const 7034535277573963776)) +(assert_return (invoke "not-quite-a-tree") (i32.const 3)) +(assert_return (invoke "not-quite-a-tree") (i32.const 9)) + ;; Syntax of flat call_indirect From 1dd05202ced86548361d5efc439ad106007f8bb8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 17 Jun 2024 14:36:38 -0700 Subject: [PATCH 391/553] wasm2js: Support arbitrary temp variable types (#6661) Previously only basic types were allowed. Generalizing this to arbitrary types means we use a map instead of a vector, which is slower, but I can't measure any noticeable difference. Temp vars are pretty rare, and there are just much slower parts of wasm2js, I think. --- src/wasm2js.h | 38 +++++++++++++++++------------------ test/wasm2js/refs.2asm.js | 15 +++++++++++++- test/wasm2js/refs.2asm.js.opt | 9 ++++++++- test/wasm2js/refs.wast | 19 ++++++++++++++++++ 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 34260547d25..321734688e7 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -206,12 +206,13 @@ class Wasm2JSBuilder { // Get a temp var. IString getTemp(Type type, Function* func) { IString ret; - TODO_SINGLE_COMPOUND(type); - if (frees[type.getBasic()].size() > 0) { - ret = frees[type.getBasic()].back(); - frees[type.getBasic()].pop_back(); + // TODO: handle tuples + assert(!type.isTuple() && "Unexpected tuple type"); + if (frees[type].size() > 0) { + ret = frees[type].back(); + frees[type].pop_back(); } else { - size_t index = temps[type.getBasic()]++; + auto index = temps[type]++; ret = IString((std::string("wasm2js_") + type.toString() + "$" + std::to_string(index)) .c_str(), @@ -225,8 +226,9 @@ class Wasm2JSBuilder { // Free a temp var. void freeTemp(Type type, IString temp) { - TODO_SINGLE_COMPOUND(type); - frees[type.getBasic()].push_back(temp); + // TODO: handle tuples + assert(!type.isTuple() && "Unexpected tuple type"); + frees[type].push_back(temp); } // Generates a mangled name from `name` within the specified scope. @@ -300,10 +302,10 @@ class Wasm2JSBuilder { Flags flags; PassOptions options; - // How many temp vars we need - std::vector temps; // type => num temps - // Which are currently free to use - std::vector> frees; // type => list of free names + // How many temp vars we need for each type (type => num). + std::unordered_map temps; + // Which temp vars are currently free to use for each type (type => freelist). + std::unordered_map> frees; // Mangled names cache by interned names. // Utilizes the usually reused underlying cstring's pointer as the key. @@ -874,15 +876,15 @@ Ref Wasm2JSBuilder::processFunction(Module* m, runner.runOnFunction(func); } + // We process multiple functions from a single Wasm2JSBuilder instance, so + // clean up the function-specific local state before each function. + frees.clear(); + temps.clear(); + // We will be symbolically referring to all variables in the function, so make // sure that everything has a name and it's unique. Names::ensureNames(func); Ref ret = ValueBuilder::makeFunction(fromName(func->name, NameScope::Top)); - frees.clear(); - frees.resize(std::max(Type::i32, std::max(Type::f32, Type::f64)) + 1); - temps.clear(); - temps.resize(std::max(Type::i32, std::max(Type::f32, Type::f64)) + 1); - temps[Type::i32] = temps[Type::f32] = temps[Type::f64] = 0; // arguments bool needCoercions = options.optimizeLevel == 0 || standaloneFunction || functionsCallableFromOutside.count(func->name); @@ -915,10 +917,6 @@ Ref Wasm2JSBuilder::processFunction(Module* m, if (theVar[1]->size() == 0) { ret[3]->splice(theVarIndex, 1); } - // checks: all temp vars should be free at the end - assert(frees[Type::i32].size() == temps[Type::i32]); - assert(frees[Type::f32].size() == temps[Type::f32]); - assert(frees[Type::f64].size() == temps[Type::f64]); return ret; } diff --git a/test/wasm2js/refs.2asm.js b/test/wasm2js/refs.2asm.js index f1d60af6cc6..f4c08408f70 100644 --- a/test/wasm2js/refs.2asm.js +++ b/test/wasm2js/refs.2asm.js @@ -50,6 +50,17 @@ function asmFunc(imports) { return temp; } + function funcref_temps($0, $1) { + $1 = +$1; + var $2 = null, $3 = null, wasm2js_funcref$0 = null, wasm2js_funcref$1 = null, wasm2js_i32$0 = 0; + $2 = $0; + loop : while (1) { + $3 = funcref_temps; + break loop; + }; + funcref_temps(funcref_temps, +(+((wasm2js_funcref$0 = $2, wasm2js_funcref$1 = $3 || wasm2js_trap(), wasm2js_i32$0 = 0, wasm2js_i32$0 ? wasm2js_funcref$0 : wasm2js_funcref$1) == null | 0))); + } + return { "null_": null_, "is_null": is_null, @@ -57,7 +68,8 @@ function asmFunc(imports) { "ref_eq": ref_eq, "ref_as": ref_as, "use_global": use_global, - "use_global_ref": use_global_ref + "use_global_ref": use_global_ref, + "funcref_temps": funcref_temps }; } @@ -70,3 +82,4 @@ export var ref_eq = retasmFunc.ref_eq; export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; export var use_global_ref = retasmFunc.use_global_ref; +export var funcref_temps = retasmFunc.funcref_temps; diff --git a/test/wasm2js/refs.2asm.js.opt b/test/wasm2js/refs.2asm.js.opt index fa1947215a8..0071a15b53e 100644 --- a/test/wasm2js/refs.2asm.js.opt +++ b/test/wasm2js/refs.2asm.js.opt @@ -48,6 +48,11 @@ function asmFunc(imports) { return $1; } + function funcref_temps($0, $1) { + $1 = +$1; + funcref_temps(funcref_temps, 0.0); + } + return { "null_": null_, "is_null": is_null, @@ -55,7 +60,8 @@ function asmFunc(imports) { "ref_eq": ref_eq, "ref_as": ref_as, "use_global": use_global, - "use_global_ref": use_global_ref + "use_global_ref": use_global_ref, + "funcref_temps": funcref_temps }; } @@ -68,3 +74,4 @@ export var ref_eq = retasmFunc.ref_eq; export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; export var use_global_ref = retasmFunc.use_global_ref; +export var funcref_temps = retasmFunc.funcref_temps; diff --git a/test/wasm2js/refs.wast b/test/wasm2js/refs.wast index 244cf2e974e..087567e8ce7 100644 --- a/test/wasm2js/refs.wast +++ b/test/wasm2js/refs.wast @@ -62,4 +62,23 @@ ) (local.get $temp) ) + + (func $funcref_temps (export "funcref_temps") (param $0 funcref) (param $1 f64) + ;; A deeply-nested expression that ends up requiring multiple function type + ;; temp variables. + (call $funcref_temps + (ref.func $funcref_temps) + (f64.convert_i32_s + (ref.is_null + (select (result funcref) + (local.get $0) + (loop $loop (result funcref) + (ref.func $funcref_temps) + ) + (i32.const 0) + ) + ) + ) + ) + ) ) From b377b6f175cf5904d8e65eb8f2184c7379f97297 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 17 Jun 2024 15:21:05 -0700 Subject: [PATCH 392/553] Fix DataSegment name handling (#6673) The code used i instead of index, as in this pseudocode: for i in range(num_names): index = readU32LEB() # index of the data segment to name name = readName() # name to give that segment data[i] = name # XXX 'i' should be 'index' That (funnily enough) happened to always work before since we write names in order. That is, normally given segments A,B,C we'd write then in the names section as A,B,C. Then the reader, which had the bug, would always have i and index identical in value anyhow. But if a wasm producer used different indexes, a problem could happen. To test this, add a binary file that has a reversed name section. Fixes #6672 --- src/wasm/wasm-binary.cpp | 2 +- test/lit/binary/data-names.test | 25 +++++++++++++++++++++++++ test/lit/binary/data-names.test.wasm | Bin 0 -> 119 bytes 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/lit/binary/data-names.test create mode 100644 test/lit/binary/data-names.test.wasm diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 924bf1601ed..e08644eaede 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3700,7 +3700,7 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto rawName = getInlineString(); auto name = processor.process(rawName); if (index < wasm.dataSegments.size()) { - wasm.dataSegments[i]->setExplicitName(name); + wasm.dataSegments[index]->setExplicitName(name); } else { std::cerr << "warning: data index out of bounds in name section, " "data subsection: " diff --git a/test/lit/binary/data-names.test b/test/lit/binary/data-names.test new file mode 100644 index 00000000000..ab7baf5d75e --- /dev/null +++ b/test/lit/binary/data-names.test @@ -0,0 +1,25 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt -all %s.wasm -q -S -o - | filecheck %s + +;; Test that data segment names roundtrip properly. The wasm file contains +;; +;; (module +;; (memory $mem 10) +;; (data $passive1 "passive1") +;; (data $passive2 "passive2") +;; (data $active1 (offset i32.const 0) "active1") +;; (data $active2 (offset i32.const 0) "active2") +;; ) +;; +;; But the names section is *reversed*: the name of the last data segment is +;; first, and so forth. We must still give the proper segments their names. + +;; CHECK: (memory $mem 10) + +;; CHECK: (data $passive1 "passive1") + +;; CHECK: (data $passive2 "passive2") + +;; CHECK: (data $active1 (i32.const 0) "active1") + +;; CHECK: (data $active2 (i32.const 0) "active2") diff --git a/test/lit/binary/data-names.test.wasm b/test/lit/binary/data-names.test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7384aea5061b2a7f4b9ca378eb369589af03a270 GIT binary patch literal 119 zcmZQbEY4+QU|?WnW@O;vVPxUfWnttfNGvYSEK4 d+*CF;Mh52G)Lc$=7G|h2BPN)7Bvarf0{{r^9Yp{D literal 0 HcmV?d00001 From 0f9f2dc21a913164c5a8681b93b7db4d383a8c47 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 17 Jun 2024 16:16:50 -0700 Subject: [PATCH 393/553] GlobalStructInference: Optimize globals too (#6674) This is achieved by simply replacing the Literal with PossibleConstantValues, which supports both Literals and Globals. --- src/passes/GlobalStructInference.cpp | 21 ++++++------ test/lit/passes/gsi.wast | 51 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index 9fc906971cc..c0b92e3bb3b 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -50,7 +50,7 @@ #include "ir/find_all.h" #include "ir/module-utils.h" -#include "ir/properties.h" +#include "ir/possible-constant.h" #include "ir/subtypes.h" #include "ir/utils.h" #include "pass.h" @@ -300,7 +300,7 @@ struct GlobalStructInference : public Pass { // Find the constant values and which globals correspond to them. // TODO: SmallVectors? - std::vector values; + std::vector values; std::vector> globalsForValue; // Check if the relevant fields contain constants. @@ -308,16 +308,15 @@ struct GlobalStructInference : public Pass { for (Index i = 0; i < globals.size(); i++) { Name global = globals[i]; auto* structNew = wasm.getGlobal(global)->init->cast(); - Literal value; + PossibleConstantValues value; if (structNew->isWithDefault()) { - value = Literal::makeZero(fieldType); + value.note(Literal::makeZero(fieldType)); } else { - auto* init = structNew->operands[fieldIndex]; - if (!Properties::isConstantExpression(init)) { - // Non-constant; give up entirely. + value.note(structNew->operands[fieldIndex], wasm); + if (!value.isConstant()) { + // Give up entirely. return; } - value = Properties::getLiteral(init); } // Process the current value, comparing it against the previous. @@ -346,7 +345,7 @@ struct GlobalStructInference : public Pass { // otherwise return the value. replaceCurrent(builder.makeSequence( builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)), - builder.makeConstantExpression(values[0]))); + values[0].makeExpression(wasm))); return; } assert(values.size() == 2); @@ -373,8 +372,8 @@ struct GlobalStructInference : public Pass { builder.makeRefEq(builder.makeRefAs(RefAsNonNull, curr->ref), builder.makeGlobalGet( checkGlobal, wasm.getGlobal(checkGlobal)->type)), - builder.makeConstantExpression(values[0]), - builder.makeConstantExpression(values[1]))); + values[0].makeExpression(wasm), + values[1].makeExpression(wasm))); } void visitFunction(Function* func) { diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast index f60e911c7ba..15afea5ed48 100644 --- a/test/lit/passes/gsi.wast +++ b/test/lit/passes/gsi.wast @@ -1437,3 +1437,54 @@ ) ) ) + +;; Test that we can optimize global.get operations on immutable globals. +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $one i32 (i32.const 1)) + (global $one i32 (i32.const 1)) + + ;; CHECK: (global $two i32 (i32.const 2)) + (global $two i32 (i32.const 2)) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $one) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (global.get $one) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $two) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (global.get $two) + )) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $one) + ;; CHECK-NEXT: (global.get $two) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + ;; The get here will read one of the two globals, so we can use a select. + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) +) From c3b9cde9d99efe46fc34af1d5b27351f34962e94 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 11:13:05 -0700 Subject: [PATCH 394/553] Reject invalid section IDs (#6675) Rather than treating them as custom sections. Also fix UB where invalid `Section` enum values could be used as keys in a map. Use the raw `uint8_t` section IDs as keys instead. Re-enable a disabled spec test that was failing because of this bug and UB. --- scripts/test/shared.py | 1 - src/wasm-binary.h | 2 +- src/wasm/wasm-binary.cpp | 13 +++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 847dd9de5cf..f5fda92a56b 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -408,7 +408,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'utf8-invalid-encoding.wast', 'const.wast', 'address.wast', - 'custom.wast', # invalid section ID accepted as Custom, triggering UBSan # Unlinkable module accepted 'linking.wast', diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9a79a4c8b89..f7d57f5c9f2 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1453,7 +1453,7 @@ class WasmBinaryReader { Index startIndex = -1; std::set debugLocation; size_t codeSectionLocation; - std::set seenSections; + std::unordered_set seenSections; // All types defined in the type section std::vector types; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index e08644eaede..b05dd52372b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1784,11 +1784,8 @@ void WasmBinaryReader::read() { // note the section in the list of seen sections, as almost no sections can // appear more than once, and verify those that shouldn't do not. if (sectionCode != BinaryConsts::Section::Custom && - sectionCode != BinaryConsts::Section::Code) { - if (!seenSections.insert(BinaryConsts::Section(sectionCode)).second) { - throwError("section seen more than once: " + - std::to_string(sectionCode)); - } + !seenSections.insert(sectionCode).second) { + throwError("section seen more than once: " + std::to_string(sectionCode)); } switch (sectionCode) { @@ -1837,7 +1834,7 @@ void WasmBinaryReader::read() { case BinaryConsts::Section::Tag: readTags(); break; - default: { + case BinaryConsts::Section::Custom: { readCustomSection(payloadLen); if (pos > oldPos + payloadLen) { throwError("bad user section size, started at " + @@ -1846,7 +1843,11 @@ void WasmBinaryReader::read() { " not being equal to new position " + std::to_string(pos)); } pos = oldPos + payloadLen; + break; } + default: + throwError(std::string("unrecognized section ID: ") + + std::to_string(sectionCode)); } // make sure we advanced exactly past this section From 408bc7fbbe193648cb242bdbd096205aa776634b Mon Sep 17 00:00:00 2001 From: mtb <39337159+mtb0x1@users.noreply.github.com> Date: Wed, 19 Jun 2024 01:09:19 +0200 Subject: [PATCH 395/553] fix(#6671): fix possible stack buffer overflow in gen-s-parser.inc (#6678) The stack buffer overflow is occurring because memcpy(buf, op.data(), op.size()); can write up to op.size() bytes into buf, but buf is only 33 bytes long. If op.size() is greater than 33, this will result in a buffer overflow. --- scripts/gen-s-parser.py | 6 ++++++ src/gen-s-parser.inc | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index d75be7635fc..2aa158c59ec 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -708,6 +708,10 @@ def instruction_parser(): printer.print_line("auto op = *keyword;") printer.print_line("char buf[{}] = {{}};".format(inst_length + 1)) + printer.print_line("// Ensure we do not copy more than the buffer can hold") + printer.print_line("if (op.size() >= sizeof(buf)) {") + printer.print_line(" goto parse_error;") + printer.print_line("}") printer.print_line("memcpy(buf, op.data(), op.size());") def print_leaf(expr, inst): @@ -754,9 +758,11 @@ def emit(node, idx=0): def print_header(): print("// DO NOT EDIT! This file generated by scripts/gen-s-parser.py\n") print("// clang-format off\n") + print("// NOLINTBEGIN\n") def print_footer(): + print("\n// NOLINTEND") print("\n// clang-format on") diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 5cdb29d833d..03b346113e1 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -2,8 +2,14 @@ // clang-format off +// NOLINTBEGIN + auto op = *keyword; char buf[33] = {}; +// Ensure we do not copy more than the buffer can hold +if (op.size() >= sizeof(buf)) { + goto parse_error; +} memcpy(buf, op.data(), op.size()); switch (buf[0]) { case 'a': { @@ -5151,4 +5157,6 @@ switch (buf[0]) { parse_error: return ctx.in.err(pos, "unrecognized instruction"); +// NOLINTEND + // clang-format on From 829e228d4b2ccb314ea1e653fd16154ae3fd31b3 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 17:14:09 -0700 Subject: [PATCH 396/553] [Parser] Fix bug in unreachable fallback logic (#6676) When popping past an unreachable instruction would lead to popping from an empty stack or popping an incorrect type, we need to avoid popping and produce new Unreachable instructions instead to ensure we parse valid IR. The logic for this was flawed and made the synthetic Unreachable come before the popped unreachable child, which was not correct in the case that that popped unreachable was a branch or other non-trapping instruction. Fix and simplify the logic and re-enable the spec test that uncovered the bug. --- scripts/test/shared.py | 3 --- src/wasm/wasm-ir-builder.cpp | 31 +++++++++++++++------------ test/lit/wat-kitchen-sink.wast | 38 +++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index f5fda92a56b..0e7062437d8 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -417,9 +417,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'type.wast', 'unreached-invalid.wast', - # WAT parser error - 'unwind.wast', - # WAST parser error 'binary.wast', diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index bf737bbd674..63f5df4c046 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -407,9 +407,12 @@ struct IRBuilder::ChildPopper --stackTupleIndex; } else { if (stackIndex == 0) { - // No more available values. This is fine iff we are reaching past - // an unreachable. Any error will be caught later when we are - // popping. + // No more available values. This is valid iff we are reaching past + // an unreachable, but we still need the fallback behavior to ensure + // the input unreachable instruction is executed first. If we are + // not reaching past an unreachable, the error will be caught when + // we pop. + needUnreachableFallback = true; goto pop; } --stackIndex; @@ -458,18 +461,20 @@ struct IRBuilder::ChildPopper // We have checked all the constraints, so we are ready to pop children. for (int i = children.size() - 1; i >= 0; --i) { if (needUnreachableFallback && - scope.exprStack.size() == *unreachableIndex + 1) { - // The expressions remaining on the stack may be executed, but they do - // not satisfy the requirements to be children of the current parent. - // Explicitly drop them so they will still be executed for their side - // effects and so the remaining children will be filled with - // unreachables. - assert(scope.exprStack.back()->type == Type::unreachable); - for (auto& expr : scope.exprStack) { - expr = Builder(builder.wasm).dropIfConcretelyTyped(expr); - } + scope.exprStack.size() == *unreachableIndex + 1 && i > 0) { + // The next item on the stack is the unreachable instruction we must + // not pop past. We cannot insert unreachables in front of it because + // it might be a branch we actually have to execute, so this next item + // must be child 0. But we are not ready to pop child 0 yet, so + // synthesize an unreachable instead of popping. The deeper + // instructions that would otherwise have been popped will remain on + // the stack to become prior children of future expressions or to be + // implicitly dropped at the end of the scope. + *children[i].childp = builder.builder.makeUnreachable(); + continue; } + // Pop a child normally. auto val = pop(children[i].constraint.size()); CHECK_ERR(val); *children[i].childp = *val; diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 170c962aa33..87778bd246d 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -2728,6 +2728,42 @@ br 0 ) + ;; CHECK: (func $br-mismatch-after (type $1) (result i32) + ;; CHECK-NEXT: (block $label (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (br $label + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-mismatch-after (result i32) + i32.const 1 + br 0 + i32.add + ) + + ;; CHECK: (func $br-mismatch-after-extra (type $1) (result i32) + ;; CHECK-NEXT: (block $label (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (br $label + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $br-mismatch-after-extra (result i32) + i64.const 0 + i32.const 1 + br 0 + i32.add + ) + ;; CHECK: (func $br_if (type $0) ;; CHECK-NEXT: (block $l ;; CHECK-NEXT: (br_if $l @@ -3669,7 +3705,7 @@ (func $ref-func ref.func $ref-func drop - ref.func 159 + ref.func 161 drop ) From 2df678e4670517eaac40d1d2d9541d3b706b324b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 18:20:49 -0700 Subject: [PATCH 397/553] [threads] Shared basic heap types (#6667) Implement binary and text parsing and printing of shared basic heap types and incorporate them into the type hierarchy. To avoid the massive amount of code duplication that would be necessary if we were to add separate enum variants for each of the shared basic heap types, use bit 0 to indicate whether the type is shared and replace `getBasic()` with `getBasic(Unshared)`, which clears that bit. Update all the use sites to record whether the original type was shared and produce shared or unshared output without code duplication. --- src/analysis/lattices/shared.h | 18 +- src/binaryen-c.cpp | 4 +- src/ir/type-updating.cpp | 2 +- src/parser/contexts.h | 93 ++++++---- src/parser/parsers.h | 91 ++++++---- src/passes/TypeGeneralizing.cpp | 7 +- src/tools/fuzzing/fuzzing.cpp | 6 +- src/tools/fuzzing/heap-types.cpp | 6 +- src/tools/wasm-fuzz-lattices.cpp | 13 +- src/wasm-type.h | 64 ++++--- src/wasm/literal.cpp | 14 +- src/wasm/wasm-binary.cpp | 23 ++- src/wasm/wasm-type.cpp | 190 ++++++++++++--------- test/example/c-api-kitchen-sink.txt | 20 +-- test/gtest/lattices.cpp | 10 +- test/gtest/type-builder.cpp | 209 ++++++++++++++++++++++- test/lit/basic/shared-types.wast | 42 ++++- test/lit/basic/typed_continuations.wast | 8 +- test/lit/passes/type-merging-shared.wast | 22 +++ test/lit/wat-kitchen-sink.wast | 32 ++-- 20 files changed, 623 insertions(+), 251 deletions(-) diff --git a/src/analysis/lattices/shared.h b/src/analysis/lattices/shared.h index 54acf92b42e..f345014b93d 100644 --- a/src/analysis/lattices/shared.h +++ b/src/analysis/lattices/shared.h @@ -27,10 +27,10 @@ namespace wasm::analysis { // A lattice whose elements are a single ascending chain in lattice `L`. // Internally, there is only ever a single monotonically increasing element of L -// materialized. Dereferencing any element of the Shared lattice will produce -// the current value of that single element of L, which is generally safe -// because the current value always overapproximates (i.e. is higher in the -// lattice than) the value at the time of the Shared element's construction. +// materialized. Dereferencing any element of the SharedPath lattice will +// produce the current value of that single element of L, which is generally +// safe because the current value always overapproximates (i.e. is higher in the +// lattice than) the value at the time of the SharedPath element's construction. // // Each element of this lattice maintains a sequence number that corresponds to // a value the shared underlying element has had at some point in time. Higher @@ -38,7 +38,7 @@ namespace wasm::analysis { // Elements of this lattice are compared and joined using these sequence // numbers, so blocks will correctly be re-analyzed if the value has increased // since the last time they were analyzed. -template struct Shared { +template struct SharedPath { // If we ever have extremely long-running analyses, this may need to be // changed to uint64_t. using Seq = uint32_t; @@ -70,7 +70,7 @@ template struct Shared { return !(*this == other); } - friend Shared; + friend SharedPath; }; L lattice; @@ -84,7 +84,7 @@ template struct Shared { mutable typename L::Element val; mutable Seq seq = 0; - Shared(L&& l) : lattice(std::move(l)), val(lattice.getBottom()) {} + SharedPath(L&& l) : lattice(std::move(l)), val(lattice.getBottom()) {} // TODO: Delete the move constructor and the move assignment operator. This // requires fixing the lattice fuzzer first, since it depends on lattices @@ -119,10 +119,10 @@ template struct Shared { }; // Deduction guide. -template Shared(L&&) -> Shared; +template SharedPath(L&&) -> SharedPath; #if __cplusplus >= 202002L -static_assert(Lattice>); +static_assert(Lattice>); #endif // __cplusplus >= 202002L } // namespace wasm::analysis diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 4e7fb0b61d7..841fa61eef7 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -78,7 +78,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { assert(x.type.isRef()); auto heapType = x.type.getHeapType(); if (heapType.isBasic()) { - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::i31: WASM_UNREACHABLE("TODO: i31"); case HeapType::ext: @@ -132,7 +132,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { assert(type.isRef()); auto heapType = type.getHeapType(); if (heapType.isBasic()) { - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::i31: WASM_UNREACHABLE("TODO: i31"); case HeapType::ext: diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index d9935ee32d8..ceb37300a91 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -90,7 +90,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( i = 0; for (auto [type, _] : typeIndices) { typeBuilder[i].setOpen(type.isOpen()); - typeBuilder[i].setShared(type.isShared()); + typeBuilder[i].setShared(type.getShared()); if (type.isSignature()) { auto sig = type.getSignature(); TypeList newParams, newResults; diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 6dabfca3d78..f58275d7115 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -105,24 +105,21 @@ struct NullTypeParserCtx { using ElemListT = Ok; using DataStringT = Ok; - HeapTypeT makeFuncType() { return Ok{}; } - HeapTypeT makeAnyType() { return Ok{}; } - HeapTypeT makeExternType() { return Ok{}; } - HeapTypeT makeEqType() { return Ok{}; } - HeapTypeT makeI31Type() { return Ok{}; } - HeapTypeT makeStructType() { return Ok{}; } - HeapTypeT makeArrayType() { return Ok{}; } - HeapTypeT makeExnType() { return Ok{}; } - HeapTypeT makeStringType() { return Ok{}; } - HeapTypeT makeStringViewWTF8Type() { return Ok{}; } - HeapTypeT makeStringViewWTF16Type() { return Ok{}; } - HeapTypeT makeStringViewIterType() { return Ok{}; } - HeapTypeT makeContType() { return Ok{}; } - HeapTypeT makeNoneType() { return Ok{}; } - HeapTypeT makeNoextType() { return Ok{}; } - HeapTypeT makeNofuncType() { return Ok{}; } - HeapTypeT makeNoexnType() { return Ok{}; } - HeapTypeT makeNocontType() { return Ok{}; } + HeapTypeT makeFuncType(Shareability) { return Ok{}; } + HeapTypeT makeAnyType(Shareability) { return Ok{}; } + HeapTypeT makeExternType(Shareability) { return Ok{}; } + HeapTypeT makeEqType(Shareability) { return Ok{}; } + HeapTypeT makeI31Type(Shareability) { return Ok{}; } + HeapTypeT makeStructType(Shareability) { return Ok{}; } + HeapTypeT makeArrayType(Shareability) { return Ok{}; } + HeapTypeT makeExnType(Shareability) { return Ok{}; } + HeapTypeT makeStringType(Shareability) { return Ok{}; } + HeapTypeT makeContType(Shareability) { return Ok{}; } + HeapTypeT makeNoneType(Shareability) { return Ok{}; } + HeapTypeT makeNoextType(Shareability) { return Ok{}; } + HeapTypeT makeNofuncType(Shareability) { return Ok{}; } + HeapTypeT makeNoexnType(Shareability) { return Ok{}; } + HeapTypeT makeNocontType(Shareability) { return Ok{}; } TypeT makeI32() { return Ok{}; } TypeT makeI64() { return Ok{}; } @@ -208,21 +205,51 @@ template struct TypeParserCtx { Ctx& self() { return *static_cast(this); } - HeapTypeT makeFuncType() { return HeapType::func; } - HeapTypeT makeAnyType() { return HeapType::any; } - HeapTypeT makeExternType() { return HeapType::ext; } - HeapTypeT makeEqType() { return HeapType::eq; } - HeapTypeT makeI31Type() { return HeapType::i31; } - HeapTypeT makeStructType() { return HeapType::struct_; } - HeapTypeT makeArrayType() { return HeapType::array; } - HeapTypeT makeExnType() { return HeapType::exn; } - HeapTypeT makeStringType() { return HeapType::string; } - HeapTypeT makeContType() { return HeapType::cont; } - HeapTypeT makeNoneType() { return HeapType::none; } - HeapTypeT makeNoextType() { return HeapType::noext; } - HeapTypeT makeNofuncType() { return HeapType::nofunc; } - HeapTypeT makeNoexnType() { return HeapType::noexn; } - HeapTypeT makeNocontType() { return HeapType::nocont; } + HeapTypeT makeFuncType(Shareability share) { + return HeapTypes::func.getBasic(share); + } + HeapTypeT makeAnyType(Shareability share) { + return HeapTypes::any.getBasic(share); + } + HeapTypeT makeExternType(Shareability share) { + return HeapTypes::ext.getBasic(share); + } + HeapTypeT makeEqType(Shareability share) { + return HeapTypes::eq.getBasic(share); + } + HeapTypeT makeI31Type(Shareability share) { + return HeapTypes::i31.getBasic(share); + } + HeapTypeT makeStructType(Shareability share) { + return HeapTypes::struct_.getBasic(share); + } + HeapTypeT makeArrayType(Shareability share) { + return HeapTypes::array.getBasic(share); + } + HeapTypeT makeExnType(Shareability share) { + return HeapTypes::exn.getBasic(share); + } + HeapTypeT makeStringType(Shareability share) { + return HeapTypes::string.getBasic(share); + } + HeapTypeT makeContType(Shareability share) { + return HeapTypes::cont.getBasic(share); + } + HeapTypeT makeNoneType(Shareability share) { + return HeapTypes::none.getBasic(share); + } + HeapTypeT makeNoextType(Shareability share) { + return HeapTypes::noext.getBasic(share); + } + HeapTypeT makeNofuncType(Shareability share) { + return HeapTypes::nofunc.getBasic(share); + } + HeapTypeT makeNoexnType(Shareability share) { + return HeapTypes::noexn.getBasic(share); + } + HeapTypeT makeNocontType(Shareability share) { + return HeapTypes::nocont.getBasic(share); + } TypeT makeI32() { return Type::i32; } TypeT makeI64() { return Type::i64; } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 1c329aecb94..db450e3c6a3 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -27,6 +27,8 @@ namespace wasm::WATParser { using namespace std::string_view_literals; // Types +template +Result absheaptype(Ctx&, Shareability); template Result heaptype(Ctx&); template MaybeResult maybeRefType(Ctx&); template Result reftype(Ctx&); @@ -358,58 +360,73 @@ template Result<> module(Ctx&); // Types // ===== -// heaptype ::= x:typeidx => types[x] -// | 'func' => func -// | 'extern' => extern -template Result heaptype(Ctx& ctx) { +// absheaptype ::= 'func' | 'extern' | ... +template +Result absheaptype(Ctx& ctx, Shareability share) { if (ctx.in.takeKeyword("func"sv)) { - return ctx.makeFuncType(); + return ctx.makeFuncType(share); } if (ctx.in.takeKeyword("any"sv)) { - return ctx.makeAnyType(); + return ctx.makeAnyType(share); } if (ctx.in.takeKeyword("extern"sv)) { - return ctx.makeExternType(); + return ctx.makeExternType(share); } if (ctx.in.takeKeyword("eq"sv)) { - return ctx.makeEqType(); + return ctx.makeEqType(share); } if (ctx.in.takeKeyword("i31"sv)) { - return ctx.makeI31Type(); + return ctx.makeI31Type(share); } if (ctx.in.takeKeyword("struct"sv)) { - return ctx.makeStructType(); + return ctx.makeStructType(share); } if (ctx.in.takeKeyword("array"sv)) { - return ctx.makeArrayType(); + return ctx.makeArrayType(share); } if (ctx.in.takeKeyword("exn"sv)) { - return ctx.makeExnType(); + return ctx.makeExnType(share); } if (ctx.in.takeKeyword("string"sv)) { - return ctx.makeStringType(); + return ctx.makeStringType(share); } if (ctx.in.takeKeyword("cont"sv)) { - return ctx.makeContType(); + return ctx.makeContType(share); } if (ctx.in.takeKeyword("none"sv)) { - return ctx.makeNoneType(); + return ctx.makeNoneType(share); } if (ctx.in.takeKeyword("noextern"sv)) { - return ctx.makeNoextType(); + return ctx.makeNoextType(share); } if (ctx.in.takeKeyword("nofunc"sv)) { - return ctx.makeNofuncType(); + return ctx.makeNofuncType(share); } if (ctx.in.takeKeyword("noexn"sv)) { - return ctx.makeNoexnType(); + return ctx.makeNoexnType(share); } if (ctx.in.takeKeyword("nocont"sv)) { - return ctx.makeNocontType(); + return ctx.makeNocontType(share); } - auto type = typeidx(ctx); - CHECK_ERR(type); - return *type; + return ctx.in.err("expected abstract heap type"); +} + +// heaptype ::= x:typeidx => types[x] +// | t:absheaptype => unshared t +// | '(' 'shared' t:absheaptype ')' => shared t +template Result heaptype(Ctx& ctx) { + if (auto t = maybeTypeidx(ctx)) { + CHECK_ERR(t); + return *t; + } + + auto share = ctx.in.takeSExprStart("shared"sv) ? Shared : Unshared; + auto t = absheaptype(ctx, share); + CHECK_ERR(t); + if (share == Shared && !ctx.in.takeRParen()) { + return ctx.in.err("expected end of shared abstract heap type"); + } + return *t; } // reftype ::= 'funcref' => funcref @@ -422,49 +439,49 @@ template Result heaptype(Ctx& ctx) { // | '(' ref null? t:heaptype ')' => ref null? t template MaybeResult maybeReftype(Ctx& ctx) { if (ctx.in.takeKeyword("funcref"sv)) { - return ctx.makeRefType(ctx.makeFuncType(), Nullable); + return ctx.makeRefType(ctx.makeFuncType(Unshared), Nullable); } if (ctx.in.takeKeyword("externref"sv)) { - return ctx.makeRefType(ctx.makeExternType(), Nullable); + return ctx.makeRefType(ctx.makeExternType(Unshared), Nullable); } if (ctx.in.takeKeyword("anyref"sv)) { - return ctx.makeRefType(ctx.makeAnyType(), Nullable); + return ctx.makeRefType(ctx.makeAnyType(Unshared), Nullable); } if (ctx.in.takeKeyword("eqref"sv)) { - return ctx.makeRefType(ctx.makeEqType(), Nullable); + return ctx.makeRefType(ctx.makeEqType(Unshared), Nullable); } if (ctx.in.takeKeyword("i31ref"sv)) { - return ctx.makeRefType(ctx.makeI31Type(), Nullable); + return ctx.makeRefType(ctx.makeI31Type(Unshared), Nullable); } if (ctx.in.takeKeyword("structref"sv)) { - return ctx.makeRefType(ctx.makeStructType(), Nullable); + return ctx.makeRefType(ctx.makeStructType(Unshared), Nullable); } if (ctx.in.takeKeyword("arrayref"sv)) { - return ctx.makeRefType(ctx.makeArrayType(), Nullable); + return ctx.makeRefType(ctx.makeArrayType(Unshared), Nullable); } if (ctx.in.takeKeyword("exnref"sv)) { - return ctx.makeRefType(ctx.makeExnType(), Nullable); + return ctx.makeRefType(ctx.makeExnType(Unshared), Nullable); } if (ctx.in.takeKeyword("stringref"sv)) { - return ctx.makeRefType(ctx.makeStringType(), Nullable); + return ctx.makeRefType(ctx.makeStringType(Unshared), Nullable); } if (ctx.in.takeKeyword("contref"sv)) { - return ctx.makeRefType(ctx.makeContType(), Nullable); + return ctx.makeRefType(ctx.makeContType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullref"sv)) { - return ctx.makeRefType(ctx.makeNoneType(), Nullable); + return ctx.makeRefType(ctx.makeNoneType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullexternref"sv)) { - return ctx.makeRefType(ctx.makeNoextType(), Nullable); + return ctx.makeRefType(ctx.makeNoextType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullfuncref"sv)) { - return ctx.makeRefType(ctx.makeNofuncType(), Nullable); + return ctx.makeRefType(ctx.makeNofuncType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullexnref"sv)) { - return ctx.makeRefType(ctx.makeNoexnType(), Nullable); + return ctx.makeRefType(ctx.makeNoexnType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullcontref"sv)) { - return ctx.makeRefType(ctx.makeNocontType(), Nullable); + return ctx.makeRefType(ctx.makeNocontType(Unshared), Nullable); } if (!ctx.in.takeSExprStart("ref"sv)) { diff --git a/src/passes/TypeGeneralizing.cpp b/src/passes/TypeGeneralizing.cpp index 81dd0a39ea3..720830400d4 100644 --- a/src/passes/TypeGeneralizing.cpp +++ b/src/passes/TypeGeneralizing.cpp @@ -58,7 +58,7 @@ using TypeRequirement = Inverted; // Record a type requirement for each local variable. Shared the requirements // across basic blocks. -using LocalTypeRequirements = Shared>; +using LocalTypeRequirements = SharedPath>; // The type requirements for each reference-typed value on the stack at a // particular location. @@ -75,7 +75,8 @@ struct State : StateLattice { static constexpr int LocalsIndex = 0; static constexpr int StackIndex = 1; - State(Function* func) : StateLattice{Shared{initLocals(func)}, initStack()} {} + State(Function* func) + : StateLattice{SharedPath{initLocals(func)}, initStack()} {} void push(Element& elem, Type type) const noexcept { stackLattice().push(stack(elem), std::move(type)); @@ -109,7 +110,7 @@ struct State : StateLattice { private: static LocalTypeRequirements initLocals(Function* func) noexcept { - return Shared{Vector{Inverted{ValType{}}, func->getNumLocals()}}; + return SharedPath{Vector{Inverted{ValType{}}, func->getNumLocals()}}; } static ValueStackTypeRequirements initStack() noexcept { diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 57c7ec6b069..6b54ac56dd9 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2556,7 +2556,8 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { auto heapType = type.getHeapType(); assert(heapType.isBasic()); assert(wasm.features.hasReferenceTypes()); - switch (heapType.getBasic()) { + assert(!heapType.isShared() && "TODO: handle shared types"); + switch (heapType.getBasic(Unshared)) { case HeapType::ext: { auto null = builder.makeRefNull(HeapType::ext); // TODO: support actual non-nullable externrefs via imported globals or @@ -4233,7 +4234,8 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) { return type; } if (type.isBasic() && oneIn(2)) { - switch (type.getBasic()) { + assert(!type.isShared() && "TODO: handle shared types"); + switch (type.getBasic(Unshared)) { case HeapType::func: // TODO: Typed function references. return pick(FeatureOptions() diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 08b4c445310..127d4f5ba7a 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -377,7 +377,8 @@ struct HeapTypeGeneratorImpl { if (rand.oneIn(8)) { return type.getBottom(); } - switch (type.getBasic()) { + assert(!type.isShared() && "TODO: handle shared types"); + switch (type.getBasic(Unshared)) { case HeapType::func: return pickSubFunc(); case HeapType::cont: @@ -438,7 +439,8 @@ struct HeapTypeGeneratorImpl { // This is not a constructed type, so it must be a basic type. assert(type.isBasic()); candidates.push_back(type); - switch (type.getBasic()) { + assert(!type.isShared() && "TODO: handle shared types"); + switch (type.getBasic(Unshared)) { case HeapType::ext: case HeapType::func: case HeapType::exn: diff --git a/src/tools/wasm-fuzz-lattices.cpp b/src/tools/wasm-fuzz-lattices.cpp index d74bc5148fd..551ddbaf1eb 100644 --- a/src/tools/wasm-fuzz-lattices.cpp +++ b/src/tools/wasm-fuzz-lattices.cpp @@ -185,7 +185,7 @@ using LatticeVariant = std::variant, TupleLattice, - Shared>; + SharedPath>; struct RandomLattice::LatticeImpl : LatticeVariant {}; @@ -196,7 +196,7 @@ using LatticeElementVariant = typename ArrayLattice::Element, typename Vector::Element, typename TupleLattice::Element, - typename Shared::Element>; + typename SharedPath::Element>; struct RandomLattice::ElementImpl : LatticeElementVariant {}; @@ -271,7 +271,7 @@ RandomLattice::RandomLattice(Random& rand, size_t depth) : rand(rand) { return; case FullLatticePicks + 5: lattice = std::make_unique( - LatticeImpl{Shared{RandomLattice{rand, depth + 1}}}); + LatticeImpl{SharedPath{RandomLattice{rand, depth + 1}}}); return; } WASM_UNREACHABLE("unexpected pick"); @@ -375,7 +375,7 @@ RandomLattice::Element RandomLattice::makeElement() const noexcept { typename TupleLattice::Element{std::get<0>(l->lattices).makeElement(), std::get<1>(l->lattices).makeElement()}}; } - if (const auto* l = std::get_if>(lattice.get())) { + if (const auto* l = std::get_if>(lattice.get())) { auto elem = l->getBottom(); l->join(elem, l->lattice.makeElement()); return ElementImpl{elem}; @@ -489,8 +489,9 @@ void printElement(std::ostream& os, indent(os, depth); os << ")\n"; } else if (const auto* e = - std::get_if::Element>(&*elem)) { - os << "Shared(\n"; + std::get_if::Element>( + &*elem)) { + os << "SharedPath(\n"; printElement(os, **e, depth + 1); indent(os, depth); os << ")\n"; diff --git a/src/wasm-type.h b/src/wasm-type.h index 2a74e4a6009..95c3605a593 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -310,6 +310,8 @@ class Type { const Type& operator[](size_t i) const { return *Iterator{{this, i}}; } }; +enum Shareability { Shared, Unshared }; + class HeapType { // Unlike `Type`, which represents the types of values on the WebAssembly // stack, `HeapType` is used to describe the structures that reference types @@ -318,24 +320,26 @@ class HeapType { uintptr_t id; public: + // Bit zero indicates whether the type is `shared`, so we need to leave it + // free. enum BasicHeapType : uint32_t { - ext, - func, - cont, - any, - eq, - i31, - struct_, - array, - exn, - string, - none, - noext, - nofunc, - nocont, - noexn, + ext = 0 << 1, + func = 1 << 1, + cont = 2 << 1, + any = 3 << 1, + eq = 4 << 1, + i31 = 5 << 1, + struct_ = 6 << 1, + array = 7 << 1, + exn = 8 << 1, + string = 9 << 1, + none = 10 << 1, + noext = 11 << 1, + nofunc = 12 << 1, + nocont = 13 << 1, + noexn = 14 << 1, }; - static constexpr BasicHeapType _last_basic_type = noexn; + static constexpr BasicHeapType _last_basic_type = BasicHeapType(noexn + 1); // BasicHeapType can be implicitly upgraded to HeapType constexpr HeapType(BasicHeapType id) : id(id) {} @@ -377,7 +381,9 @@ class HeapType { bool isString() const; bool isBottom() const; bool isOpen() const; - bool isShared() const; + bool isShared() const { return getShared() == Shared; } + + Shareability getShared() const; Signature getSignature() const; Continuation getContinuation() const; @@ -399,19 +405,27 @@ class HeapType { size_t getDepth() const; // Get the bottom heap type for this heap type's hierarchy. - BasicHeapType getBottom() const; + BasicHeapType getUnsharedBottom() const; + BasicHeapType getBottom() const { + return HeapType(getUnsharedBottom()).getBasic(getShared()); + } // Get the top heap type for this heap type's hierarchy. - BasicHeapType getTop() const; + BasicHeapType getUnsharedTop() const; + BasicHeapType getTop() const { + return HeapType(getUnsharedTop()).getBasic(getShared()); + } // Get the recursion group for this non-basic type. RecGroup getRecGroup() const; size_t getRecGroupIndex() const; constexpr TypeID getID() const { return id; } - constexpr BasicHeapType getBasic() const { - assert(isBasic() && "Basic heap type expected"); - return static_cast(id); + + // Get the shared or unshared version of this basic heap type. + constexpr BasicHeapType getBasic(Shareability share) const { + assert(isBasic()); + return BasicHeapType(share == Shared ? (id | 1) : (id & ~1)); } // (In)equality must be defined for both HeapType and BasicHeapType because it @@ -644,7 +658,7 @@ struct TypeBuilder { void createRecGroup(size_t i, size_t length); void setOpen(size_t i, bool open = true); - void setShared(size_t i, bool shared = true); + void setShared(size_t i, Shareability share = Shared); enum class ErrorReason { // There is a cycle in the supertype relation. @@ -717,8 +731,8 @@ struct TypeBuilder { builder.setOpen(index, open); return *this; } - Entry& setShared(bool shared = true) { - builder.setShared(index, shared); + Entry& setShared(Shareability share = Shared) { + builder.setShared(index, share); return *this; } }; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index d4e1bfc4581..f13ea504fb3 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -127,7 +127,7 @@ Literal::Literal(const Literal& other) : type(other.type) { assert(!type.isNullable()); auto heapType = type.getHeapType(); if (heapType.isBasic()) { - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::i31: i32 = other.i32; return; @@ -620,8 +620,11 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { } else { assert(literal.type.isRef()); auto heapType = literal.type.getHeapType(); + if (heapType.isShared()) { + o << "shared "; + } if (heapType.isBasic()) { - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::i31: o << "i31ref(" << literal.geti31() << ")"; break; @@ -2686,11 +2689,12 @@ Literal Literal::externalize() const { return Literal(std::shared_ptr{}, HeapType::noext); } auto heapType = type.getHeapType(); + auto extType = HeapTypes::ext.getBasic(heapType.getShared()); if (heapType.isBasic()) { - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::i31: { return Literal(std::make_shared(HeapType::i31, Literals{*this}), - HeapType::ext); + extType); } case HeapType::string: WASM_UNREACHABLE("TODO: string literals"); @@ -2698,7 +2702,7 @@ Literal Literal::externalize() const { WASM_UNREACHABLE("unexpected type"); } } - return Literal(gcData, HeapType::ext); + return Literal(gcData, extType); } Literal Literal::internalize() const { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b05dd52372b..524f4b98c8a 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1538,8 +1538,8 @@ void WasmBinaryWriter::writeType(Type type) { WASM_UNREACHABLE("bad type without GC"); } auto heapType = type.getHeapType(); - if (heapType.isBasic() && type.isNullable()) { - switch (heapType.getBasic()) { + if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) { + switch (heapType.getBasic(Unshared)) { case HeapType::ext: o << S32LEB(BinaryConsts::EncodedType::externref); return; @@ -1644,14 +1644,16 @@ void WasmBinaryWriter::writeHeapType(HeapType type) { } } - if (type.isSignature() || type.isContinuation() || type.isStruct() || - type.isArray()) { + if (!type.isBasic()) { o << S64LEB(getTypeIndex(type)); // TODO: Actually s33 return; } + int ret = 0; - assert(type.isBasic()); - switch (type.getBasic()) { + if (type.isShared()) { + o << S32LEB(BinaryConsts::EncodedType::Shared); + } + switch (type.getBasic(Unshared)) { case HeapType::ext: ret = BinaryConsts::EncodedHeapType::ext; break; @@ -2083,7 +2085,7 @@ bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) { out = HeapType::func; return true; case BinaryConsts::EncodedHeapType::cont: - out = HeapType::func; + out = HeapType::cont; return true; case BinaryConsts::EncodedHeapType::ext: out = HeapType::ext; @@ -2168,9 +2170,14 @@ HeapType WasmBinaryReader::getHeapType() { } return types[type]; } + auto share = Unshared; + if (type == BinaryConsts::EncodedType::Shared) { + share = Shared; + type = getS64LEB(); // TODO: Actually s33 + } HeapType ht; if (getBasicHeapType(type, ht)) { - return ht; + return ht.getBasic(share); } else { throwError("invalid wasm heap type: " + std::to_string(type)); } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 532ebb9136f..ae6fd4b305f 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -86,7 +86,7 @@ struct HeapTypeInfo { // global store. bool isTemp = false; bool isOpen = false; - bool isShared = false; + Shareability share = Unshared; // The supertype of this HeapType, if it exists. HeapTypeInfo* supertype = nullptr; // The recursion group of this type or null if the recursion group is trivial @@ -436,18 +436,18 @@ bool isTemp(HeapType type) { HeapType::BasicHeapType getBasicHeapSupertype(HeapType type) { if (type.isBasic()) { - return type.getBasic(); + return HeapType::BasicHeapType(type.getID()); } auto* info = getHeapTypeInfo(type); switch (info->kind) { case HeapTypeInfo::SignatureKind: - return HeapType::func; + return HeapTypes::func.getBasic(info->share); case HeapTypeInfo::ContinuationKind: - return HeapType::cont; + return HeapTypes::cont.getBasic(info->share); case HeapTypeInfo::StructKind: - return HeapType::struct_; + return HeapTypes::struct_.getBasic(info->share); case HeapTypeInfo::ArrayKind: - return HeapType::array; + return HeapTypes::array.getBasic(info->share); } WASM_UNREACHABLE("unexpected kind"); }; @@ -470,42 +470,53 @@ std::optional getBasicHeapTypeLUB(HeapType::BasicHeapType a, if (unsigned(a) > unsigned(b)) { std::swap(a, b); } - switch (a) { + auto bUnshared = HeapType(b).getBasic(Unshared); + HeapType lubUnshared; + switch (HeapType(a).getBasic(Unshared)) { case HeapType::ext: case HeapType::func: case HeapType::cont: case HeapType::exn: return std::nullopt; case HeapType::any: - return {HeapType::any}; + lubUnshared = HeapType::any; + break; case HeapType::eq: - if (b == HeapType::i31 || b == HeapType::struct_ || - b == HeapType::array) { - return {HeapType::eq}; + if (bUnshared == HeapType::i31 || bUnshared == HeapType::struct_ || + bUnshared == HeapType::array) { + lubUnshared = HeapType::eq; + } else { + lubUnshared = HeapType::any; } - return {HeapType::any}; + break; case HeapType::i31: - if (b == HeapType::struct_ || b == HeapType::array) { - return {HeapType::eq}; + if (bUnshared == HeapType::struct_ || bUnshared == HeapType::array) { + lubUnshared = HeapType::eq; + } else { + lubUnshared = HeapType::any; } - return {HeapType::any}; + break; case HeapType::struct_: - if (b == HeapType::array) { - return {HeapType::eq}; + if (bUnshared == HeapType::array) { + lubUnshared = HeapType::eq; + } else { + lubUnshared = HeapType::any; } - return {HeapType::any}; + break; case HeapType::array: case HeapType::string: - return {HeapType::any}; + lubUnshared = HeapType::any; + break; case HeapType::none: case HeapType::noext: case HeapType::nofunc: case HeapType::nocont: case HeapType::noexn: // Bottom types already handled. - break; + WASM_UNREACHABLE("unexpected basic type"); } - WASM_UNREACHABLE("unexpected basic type"); + auto share = HeapType(a).getShared(); + return {lubUnshared.getBasic(share)}; } TypeInfo::TypeInfo(const TypeInfo& other) { @@ -898,7 +909,7 @@ FeatureSet Type::getFeatures() const { void noteChild(HeapType* heapType) { if (heapType->isBasic()) { - switch (heapType->getBasic()) { + switch (heapType->getBasic(Unshared)) { case HeapType::ext: case HeapType::func: feats |= FeatureSet::ReferenceTypes; @@ -1228,7 +1239,7 @@ bool HeapType::isString() const { return *this == HeapType::string; } bool HeapType::isBottom() const { if (isBasic()) { - switch (getBasic()) { + switch (getBasic(Unshared)) { case ext: case func: case cont: @@ -1259,12 +1270,11 @@ bool HeapType::isOpen() const { } } -bool HeapType::isShared() const { +Shareability HeapType::getShared() const { if (isBasic()) { - // TODO: shared basic heap types - return false; + return (id & 1) != 0 ? Shared : Unshared; } else { - return getHeapTypeInfo(*this)->isShared; + return getHeapTypeInfo(*this)->share; } } @@ -1305,9 +1315,11 @@ std::optional HeapType::getSuperType() const { return ret; } + auto share = getShared(); + // There may be a basic supertype. if (isBasic()) { - switch (getBasic()) { + switch (getBasic(Unshared)) { case ext: case noext: case func: @@ -1321,24 +1333,24 @@ std::optional HeapType::getSuperType() const { case string: return {}; case eq: - return any; + return HeapType(any).getBasic(share); case i31: case struct_: case array: - return eq; + return HeapType(eq).getBasic(share); } } auto* info = getHeapTypeInfo(*this); switch (info->kind) { case HeapTypeInfo::SignatureKind: - return func; + return HeapType(func).getBasic(share); case HeapTypeInfo::ContinuationKind: - return cont; + return HeapType(cont).getBasic(share); case HeapTypeInfo::StructKind: - return struct_; + return HeapType(struct_).getBasic(share); case HeapTypeInfo::ArrayKind: - return array; + return HeapType(array).getBasic(share); } WASM_UNREACHABLE("unexpected kind"); } @@ -1365,7 +1377,7 @@ size_t HeapType::getDepth() const { } } else { // Some basic types have supers. - switch (getBasic()) { + switch (getBasic(Unshared)) { case HeapType::ext: case HeapType::func: case HeapType::cont: @@ -1393,9 +1405,9 @@ size_t HeapType::getDepth() const { return depth; } -HeapType::BasicHeapType HeapType::getBottom() const { +HeapType::BasicHeapType HeapType::getUnsharedBottom() const { if (isBasic()) { - switch (getBasic()) { + switch (getBasic(Unshared)) { case ext: return noext; case func: @@ -1435,8 +1447,8 @@ HeapType::BasicHeapType HeapType::getBottom() const { WASM_UNREACHABLE("unexpected kind"); } -HeapType::BasicHeapType HeapType::getTop() const { - switch (getBottom()) { +HeapType::BasicHeapType HeapType::getUnsharedTop() const { + switch (getUnsharedBottom()) { case none: return any; case nofunc: @@ -1730,30 +1742,34 @@ bool SubTyper::isSubType(HeapType a, HeapType b) { if (a == b) { return true; } + if (a.isShared() != b.isShared()) { + return false; + } if (b.isBasic()) { - switch (b.getBasic()) { + auto aTop = a.getUnsharedTop(); + auto aUnshared = a.isBasic() ? a.getBasic(Unshared) : a; + switch (b.getBasic(Unshared)) { case HeapType::ext: - return a.getTop() == HeapType::ext; + return aTop == HeapType::ext; case HeapType::func: - return a.getTop() == HeapType::func; + return aTop == HeapType::func; case HeapType::cont: - return a.getTop() == HeapType::cont; + return aTop == HeapType::cont; case HeapType::exn: - return a.getTop() == HeapType::exn; + return aTop == HeapType::exn; case HeapType::any: - return a.getTop() == HeapType::any; + return aTop == HeapType::any; case HeapType::eq: - return a == HeapType::i31 || a == HeapType::none || - a == HeapType::struct_ || a == HeapType::array || a.isStruct() || - a.isArray(); + return aUnshared == HeapType::i31 || aUnshared == HeapType::none || + aUnshared == HeapType::struct_ || aUnshared == HeapType::array || + a.isStruct() || a.isArray(); case HeapType::i31: - return a == HeapType::none; + case HeapType::string: + return aUnshared == HeapType::none; case HeapType::struct_: - return a == HeapType::none || a.isStruct(); + return aUnshared == HeapType::none || a.isStruct(); case HeapType::array: - return a == HeapType::none || a.isArray(); - case HeapType::string: - return a == HeapType::none; + return aUnshared == HeapType::none || a.isArray(); case HeapType::none: case HeapType::noext: case HeapType::nofunc: @@ -1865,9 +1881,9 @@ std::ostream& TypePrinter::print(Type type) { print(type.getTuple()); } else if (type.isRef()) { auto heapType = type.getHeapType(); - if (heapType.isBasic() && type.isNullable()) { + if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) { // Print shorthands for certain basic heap types. - switch (heapType.getBasic()) { + switch (heapType.getBasic(Unshared)) { case HeapType::ext: return os << "externref"; case HeapType::func: @@ -1914,38 +1930,60 @@ std::ostream& TypePrinter::print(Type type) { std::ostream& TypePrinter::print(HeapType type) { if (type.isBasic()) { - switch (type.getBasic()) { + if (type.isShared()) { + os << "(shared "; + } + switch (type.getBasic(Unshared)) { case HeapType::ext: - return os << "extern"; + os << "extern"; + break; case HeapType::func: - return os << "func"; + os << "func"; + break; case HeapType::cont: - return os << "cont"; + os << "cont"; + break; case HeapType::any: - return os << "any"; + os << "any"; + break; case HeapType::eq: - return os << "eq"; + os << "eq"; + break; case HeapType::i31: - return os << "i31"; + os << "i31"; + break; case HeapType::struct_: - return os << "struct"; + os << "struct"; + break; case HeapType::array: - return os << "array"; + os << "array"; + break; case HeapType::exn: - return os << "exn"; + os << "exn"; + break; case HeapType::string: - return os << "string"; + os << "string"; + break; case HeapType::none: - return os << "none"; + os << "none"; + break; case HeapType::noext: - return os << "noextern"; + os << "noextern"; + break; case HeapType::nofunc: - return os << "nofunc"; + os << "nofunc"; + break; case HeapType::nocont: - return os << "nocont"; + os << "nocont"; + break; case HeapType::noexn: - return os << "noexn"; + os << "noexn"; + break; + } + if (type.isShared()) { + os << ')'; } + return os; } auto names = generator(type); @@ -2144,7 +2182,7 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const { hash_combine(digest, hash(HeapType(uintptr_t(info.supertype)))); } wasm::rehash(digest, info.isOpen); - wasm::rehash(digest, info.isShared); + wasm::rehash(digest, info.share); wasm::rehash(digest, info.kind); switch (info.kind) { case HeapTypeInfo::SignatureKind: @@ -2281,7 +2319,7 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const { if (a.isOpen != b.isOpen) { return false; } - if (a.isShared != b.isShared) { + if (a.share != b.share) { return false; } if (a.kind != b.kind) { @@ -2559,9 +2597,9 @@ void TypeBuilder::setOpen(size_t i, bool open) { impl->entries[i].info->isOpen = open; } -void TypeBuilder::setShared(size_t i, bool shared) { +void TypeBuilder::setShared(size_t i, Shareability share) { assert(i < size() && "index out of bounds"); - impl->entries[i].info->isShared = shared; + impl->entries[i].info->share = share; } namespace { @@ -2570,7 +2608,7 @@ bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { if (!super.isOpen) { return false; } - if (sub.isShared != super.isShared) { + if (sub.share != super.share) { return false; } if (sub.kind != super.kind) { diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index d79b34e6662..5ba35fb0e7a 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -21,16 +21,16 @@ BinaryenPackedTypeNotPacked: 0 BinaryenPackedTypeInt8: 1 BinaryenPackedTypeInt16: 2 BinaryenHeapTypeExt: 0 -BinaryenHeapTypeFunc: 1 -BinaryenHeapTypeAny: 3 -BinaryenHeapTypeEq: 4 -BinaryenHeapTypeI31: 5 -BinaryenHeapTypeStruct: 6 -BinaryenHeapTypeArray: 7 -BinaryenHeapTypeString: 9 -BinaryenHeapTypeNone: 10 -BinaryenHeapTypeNoext: 11 -BinaryenHeapTypeNofunc: 12 +BinaryenHeapTypeFunc: 2 +BinaryenHeapTypeAny: 6 +BinaryenHeapTypeEq: 8 +BinaryenHeapTypeI31: 10 +BinaryenHeapTypeStruct: 12 +BinaryenHeapTypeArray: 14 +BinaryenHeapTypeString: 18 +BinaryenHeapTypeNone: 20 +BinaryenHeapTypeNoext: 22 +BinaryenHeapTypeNofunc: 24 BinaryenFeatureMVP: 0 BinaryenFeatureAtomics: 1 BinaryenFeatureBulkMemory: 16 diff --git a/test/gtest/lattices.cpp b/test/gtest/lattices.cpp index 905f03420e2..7fff8d0c075 100644 --- a/test/gtest/lattices.cpp +++ b/test/gtest/lattices.cpp @@ -574,12 +574,12 @@ TEST(ValTypeLattice, Meet) { } TEST(SharedLattice, GetBottom) { - analysis::Shared shared{analysis::UInt32{}}; + analysis::SharedPath shared{analysis::UInt32{}}; EXPECT_EQ(*shared.getBottom(), 0u); } TEST(SharedLattice, Compare) { - analysis::Shared shared{analysis::UInt32{}}; + analysis::SharedPath shared{analysis::UInt32{}}; auto zero = shared.getBottom(); @@ -615,7 +615,7 @@ TEST(SharedLattice, Compare) { } TEST(SharedLattice, Join) { - analysis::Shared shared{analysis::UInt32{}}; + analysis::SharedPath shared{analysis::UInt32{}}; auto zero = shared.getBottom(); @@ -682,7 +682,7 @@ TEST(SharedLattice, Join) { TEST(SharedLattice, JoinVecSingleton) { using Vec = analysis::Vector; - analysis::Shared shared{analysis::Vector{analysis::Bool{}, 2}}; + analysis::SharedPath shared{analysis::Vector{analysis::Bool{}, 2}}; auto elem = shared.getBottom(); EXPECT_TRUE(shared.join(elem, Vec::SingletonElement(1, true))); @@ -691,7 +691,7 @@ TEST(SharedLattice, JoinVecSingleton) { TEST(SharedLattice, JoinInvertedVecSingleton) { using Vec = analysis::Vector; - analysis::Shared> shared{ + analysis::SharedPath> shared{ analysis::Inverted{analysis::Vector{analysis::Bool{}, 2}}}; auto elem = shared.getBottom(); diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index b72b78c9ede..2ad43d18980 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -277,8 +277,8 @@ TEST_F(TypeTest, InvalidSharedSupertype) { TypeBuilder builder(2); builder[0] = Struct{}; builder[1] = Struct{}; - builder[0].setShared(true); - builder[1].setShared(false); + builder[0].setShared(); + builder[1].setShared(); builder[1].subTypeOf(builder[0]); auto result = builder.build(); @@ -294,8 +294,8 @@ TEST_F(TypeTest, InvalidUnsharedSupertype) { TypeBuilder builder(2); builder[0] = Struct{}; builder[1] = Struct{}; - builder[0].setShared(false); - builder[1].setShared(true); + builder[0].setShared(Unshared); + builder[1].setShared(Shared); builder[1].subTypeOf(builder[0]); auto result = builder.build(); @@ -570,6 +570,27 @@ TEST_F(TypeTest, TestHeapTypeRelations) { HeapType defCont = Continuation(defFunc); HeapType defStruct = Struct(); HeapType defArray = Array(Field(Type::i32, Immutable)); + HeapType sharedAny = any.getBasic(Shared); + HeapType sharedEq = eq.getBasic(Shared); + HeapType sharedI31 = i31.getBasic(Shared); + HeapType sharedStruct = struct_.getBasic(Shared); + HeapType sharedNone = none.getBasic(Shared); + HeapType sharedFunc = func.getBasic(Shared); + + HeapType sharedDefStruct; + HeapType sharedDefFunc; + { + TypeBuilder builder(2); + builder[0] = Struct{}; + builder[1] = Signature(); + builder[0].setShared(); + builder[1].setShared(); + auto results = builder.build(); + ASSERT_TRUE(results); + auto built = *results; + sharedDefStruct = built[0]; + sharedDefFunc = built[1]; + } auto assertLUB = [](HeapType a, HeapType b, std::optional lub) { auto lub1 = HeapType::getLeastUpperBound(a, b); @@ -620,6 +641,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(ext, defFunc, {}); assertLUB(ext, defStruct, {}); assertLUB(ext, defArray, {}); + assertLUB(ext, sharedAny, {}); + assertLUB(ext, sharedEq, {}); + assertLUB(ext, sharedI31, {}); + assertLUB(ext, sharedStruct, {}); + assertLUB(ext, sharedNone, {}); + assertLUB(ext, sharedFunc, {}); + assertLUB(ext, sharedDefStruct, {}); + assertLUB(ext, sharedDefFunc, {}); assertLUB(func, func, func); assertLUB(func, cont, {}); @@ -637,6 +666,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(func, defCont, {}); assertLUB(func, defStruct, {}); assertLUB(func, defArray, {}); + assertLUB(func, sharedAny, {}); + assertLUB(func, sharedEq, {}); + assertLUB(func, sharedI31, {}); + assertLUB(func, sharedStruct, {}); + assertLUB(func, sharedNone, {}); + assertLUB(func, sharedFunc, {}); + assertLUB(func, sharedDefStruct, {}); + assertLUB(func, sharedDefFunc, {}); assertLUB(cont, cont, cont); assertLUB(cont, func, {}); @@ -654,6 +691,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(cont, defCont, cont); assertLUB(cont, defStruct, {}); assertLUB(cont, defArray, {}); + assertLUB(cont, sharedAny, {}); + assertLUB(cont, sharedEq, {}); + assertLUB(cont, sharedI31, {}); + assertLUB(cont, sharedStruct, {}); + assertLUB(cont, sharedNone, {}); + assertLUB(cont, sharedFunc, {}); + assertLUB(cont, sharedDefStruct, {}); + assertLUB(cont, sharedDefFunc, {}); assertLUB(any, any, any); assertLUB(any, cont, {}); @@ -670,6 +715,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(any, defCont, {}); assertLUB(any, defStruct, any); assertLUB(any, defArray, any); + assertLUB(any, sharedAny, {}); + assertLUB(any, sharedEq, {}); + assertLUB(any, sharedI31, {}); + assertLUB(any, sharedStruct, {}); + assertLUB(any, sharedNone, {}); + assertLUB(any, sharedFunc, {}); + assertLUB(any, sharedDefStruct, {}); + assertLUB(any, sharedDefFunc, {}); assertLUB(eq, eq, eq); assertLUB(eq, cont, {}); @@ -685,6 +738,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(eq, defCont, {}); assertLUB(eq, defStruct, eq); assertLUB(eq, defArray, eq); + assertLUB(eq, sharedAny, {}); + assertLUB(eq, sharedEq, {}); + assertLUB(eq, sharedI31, {}); + assertLUB(eq, sharedStruct, {}); + assertLUB(eq, sharedNone, {}); + assertLUB(eq, sharedFunc, {}); + assertLUB(eq, sharedDefStruct, {}); + assertLUB(eq, sharedDefFunc, {}); assertLUB(i31, i31, i31); assertLUB(i31, cont, {}); @@ -699,6 +760,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(i31, defCont, {}); assertLUB(i31, defStruct, eq); assertLUB(i31, defArray, eq); + assertLUB(i31, sharedAny, {}); + assertLUB(i31, sharedEq, {}); + assertLUB(i31, sharedI31, {}); + assertLUB(i31, sharedStruct, {}); + assertLUB(i31, sharedNone, {}); + assertLUB(i31, sharedFunc, {}); + assertLUB(i31, sharedDefStruct, {}); + assertLUB(i31, sharedDefFunc, {}); assertLUB(struct_, struct_, struct_); assertLUB(struct_, cont, {}); @@ -712,6 +781,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(struct_, defCont, {}); assertLUB(struct_, defStruct, struct_); assertLUB(struct_, defArray, eq); + assertLUB(struct_, sharedAny, {}); + assertLUB(struct_, sharedEq, {}); + assertLUB(struct_, sharedI31, {}); + assertLUB(struct_, sharedStruct, {}); + assertLUB(struct_, sharedNone, {}); + assertLUB(struct_, sharedFunc, {}); + assertLUB(struct_, sharedDefStruct, {}); + assertLUB(struct_, sharedDefFunc, {}); assertLUB(array, array, array); assertLUB(array, cont, {}); @@ -724,6 +801,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(array, defCont, {}); assertLUB(array, defStruct, eq); assertLUB(array, defArray, array); + assertLUB(array, sharedAny, {}); + assertLUB(array, sharedEq, {}); + assertLUB(array, sharedI31, {}); + assertLUB(array, sharedStruct, {}); + assertLUB(array, sharedNone, {}); + assertLUB(array, sharedFunc, {}); + assertLUB(array, sharedDefStruct, {}); + assertLUB(array, sharedDefFunc, {}); assertLUB(string, string, string); assertLUB(string, cont, {}); @@ -735,6 +820,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(string, defCont, {}); assertLUB(string, defStruct, any); assertLUB(string, defArray, any); + assertLUB(string, sharedAny, {}); + assertLUB(string, sharedEq, {}); + assertLUB(string, sharedI31, {}); + assertLUB(string, sharedStruct, {}); + assertLUB(string, sharedNone, {}); + assertLUB(string, sharedFunc, {}); + assertLUB(string, sharedDefStruct, {}); + assertLUB(string, sharedDefFunc, {}); assertLUB(none, none, none); assertLUB(none, noext, {}); @@ -744,6 +837,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(none, defCont, {}); assertLUB(none, defStruct, defStruct); assertLUB(none, defArray, defArray); + assertLUB(none, sharedAny, {}); + assertLUB(none, sharedEq, {}); + assertLUB(none, sharedI31, {}); + assertLUB(none, sharedStruct, {}); + assertLUB(none, sharedNone, {}); + assertLUB(none, sharedFunc, {}); + assertLUB(none, sharedDefStruct, {}); + assertLUB(none, sharedDefFunc, {}); assertLUB(noext, noext, noext); assertLUB(noext, nofunc, {}); @@ -752,6 +853,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(noext, defCont, {}); assertLUB(noext, defStruct, {}); assertLUB(noext, defArray, {}); + assertLUB(noext, sharedAny, {}); + assertLUB(noext, sharedEq, {}); + assertLUB(noext, sharedI31, {}); + assertLUB(noext, sharedStruct, {}); + assertLUB(noext, sharedNone, {}); + assertLUB(noext, sharedFunc, {}); + assertLUB(noext, sharedDefStruct, {}); + assertLUB(noext, sharedDefFunc, {}); assertLUB(nofunc, nofunc, nofunc); assertLUB(nofunc, nocont, {}); @@ -759,6 +868,14 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(nofunc, defCont, {}); assertLUB(nofunc, defStruct, {}); assertLUB(nofunc, defArray, {}); + assertLUB(nofunc, sharedAny, {}); + assertLUB(nofunc, sharedEq, {}); + assertLUB(nofunc, sharedI31, {}); + assertLUB(nofunc, sharedStruct, {}); + assertLUB(nofunc, sharedNone, {}); + assertLUB(nofunc, sharedFunc, {}); + assertLUB(nofunc, sharedDefStruct, {}); + assertLUB(nofunc, sharedDefFunc, {}); assertLUB(nocont, nocont, nocont); assertLUB(nocont, func, {}); @@ -768,21 +885,105 @@ TEST_F(TypeTest, TestHeapTypeRelations) { assertLUB(nocont, defCont, defCont); assertLUB(nocont, defStruct, {}); assertLUB(nocont, defArray, {}); + assertLUB(nocont, sharedAny, {}); + assertLUB(nocont, sharedEq, {}); + assertLUB(nocont, sharedI31, {}); + assertLUB(nocont, sharedStruct, {}); + assertLUB(nocont, sharedNone, {}); + assertLUB(nocont, sharedFunc, {}); + assertLUB(nocont, sharedDefStruct, {}); + assertLUB(nocont, sharedDefFunc, {}); assertLUB(defFunc, defFunc, defFunc); assertLUB(defFunc, defCont, {}); assertLUB(defFunc, defStruct, {}); assertLUB(defFunc, defArray, {}); + assertLUB(defFunc, sharedAny, {}); + assertLUB(defFunc, sharedEq, {}); + assertLUB(defFunc, sharedI31, {}); + assertLUB(defFunc, sharedStruct, {}); + assertLUB(defFunc, sharedNone, {}); + assertLUB(defFunc, sharedFunc, {}); + assertLUB(defFunc, sharedDefStruct, {}); + assertLUB(defFunc, sharedDefFunc, {}); assertLUB(defCont, defCont, defCont); assertLUB(defCont, defFunc, {}); assertLUB(defCont, defStruct, {}); assertLUB(defCont, defArray, {}); + assertLUB(defCont, sharedAny, {}); + assertLUB(defCont, sharedEq, {}); + assertLUB(defCont, sharedI31, {}); + assertLUB(defCont, sharedStruct, {}); + assertLUB(defCont, sharedNone, {}); + assertLUB(defCont, sharedFunc, {}); + assertLUB(defCont, sharedDefStruct, {}); + assertLUB(defCont, sharedDefFunc, {}); assertLUB(defStruct, defStruct, defStruct); assertLUB(defStruct, defArray, eq); + assertLUB(defStruct, sharedAny, {}); + assertLUB(defStruct, sharedEq, {}); + assertLUB(defStruct, sharedI31, {}); + assertLUB(defStruct, sharedStruct, {}); + assertLUB(defStruct, sharedNone, {}); + assertLUB(defStruct, sharedFunc, {}); + assertLUB(defStruct, sharedDefStruct, {}); + assertLUB(defStruct, sharedDefFunc, {}); assertLUB(defArray, defArray, defArray); + assertLUB(defArray, sharedAny, {}); + assertLUB(defArray, sharedEq, {}); + assertLUB(defArray, sharedI31, {}); + assertLUB(defArray, sharedStruct, {}); + assertLUB(defArray, sharedNone, {}); + assertLUB(defArray, sharedFunc, {}); + assertLUB(defArray, sharedDefStruct, {}); + assertLUB(defArray, sharedDefFunc, {}); + + assertLUB(sharedAny, sharedAny, sharedAny); + assertLUB(sharedAny, sharedEq, sharedAny); + assertLUB(sharedAny, sharedI31, sharedAny); + assertLUB(sharedAny, sharedStruct, sharedAny); + assertLUB(sharedAny, sharedNone, sharedAny); + assertLUB(sharedAny, sharedFunc, {}); + assertLUB(sharedAny, sharedDefStruct, sharedAny); + assertLUB(sharedAny, sharedDefFunc, {}); + + assertLUB(sharedEq, sharedEq, sharedEq); + assertLUB(sharedEq, sharedI31, sharedEq); + assertLUB(sharedEq, sharedStruct, sharedEq); + assertLUB(sharedEq, sharedNone, sharedEq); + assertLUB(sharedEq, sharedFunc, {}); + assertLUB(sharedEq, sharedDefStruct, sharedEq); + assertLUB(sharedEq, sharedDefFunc, {}); + + assertLUB(sharedI31, sharedI31, sharedI31); + assertLUB(sharedI31, sharedStruct, sharedEq); + assertLUB(sharedI31, sharedNone, sharedI31); + assertLUB(sharedI31, sharedFunc, {}); + assertLUB(sharedI31, sharedDefStruct, sharedEq); + assertLUB(sharedI31, sharedDefFunc, {}); + + assertLUB(sharedStruct, sharedStruct, sharedStruct); + assertLUB(sharedStruct, sharedNone, sharedStruct); + assertLUB(sharedStruct, sharedFunc, {}); + assertLUB(sharedStruct, sharedDefStruct, sharedStruct); + assertLUB(sharedStruct, sharedDefFunc, {}); + + assertLUB(sharedNone, sharedNone, sharedNone); + assertLUB(sharedNone, sharedFunc, {}); + assertLUB(sharedNone, sharedDefStruct, sharedDefStruct); + assertLUB(sharedNone, sharedDefFunc, {}); + + assertLUB(sharedFunc, sharedFunc, sharedFunc); + assertLUB(sharedFunc, sharedDefStruct, {}); + assertLUB(sharedFunc, sharedDefFunc, sharedFunc); + + assertLUB(sharedDefStruct, sharedDefStruct, sharedDefStruct); + assertLUB(sharedDefStruct, sharedDefFunc, {}); + + assertLUB(sharedDefFunc, sharedDefFunc, sharedDefFunc); Type anyref = Type(any, Nullable); Type eqref = Type(eq, Nullable); diff --git a/test/lit/basic/shared-types.wast b/test/lit/basic/shared-types.wast index d3720c2e90c..0bba2f05487 100644 --- a/test/lit/basic/shared-types.wast +++ b/test/lit/basic/shared-types.wast @@ -5,6 +5,8 @@ (module (rec + ;; CHECK: (type $0 (func)) + ;; CHECK: (rec ;; CHECK-NEXT: (type $final (shared (struct ))) (type $final (shared (struct))) @@ -23,9 +25,7 @@ (type $cont (shared (cont $func))) ) - ;; CHECK: (type $7 (func)) - - ;; CHECK: (func $use-types (type $7) + ;; CHECK: (func $use-types (type $0) ;; CHECK-NEXT: (local $0 (ref $final)) ;; CHECK-NEXT: (local $1 (ref $top)) ;; CHECK-NEXT: (local $2 (ref $mid)) @@ -44,4 +44,40 @@ (local (ref $array)) (local (ref $cont)) ) + + ;; CHECK: (func $use-basic-types (type $0) + ;; CHECK-NEXT: (local $0 (ref (shared extern))) + ;; CHECK-NEXT: (local $1 (ref (shared func))) + ;; CHECK-NEXT: (local $2 (ref (shared cont))) + ;; CHECK-NEXT: (local $3 (ref (shared any))) + ;; CHECK-NEXT: (local $4 (ref (shared eq))) + ;; CHECK-NEXT: (local $5 (ref (shared i31))) + ;; CHECK-NEXT: (local $6 (ref (shared struct))) + ;; CHECK-NEXT: (local $7 (ref (shared array))) + ;; CHECK-NEXT: (local $8 (ref (shared exn))) + ;; CHECK-NEXT: (local $9 (ref (shared string))) + ;; CHECK-NEXT: (local $10 (ref (shared none))) + ;; CHECK-NEXT: (local $11 (ref (shared noextern))) + ;; CHECK-NEXT: (local $12 (ref (shared nofunc))) + ;; CHECK-NEXT: (local $13 (ref (shared nocont))) + ;; CHECK-NEXT: (local $14 (ref (shared noexn))) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $use-basic-types + (local (ref (shared extern))) + (local (ref (shared func))) + (local (ref (shared cont))) + (local (ref (shared any))) + (local (ref (shared eq))) + (local (ref (shared i31))) + (local (ref (shared struct))) + (local (ref (shared array))) + (local (ref (shared exn))) + (local (ref (shared string))) + (local (ref (shared none))) + (local (ref (shared noextern))) + (local (ref (shared nofunc))) + (local (ref (shared nocont))) + (local (ref (shared noexn))) + ) ) diff --git a/test/lit/basic/typed_continuations.wast b/test/lit/basic/typed_continuations.wast index 52258403f5e..1e024ca0b3e 100644 --- a/test/lit/basic/typed_continuations.wast +++ b/test/lit/basic/typed_continuations.wast @@ -26,7 +26,7 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $2 (func (param (ref $ct)) (result (ref $ct)))) - ;; CHECK-BIN: (type $3 (func (param contref nullcontref (ref func) (ref nocont)) (result contref))) + ;; CHECK-BIN: (type $3 (func (param contref nullcontref (ref cont) (ref nocont)) (result contref))) ;; CHECK-BIN: (func $id (type $2) (param $x (ref $ct)) (result (ref $ct)) ;; CHECK-BIN-NEXT: (local.get $x) @@ -38,7 +38,7 @@ ;; CHECK-TEXT: (func $id2 (type $3) (param $w contref) (param $x nullcontref) (param $y (ref cont)) (param $z (ref nocont)) (result contref) ;; CHECK-TEXT-NEXT: (local.get $z) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $id2 (type $3) (param $w contref) (param $x nullcontref) (param $y (ref func)) (param $z (ref nocont)) (result contref) + ;; CHECK-BIN: (func $id2 (type $3) (param $w contref) (param $x nullcontref) (param $y (ref cont)) (param $z (ref nocont)) (result contref) ;; CHECK-BIN-NEXT: (local.get $z) ;; CHECK-BIN-NEXT: ) (func $id2 @@ -57,12 +57,12 @@ ;; CHECK-BIN-NODEBUG: (type $2 (func (param (ref $1)) (result (ref $1)))) -;; CHECK-BIN-NODEBUG: (type $3 (func (param contref nullcontref (ref func) (ref nocont)) (result contref))) +;; CHECK-BIN-NODEBUG: (type $3 (func (param contref nullcontref (ref cont) (ref nocont)) (result contref))) ;; CHECK-BIN-NODEBUG: (func $0 (type $2) (param $0 (ref $1)) (result (ref $1)) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $1 (type $3) (param $0 contref) (param $1 nullcontref) (param $2 (ref func)) (param $3 (ref nocont)) (result contref) +;; CHECK-BIN-NODEBUG: (func $1 (type $3) (param $0 contref) (param $1 nullcontref) (param $2 (ref cont)) (param $3 (ref nocont)) (result contref) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $3) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast index 2d3bcdc2137..2457cd57259 100644 --- a/test/lit/passes/type-merging-shared.wast +++ b/test/lit/passes/type-merging-shared.wast @@ -75,3 +75,25 @@ (local $c' (ref null $C')) ) ) + +(module + ;; Shared and unshared basic heap types similarly cannot be merged. + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A' (shared (struct (field anyref)))) + + ;; CHECK: (type $A (shared (struct (field (ref null (shared any)))))) + (type $A (shared (struct (ref null (shared any))))) + (type $A' (shared (struct (ref null any)))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (func $foo (type $2) + ;; CHECK-NEXT: (local $a (ref null $A)) + ;; CHECK-NEXT: (local $a' (ref null $A')) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo + (local $a (ref null $A)) + (local $a' (ref null $A')) + ) +) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 87778bd246d..71484977a17 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -234,22 +234,22 @@ (type $cont-bind-before-func (func (param i32) (param i64) (param i32) (param i64) (result f32))) (type $cont-bind-before (cont $cont-bind-before-func)) - ;; CHECK: (type $all-types (struct (field externref) (field (ref extern)) (field funcref) (field (ref func)) (field anyref) (field (ref any)) (field eqref) (field (ref eq)) (field i31ref) (field (ref i31)) (field structref) (field (ref struct)) (field arrayref) (field (ref array)) (field exnref) (field (ref exn)) (field stringref) (field (ref string)) (field contref) (field (ref cont)) (field nullref) (field (ref none)) (field nullexternref) (field (ref noextern)) (field nullfuncref) (field (ref nofunc)) (field nullexnref) (field (ref noexn)) (field nullcontref) (field (ref nocont)))) - (type $all-types (struct externref (ref extern) - funcref (ref func) - anyref (ref any) - eqref (ref eq) - i31ref (ref i31) - structref (ref struct) - arrayref (ref array) - exnref (ref exn) - stringref (ref string) - contref (ref cont) - nullref (ref none) - nullexternref (ref noextern) - nullfuncref (ref nofunc) - nullexnref (ref noexn) - nullcontref (ref nocont))) + ;; CHECK: (type $all-types (struct (field externref) (field (ref extern)) (field (ref null (shared extern))) (field (ref (shared extern))) (field funcref) (field (ref func)) (field (ref null (shared func))) (field (ref (shared func))) (field anyref) (field (ref any)) (field (ref null (shared any))) (field (ref (shared any))) (field eqref) (field (ref eq)) (field (ref null (shared eq))) (field (ref (shared eq))) (field i31ref) (field (ref i31)) (field (ref null (shared i31))) (field (ref (shared i31))) (field structref) (field (ref struct)) (field (ref null (shared struct))) (field (ref (shared struct))) (field arrayref) (field (ref array)) (field (ref null (shared array))) (field (ref (shared array))) (field exnref) (field (ref exn)) (field (ref null (shared exn))) (field (ref (shared exn))) (field stringref) (field (ref string)) (field (ref null (shared string))) (field (ref (shared string))) (field contref) (field (ref cont)) (field (ref null (shared cont))) (field (ref (shared cont))) (field nullref) (field (ref none)) (field (ref null (shared none))) (field (ref (shared none))) (field nullexternref) (field (ref noextern)) (field (ref null (shared noextern))) (field (ref (shared noextern))) (field nullfuncref) (field (ref nofunc)) (field (ref null (shared nofunc))) (field (ref (shared nofunc))) (field nullexnref) (field (ref noexn)) (field (ref null (shared noexn))) (field (ref (shared noexn))) (field nullcontref) (field (ref nocont)) (field (ref null (shared nocont))) (field (ref (shared nocont))))) + (type $all-types (struct externref (ref extern) (ref null (shared extern)) (ref (shared extern)) + funcref (ref func) (ref null (shared func)) (ref (shared func)) + anyref (ref any) (ref null (shared any)) (ref (shared any)) + eqref (ref eq) (ref null (shared eq)) (ref (shared eq)) + i31ref (ref i31) (ref null (shared i31)) (ref (shared i31)) + structref (ref struct) (ref null (shared struct)) (ref (shared struct)) + arrayref (ref array) (ref null (shared array)) (ref (shared array)) + exnref (ref exn) (ref null (shared exn)) (ref (shared exn)) + stringref (ref string) (ref null (shared string)) (ref (shared string)) + contref (ref cont) (ref null (shared cont)) (ref (shared cont)) + nullref (ref none) (ref null (shared none)) (ref (shared none)) + nullexternref (ref noextern) (ref null (shared noextern)) (ref (shared noextern)) + nullfuncref (ref nofunc) (ref null (shared nofunc)) (ref (shared nofunc)) + nullexnref (ref noexn) (ref null (shared noexn)) (ref (shared noexn)) + nullcontref (ref nocont) (ref null (shared nocont)) (ref (shared nocont)))) ;; imported memories (memory (export "mem") (export "mem2") (import "" "mem") 0) From 02c4c3cd43a2033a7fd2f5c75f6d92ac9b80bb4b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 18:34:53 -0700 Subject: [PATCH 398/553] Re-enable binary.wast spec test (#6677) Fix the wast parser to accept IDs on quoted modules, remove tests that are invalidated by the multimemory proposal, and add validation that the total number of variables in a function is less than 2^32 and that the code section is present if there is a non-empty function section. --- scripts/test/shared.py | 3 - src/parser/wast-parser.cpp | 2 + src/wasm-binary.h | 2 +- src/wasm/wasm-binary.cpp | 33 +++++-- test/spec/binary.wast | 191 ------------------------------------- 5 files changed, 26 insertions(+), 205 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 0e7062437d8..665ad6b7cfc 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -417,9 +417,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'type.wast', 'unreached-invalid.wast', - # WAST parser error - 'binary.wast', - # Test invalid 'elem.wast', ] diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 9473da9fb60..137ef0df13a 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -77,6 +77,8 @@ Result wastModule(Lexer& in, bool maybeInvalid = false) { if (!in.takeSExprStart("module"sv)) { return in.err("expected module"); } + // TODO: use ID? + [[maybe_unused]] auto id = in.takeID(); QuotedModuleType type; if (in.takeKeyword("quote"sv)) { type = QuotedModuleType::Text; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index f7d57f5c9f2..3870ccf7faa 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1583,7 +1583,7 @@ class WasmBinaryReader { void readVars(); std::map exportIndices; - std::vector exportOrder; + std::vector> exportOrder; void readExports(); // The strings in the strings section (which are referred to by StringConst). diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 524f4b98c8a..01b3602eb38 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -23,6 +23,7 @@ #include "ir/type-updating.h" #include "support/bits.h" #include "support/debug.h" +#include "support/stdckdint.h" #include "support/string.h" #include "wasm-binary.h" #include "wasm-debug.h" @@ -2688,10 +2689,10 @@ void WasmBinaryReader::readFunctions() { } endOfFunction = pos + size; - auto* func = new Function; + auto func = std::make_unique(); func->name = Name::fromInt(i); func->type = getTypeByFunctionIndex(numImports + i); - currFunction = func; + currFunction = func.get(); if (DWARF) { func->funcLocation = BinaryLocations::FunctionLocations{ @@ -2755,21 +2756,29 @@ void WasmBinaryReader::readFunctions() { } } - TypeUpdating::handleNonDefaultableLocals(func, wasm); + TypeUpdating::handleNonDefaultableLocals(func.get(), wasm); std::swap(func->epilogLocation, debugLocation); currFunction = nullptr; debugLocation.clear(); - wasm.addFunction(func); + wasm.addFunction(std::move(func)); } BYN_TRACE(" end function bodies\n"); } void WasmBinaryReader::readVars() { + uint32_t totalVars = 0; size_t numLocalTypes = getU32LEB(); for (size_t t = 0; t < numLocalTypes; t++) { auto num = getU32LEB(); + // The core spec allows up to 2^32 locals, but to avoid allocation failures, + // we additionally impose a much smaller limit, matching the JS embedding. + if (std::ckd_add(&totalVars, totalVars, num) || + totalVars > WebLimitations::MaxFunctionLocals) { + throwError("too many locals"); + } auto type = getConcreteType(); + while (num > 0) { currFunction->vars.push_back(type); num--; @@ -2784,15 +2793,15 @@ void WasmBinaryReader::readExports() { std::unordered_set names; for (size_t i = 0; i < num; i++) { BYN_TRACE("read one\n"); - auto curr = new Export; + auto curr = std::make_unique(); curr->name = getInlineString(); if (!names.emplace(curr->name).second) { throwError("duplicate export name"); } curr->kind = (ExternalKind)getU32LEB(); auto index = getU32LEB(); - exportIndices[curr] = index; - exportOrder.push_back(curr); + exportIndices[curr.get()] = index; + exportOrder.push_back(std::move(curr)); } } @@ -3235,6 +3244,10 @@ void WasmBinaryReader::validateBinary() { if (hasDataCount && wasm.dataSegments.size() != dataCount) { throwError("Number of segments does not agree with DataCount section"); } + + if (functionTypes.size() != wasm.functions.size()) { + throwError("function section without code section"); + } } void WasmBinaryReader::processNames() { @@ -3244,8 +3257,8 @@ void WasmBinaryReader::processNames() { wasm.start = getFunctionName(startIndex); } - for (auto* curr : exportOrder) { - auto index = exportIndices[curr]; + for (auto& curr : exportOrder) { + auto index = exportIndices[curr.get()]; switch (curr->kind) { case ExternalKind::Function: { curr->value = getFunctionName(index); @@ -3266,7 +3279,7 @@ void WasmBinaryReader::processNames() { default: throwError("bad export kind"); } - wasm.addExport(curr); + wasm.addExport(std::move(curr)); } for (auto& [index, refs] : functionRefs) { diff --git a/test/spec/binary.wast b/test/spec/binary.wast index e748bbe8cd9..e7bca9b116d 100644 --- a/test/spec/binary.wast +++ b/test/spec/binary.wast @@ -138,197 +138,6 @@ "zero flag expected" ) -;; memory.grow reserved byte equal to zero. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\09\01" ;; Code section - - ;; function 0 - "\07\00" - "\41\00" ;; i32.const 0 - "\40" ;; memory.grow - "\01" ;; memory.grow reserved byte is not equal to zero! - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -;; memory.grow reserved byte should not be a "long" LEB128 zero. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0a\01" ;; Code section - - ;; function 0 - "\08\00" - "\41\00" ;; i32.const 0 - "\40" ;; memory.grow - "\80\00" ;; memory.grow reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -;; Same as above for 3, 4, and 5-byte zero encodings. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0b\01" ;; Code section - - ;; function 0 - "\09\00" - "\41\00" ;; i32.const 0 - "\40" ;; memory.grow - "\80\80\00" ;; memory.grow reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0c\01" ;; Code section - - ;; function 0 - "\0a\00" - "\41\00" ;; i32.const 0 - "\40" ;; memory.grow - "\80\80\80\00" ;; memory.grow reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0d\01" ;; Code section - - ;; function 0 - "\0b\00" - "\41\00" ;; i32.const 0 - "\40" ;; memory.grow - "\80\80\80\80\00" ;; memory.grow reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -;; memory.size reserved byte equal to zero. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\07\01" ;; Code section - - ;; function 0 - "\05\00" - "\3f" ;; memory.size - "\01" ;; memory.size reserved byte is not equal to zero! - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -;; memory.size reserved byte should not be a "long" LEB128 zero. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\08\01" ;; Code section - - ;; function 0 - "\06\00" - "\3f" ;; memory.size - "\80\00" ;; memory.size reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -;; Same as above for 3, 4, and 5-byte zero encodings. -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\09\01" ;; Code section - - ;; function 0 - "\07\00" - "\3f" ;; memory.size - "\80\80\00" ;; memory.size reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0a\01" ;; Code section - - ;; function 0 - "\08\00" - "\3f" ;; memory.size - "\80\80\80\00" ;; memory.size reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\00" ;; Memory section - "\0a\0b\01" ;; Code section - - ;; function 0 - "\09\00" - "\3f" ;; memory.size - "\80\80\80\80\00" ;; memory.size reserved byte - "\1a" ;; drop - "\0b" ;; end - ) - "zero flag expected" -) - ;; No more than 2^32 locals. (assert_malformed (module binary From eceb0fb6ac097e262bf74dcdb686cfc5d4c55188 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 18:35:30 -0700 Subject: [PATCH 399/553] Check malformed mutability on imported globals (#6679) And re-enable the globals.wast spec test, which checks this. --- scripts/test/shared.py | 1 - src/wasm/wasm-binary.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 665ad6b7cfc..76d6fd56840 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -400,7 +400,6 @@ def get_tests(test_dir, extensions=[], recursive=False): # expected-output/ if any. SPEC_TESTS_TO_SKIP = [ # Malformed module accepted - 'globals.wast', 'binary-leb128.wast', 'utf8-custom-section-id.wast', 'utf8-import-field.wast', diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 01b3602eb38..cd1ca7dfdb8 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2591,6 +2591,9 @@ void WasmBinaryReader::readImports() { Name name(std::string("gimport$") + std::to_string(globalCounter++)); auto type = getConcreteType(); auto mutable_ = getU32LEB(); + if (mutable_ & ~1) { + throwError("Global mutability must be 0 or 1"); + } auto curr = builder.makeGlobal(name, type, From 3acacac34c9ebe949fbc7d9eb3649266760104fe Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 19:12:36 -0700 Subject: [PATCH 400/553] Fix validation of unused LEB128 bits (#6680) The unused bits must be a sign extension of the significant value, but we were previously only validating that unsigned LEBs had their unused bytes set to zero. Re-enable the spec test that checks for proper validation. --- scripts/test/shared.py | 1 - src/wasm-binary.h | 27 ++++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 76d6fd56840..4034f95ef4b 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -400,7 +400,6 @@ def get_tests(test_dir, extensions=[], recursive=False): # expected-output/ if any. SPEC_TESTS_TO_SKIP = [ # Malformed module accepted - 'binary-leb128.wast', 'utf8-custom-section-id.wast', 'utf8-import-field.wast', 'utf8-import-module.wast', diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 3870ccf7faa..46d81064e0f 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -102,16 +102,22 @@ template struct LEB { bool last = !(byte & 128); T payload = byte & 127; using mask_type = typename std::make_unsigned::type; - auto shift_mask = 0 == shift - ? ~mask_type(0) - : ((mask_type(1) << (sizeof(T) * 8 - shift)) - 1u); - T significant_payload = payload & shift_mask; - if (significant_payload != payload) { - if (!(std::is_signed::value && last)) { - throw ParseException("LEB dropped bits only valid for signed LEB"); + auto payload_mask = 0 == shift + ? ~mask_type(0) + : ((mask_type(1) << (sizeof(T) * 8 - shift)) - 1u); + T significant_payload = payload_mask & payload; + value |= significant_payload << shift; + T unused_bits_mask = ~payload_mask & 127; + T unused_bits = payload & unused_bits_mask; + if (std::is_signed_v && value < 0) { + if (unused_bits != unused_bits_mask) { + throw ParseException("Unused negative LEB bits must be 1s"); + } + } else { + if (unused_bits != 0) { + throw ParseException("Unused non-negative LEB bits must be 0s"); } } - value |= significant_payload << shift; if (last) { break; } @@ -120,9 +126,8 @@ template struct LEB { throw ParseException("LEB overflow"); } } - // If signed LEB, then we might need to sign-extend. (compile should - // optimize this out if not needed). - if (std::is_signed::value) { + // If signed LEB, then we might need to sign-extend. + if constexpr (std::is_signed_v) { shift += 7; if ((byte & 64) && size_t(shift) < 8 * sizeof(T)) { size_t sext_bits = 8 * sizeof(T) - size_t(shift); From 765c61445550c6e4ecfd250e1893d776d570b4fd Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Jun 2024 20:08:25 -0700 Subject: [PATCH 401/553] Validate that names are valid UTF-8 (#6682) Add an `isUTF8` utility and use it in both the text and binary parsers. Add missing checks for overlong encodings and overlarge code points in our WTF8 reader, which the new utility uses. Re-enable the spec tests that test UTF-8 validation. --- scripts/test/shared.py | 4 ---- src/parser/lexer.h | 9 +++++---- src/support/string.cpp | 22 ++++++++++++++++++++++ src/support/string.h | 3 +++ src/wasm-binary.h | 2 +- src/wasm/wasm-binary.cpp | 8 +++++--- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 4034f95ef4b..909b20c4b71 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -400,10 +400,6 @@ def get_tests(test_dir, extensions=[], recursive=False): # expected-output/ if any. SPEC_TESTS_TO_SKIP = [ # Malformed module accepted - 'utf8-custom-section-id.wast', - 'utf8-import-field.wast', - 'utf8-import-module.wast', - 'utf8-invalid-encoding.wast', 'const.wast', 'address.wast', diff --git a/src/parser/lexer.h b/src/parser/lexer.h index 83cbcfc5363..37c3fe04a87 100644 --- a/src/parser/lexer.h +++ b/src/parser/lexer.h @@ -25,6 +25,7 @@ #include "support/name.h" #include "support/result.h" +#include "support/string.h" #ifndef parser_lexer_h #define parser_lexer_h @@ -124,11 +125,11 @@ struct Lexer { std::optional takeString(); std::optional takeName() { - // TODO: Validate UTF. - if (auto str = takeString()) { - return Name(*str); + auto str = takeString(); + if (!str || !String::isUTF8(*str)) { + return std::nullopt; } - return std::nullopt; + return Name(*str); } bool takeSExprStart(std::string_view expected) { diff --git a/src/support/string.cpp b/src/support/string.cpp index 31d0e91705c..01fe4e522f6 100644 --- a/src/support/string.cpp +++ b/src/support/string.cpp @@ -195,9 +195,21 @@ std::optional takeWTF8CodePoint(std::string_view& str) { } str = str.substr(1 + trailingBytes); + if (!valid) { return std::nullopt; } + + size_t expectedTrailing = u < 0x80 ? 0 + : u < 0x800 ? 1 + : u < 0x10000 ? 2 + : u < 0x110000 ? 3 + : -1; + if (trailingBytes != expectedTrailing) { + // Overlong encoding or overlarge code point. + return std::nullopt; + } + return u; } @@ -404,4 +416,14 @@ std::ostream& printEscapedJSON(std::ostream& os, std::string_view str) { return os << '"'; } +bool isUTF8(std::string_view str) { + while (str.size()) { + auto u = takeWTF8CodePoint(str); + if (!u || (0xD800 <= *u && *u < 0xE000)) { + return false; + } + } + return true; +} + } // namespace wasm::String diff --git a/src/support/string.h b/src/support/string.h index af120ab4e2c..24eb570c2c3 100644 --- a/src/support/string.h +++ b/src/support/string.h @@ -99,6 +99,9 @@ bool convertWTF16ToWTF8(std::ostream& os, std::string_view str); // unit. Returns `true` if the input was valid UTF-16. bool convertUTF16ToUTF8(std::ostream& os, std::string_view str); +// Whether the string is valid UTF-8. +bool isUTF8(std::string_view str); + } // namespace wasm::String #endif // wasm_support_string_h diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 46d81064e0f..9ce9bf1816b 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1505,7 +1505,7 @@ class WasmBinaryReader { HeapType getIndexedHeapType(); Type getConcreteType(); - Name getInlineString(); + Name getInlineString(bool requireValid = true); void verifyInt8(int8_t x); void verifyInt16(int16_t x); void verifyInt32(int32_t x); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index cd1ca7dfdb8..dc97dbbc31b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2201,11 +2201,13 @@ Type WasmBinaryReader::getConcreteType() { return type; } -Name WasmBinaryReader::getInlineString() { +Name WasmBinaryReader::getInlineString(bool requireValid) { BYN_TRACE("<==\n"); auto len = getU32LEB(); auto data = getByteView(len); - + if (requireValid && !String::isUTF8(data)) { + throwError("invalid UTF-8 string"); + } BYN_TRACE("getInlineString: " << data << " ==>\n"); return Name(data); } @@ -3027,7 +3029,7 @@ void WasmBinaryReader::readStrings() { } size_t num = getU32LEB(); for (size_t i = 0; i < num; i++) { - auto string = getInlineString(); + auto string = getInlineString(false); // Re-encode from WTF-8 to WTF-16. std::stringstream wtf16; if (!String::convertWTF8ToWTF16(wtf16, string.str)) { From 98da69f2ee63214a4f946d55b863ee6d41d3e250 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 20 Jun 2024 09:57:23 -0700 Subject: [PATCH 402/553] [NFC] Add pragma to ignore maybe-uninitialized in strings.cpp (#6686) This will hopefully fix the build on the coverage builder. --- src/support/string.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/support/string.cpp b/src/support/string.cpp index 01fe4e522f6..7dc9ba89c55 100644 --- a/src/support/string.cpp +++ b/src/support/string.cpp @@ -318,6 +318,9 @@ std::ostream& writeWTF16CodePoint(std::ostream& os, uint32_t u) { return os; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + bool convertWTF8ToWTF16(std::ostream& os, std::string_view str) { bool valid = true; bool lastWasLeadingSurrogate = false; @@ -343,6 +346,8 @@ bool convertWTF8ToWTF16(std::ostream& os, std::string_view str) { return valid; } +#pragma GCC diagnostic pop + bool convertWTF16ToWTF8(std::ostream& os, std::string_view str) { return doConvertWTF16ToWTF8(os, str, true); } From 45f6bdd4b2f694513aaed8b785bda422f0067a0d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 20 Jun 2024 09:58:18 -0700 Subject: [PATCH 403/553] Validate memarg offsets (#6683) For 32-bit memories, the offset value must be in the u32 range. Update the address.wast spec test to assert that a module with an overlarge offset value is invalid rather than malformed. --- scripts/test/shared.py | 3 +-- src/wasm/wasm-validator.cpp | 13 +++++++++++++ test/spec/address.wast | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 909b20c4b71..b629eafc1bd 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -399,9 +399,8 @@ def get_tests(test_dir, extensions=[], recursive=False): # delete the old file, make sure you rename the corresponding .wast.log file in # expected-output/ if any. SPEC_TESTS_TO_SKIP = [ - # Malformed module accepted + # Requires us to write our own floating point parser 'const.wast', - 'address.wast', # Unlinkable module accepted 'linking.wast', diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index f8bd08e1dec..13993c82518 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -526,6 +526,7 @@ struct FunctionValidator : public WalkerPass> { return info.shouldBeSubType(left, right, curr, text, getFunction()); } + void validateOffset(Address offset, Memory* mem, Expression* curr); void validateAlignment( size_t align, Type type, Index bytes, bool isAtomic, Expression* curr); void validateMemBytes(uint8_t bytes, Type type, Expression* curr); @@ -1046,6 +1047,7 @@ void FunctionValidator::visitLoad(Load* curr) { "SIMD operations require SIMD [--enable-simd]"); } validateMemBytes(curr->bytes, curr->type, curr); + validateOffset(curr->offset, memory, curr); validateAlignment(curr->align, curr->type, curr->bytes, curr->isAtomic, curr); shouldBeEqualOrFirstIsUnreachable( curr->ptr->type, @@ -1077,6 +1079,7 @@ void FunctionValidator::visitStore(Store* curr) { "SIMD operations require SIMD [--enable-simd]"); } validateMemBytes(curr->bytes, curr->valueType, curr); + validateOffset(curr->offset, memory, curr); validateAlignment( curr->align, curr->valueType, curr->bytes, curr->isAtomic, curr); shouldBeEqualOrFirstIsUnreachable( @@ -1370,6 +1373,7 @@ void FunctionValidator::visitSIMDLoad(SIMDLoad* curr) { break; } Index bytes = curr->getMemBytes(); + validateOffset(curr->offset, memory, curr); validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr); } @@ -1423,6 +1427,7 @@ void FunctionValidator::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) { WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op"); } Index bytes = curr->getMemBytes(); + validateOffset(curr->offset, memory, curr); validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr); shouldBeTrue(curr->index < lanes, curr, "invalid lane index"); } @@ -3457,6 +3462,14 @@ void FunctionValidator::visitFunction(Function* curr) { } } +void FunctionValidator::validateOffset(Address offset, + Memory* mem, + Expression* curr) { + shouldBeTrue(mem->is64() || offset <= std::numeric_limits::max(), + curr, + "offset must be u32"); +} + void FunctionValidator::validateAlignment( size_t align, Type type, Index bytes, bool isAtomic, Expression* curr) { if (isAtomic) { diff --git a/test/spec/address.wast b/test/spec/address.wast index e071cca5038..212b7a85aa6 100644 --- a/test/spec/address.wast +++ b/test/spec/address.wast @@ -203,7 +203,7 @@ (assert_trap (invoke "16s_bad" (i32.const 1)) "out of bounds memory access") (assert_trap (invoke "32_bad" (i32.const 1)) "out of bounds memory access") -(assert_malformed +(assert_invalid (module quote "(memory 1)" "(func (drop (i32.load offset=4294967296 (i32.const 0))))" From 1079a9e34599e65ee25fb5f32caa57bd21737593 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 20 Jun 2024 10:13:31 -0700 Subject: [PATCH 404/553] Re-enable spec tests requiring multivalue (#6684) And delete tests that no longer pass now that multivalue is standard. --- scripts/test/shared.py | 2 -- test/spec/func.wast | 13 ------------ test/spec/type.wast | 45 +++++++++++++++++------------------------- 3 files changed, 18 insertions(+), 42 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index b629eafc1bd..d593aa45b5a 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -406,8 +406,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'linking.wast', # Invalid module accepted - 'func.wast', - 'type.wast', 'unreached-invalid.wast', # Test invalid diff --git a/test/spec/func.wast b/test/spec/func.wast index a6b05f53c09..af685fb9d10 100644 --- a/test/spec/func.wast +++ b/test/spec/func.wast @@ -489,19 +489,6 @@ ;; Invalid typing of result -(assert_invalid - (module (func $type-multiple-result (result i32 i32) (unreachable))) - "invalid result arity" -) -(assert_invalid - (module - (type (func (result i32 i32))) - (func $type-multiple-result (type 0) (unreachable)) - ) - "invalid result arity" -) - - (assert_invalid (module (func $type-empty-i32 (result i32))) "type mismatch" diff --git a/test/spec/type.wast b/test/spec/type.wast index 5ceeeb26977..b94063e6a04 100644 --- a/test/spec/type.wast +++ b/test/spec/type.wast @@ -11,33 +11,33 @@ (type (func (param $x i32) (result i32))) (type (func (param f32 f64))) - ;; (type (func (result i64 f32))) - ;; (type (func (param i32 i64) (result f32 f64))) + (type (func (result i64 f32))) + (type (func (param i32 i64) (result f32 f64))) (type (func (param f32) (param f64))) (type (func (param $x f32) (param f64))) (type (func (param f32) (param $y f64))) (type (func (param $x f32) (param $y f64))) - ;; (type (func (result i64) (result f32))) - ;; (type (func (param i32) (param i64) (result f32) (result f64))) - ;; (type (func (param $x i32) (param $y i64) (result f32) (result f64))) + (type (func (result i64) (result f32))) + (type (func (param i32) (param i64) (result f32) (result f64))) + (type (func (param $x i32) (param $y i64) (result f32) (result f64))) (type (func (param f32 f64) (param $x i32) (param f64 i32 i32))) - ;; (type (func (result i64 i64 f32) (result f32 i32))) - ;; (type - ;; (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32)) - ;; ) + (type (func (result i64 i64 f32) (result f32 i32))) + (type + (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32)) + ) (type (func (param) (param $x f32) (param) (param) (param f64 i32) (param))) - ;; (type - ;; (func (result) (result) (result i64 i64) (result) (result f32) (result)) - ;; ) - ;; (type - ;; (func - ;; (param i32 i32) (param i64 i32) (param) (param $x i32) (param) - ;; (result) (result f32 f64) (result f64 i32) (result) - ;; ) - ;; ) + (type + (func (result) (result) (result i64 i64) (result) (result f32) (result)) + ) + (type + (func + (param i32 i32) (param i64 i32) (param) (param $x i32) (param) + (result) (result f32 f64) (result f64 i32) (result) + ) + ) ) (assert_malformed @@ -48,12 +48,3 @@ (module quote "(type (func (result $x i32)))") "unexpected token" ) - -(assert_invalid - (module (type (func (result i32 i32)))) - "invalid result arity" -) -(assert_invalid - (module (type (func (result i32) (result i32)))) - "invalid result arity" -) From c3089b3b553536ece3b1d6a9cffe82cda1b813e5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 20 Jun 2024 15:24:14 -0700 Subject: [PATCH 405/553] GlobalStructInference: Un-nest struct.news in globals when that is helpful (#6688) If we have (global $g (struct.new $S (i32.const 1) (struct.new $T ..) (ref.func $f) )) then before this PR if we wanted to read the middle field we'd stop, as it is non-constant. However, we can un-nest it, making it constant: (global $g.unnested (struct.new $T ..)) (global $g (struct.new $S (i32.const 1) (global.get $g.unnested) (ref.func $f) )) Now the field is a global.get of an immutable global, which is constant. Using this technique we can handle anything in a struct field, constant or not. The cost of adding a global is likely offset by the benefit of being able to refer to it directly, as that opens up more opportunities later. Concretely, this replaces the constant values we look for in GSI with a variant over constants or expressions (we do still want to group constants, as multiple globals with the same constant field can be treated as a whole). And we note cases where we need to un-nest, and handle those at the end. --- src/passes/GlobalStructInference.cpp | 282 ++++++++++++++---- test/lit/passes/gsi.wast | 417 ++++++++++++++++++++++++++- 2 files changed, 632 insertions(+), 67 deletions(-) diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index c0b92e3bb3b..0ddbe9b0f51 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -48,8 +48,11 @@ // TODO: Only do the case with a select when shrinkLevel == 0? // +#include + #include "ir/find_all.h" #include "ir/module-utils.h" +#include "ir/names.h" #include "ir/possible-constant.h" #include "ir/subtypes.h" #include "ir/utils.h" @@ -211,16 +214,98 @@ struct GlobalStructInference : public Pass { std::sort(globals.begin(), globals.end()); } - // Optimize based on the above. - struct FunctionOptimizer - : public WalkerPass> { - bool isFunctionParallel() override { return true; } + // We are looking for the case where we can pick between two values using a + // single comparison. More than two values, or more than a single + // comparison, lead to tradeoffs that may not be worth it. + // + // Note that situation may involve more than two globals. For example we may + // have three relevant globals, but two may have the same value. In that + // case we can compare against the third: + // + // $global0: (struct.new $Type (i32.const 42)) + // $global1: (struct.new $Type (i32.const 42)) + // $global2: (struct.new $Type (i32.const 1337)) + // + // (struct.get $Type (ref)) + // => + // (select + // (i32.const 1337) + // (i32.const 42) + // (ref.eq (ref) $global2)) + // + // To discover these situations, we compute and group the possible values + // that can be read from a particular struct.get, using the following data + // structure. + struct Value { + // A value is either a constant, or if not, then we point to whatever + // expression it is. + std::variant content; + // The list of globals that have this Value. In the example from above, + // the Value for 42 would list globals = [$global0, $global1]. + // TODO: SmallVector? + std::vector globals; + + bool isConstant() const { + return std::get_if(&content); + } - std::unique_ptr create() override { - return std::make_unique(parent); + const PossibleConstantValues& getConstant() const { + assert(isConstant()); + return std::get(content); } - FunctionOptimizer(GlobalStructInference& parent) : parent(parent) {} + Expression* getExpression() const { + assert(!isConstant()); + return std::get(content); + } + }; + + // Constant expressions are easy to handle, and we can emit a select as in + // the last example. But we can handle non-constant ones too, by un-nesting + // the relevant global. Imagine we have this: + // + // (global $g (struct.new $S + // (struct.new $T ..) + // + // We have a nested struct.new here. That is not a constant value, but we + // can turn it into a global.get: + // + // (global $g.nested (struct.new $T ..) + // (global $g (struct.new $S + // (global.get $g.nested) + // + // After this un-nesting we end up with a global.get of an immutable global, + // which is constant. Note that this adds a global and may increase code + // size slightly, but if it lets us infer constant values that may lead to + // devirtualization and other large benefits. Later passes can also re-nest. + // + // We do most of our optimization work in parallel, but we cannot add + // globals in parallel, so instead we note the places we need to un-nest in + // this data structure and process them at the end. + struct GlobalToUnnest { + // The global we want to refer to a nested part of, by un-nesting it. The + // global contains a struct.new, and we want to refer to one of the + // operands of the struct.new directly, which we can do by moving it out + // to its own new global. + Name global; + // The index of the struct.new in the global named |global|. + Index index; + // The global.get that should refer to the new global. At the end, after + // we create a new global and have a name for it, we update this get to + // point to it. + GlobalGet* get; + }; + using GlobalsToUnnest = std::vector; + + struct FunctionOptimizer : PostWalker { + private: + GlobalStructInference& parent; + GlobalsToUnnest& globalsToUnnest; + + public: + FunctionOptimizer(GlobalStructInference& parent, + GlobalsToUnnest& globalsToUnnest) + : parent(parent), globalsToUnnest(globalsToUnnest) {} bool refinalize = false; @@ -278,65 +363,85 @@ struct GlobalStructInference : public Pass { return; } - // We are looking for the case where we can pick between two values - // using a single comparison. More than two values, or more than a - // single comparison, add tradeoffs that may not be worth it, and a - // single value (or no value) is already handled by other passes. - // - // That situation may involve more than two globals. For example we may - // have three relevant globals, but two may have the same value. In that - // case we can compare against the third: - // - // $global0: (struct.new $Type (i32.const 42)) - // $global1: (struct.new $Type (i32.const 42)) - // $global2: (struct.new $Type (i32.const 1337)) - // - // (struct.get $Type (ref)) - // => - // (select - // (i32.const 1337) - // (i32.const 42) - // (ref.eq (ref) $global2)) - - // Find the constant values and which globals correspond to them. - // TODO: SmallVectors? - std::vector values; - std::vector> globalsForValue; - - // Check if the relevant fields contain constants. + // TODO: SmallVector? + std::vector values; + + // Scan the relevant struct.new operands. auto fieldType = field.type; for (Index i = 0; i < globals.size(); i++) { Name global = globals[i]; auto* structNew = wasm.getGlobal(global)->init->cast(); - PossibleConstantValues value; + // The value that is read from this struct.new. + Value value; + + // Find the value read from the struct and represent it as a Value. + PossibleConstantValues constant; if (structNew->isWithDefault()) { - value.note(Literal::makeZero(fieldType)); + constant.note(Literal::makeZero(fieldType)); + value.content = constant; } else { - value.note(structNew->operands[fieldIndex], wasm); - if (!value.isConstant()) { - // Give up entirely. - return; + Expression* operand = structNew->operands[fieldIndex]; + constant.note(operand, wasm); + if (constant.isConstant()) { + value.content = constant; + } else { + value.content = operand; } } - // Process the current value, comparing it against the previous. - auto found = std::find(values.begin(), values.end(), value); - if (found == values.end()) { - // This is a new value. - assert(values.size() <= 2); + // If the value is constant, it may be grouped as mentioned before. + // See if it matches anything we've seen before. + bool grouped = false; + if (value.isConstant()) { + for (auto& oldValue : values) { + if (oldValue.isConstant() && + oldValue.getConstant() == value.getConstant()) { + // Add us to this group. + oldValue.globals.push_back(global); + grouped = true; + break; + } + } + } + if (!grouped) { + // This is a new value, so create a new group, unless we've seen too + // many unique values. In that case, give up. if (values.size() == 2) { - // Adding this value would mean we have too many, so give up. return; } + value.globals.push_back(global); values.push_back(value); - globalsForValue.push_back({global}); - } else { - // This is an existing value. - Index index = found - values.begin(); - globalsForValue[index].push_back(global); } } + // Helper for optimization: Given a Value, returns what we should read + // for it. + auto getReadValue = [&](const Value& value) -> Expression* { + if (value.isConstant()) { + // This is known to be a constant, so simply emit an expression for + // that constant. + return value.getConstant().makeExpression(wasm); + } + + // Otherwise, this is non-constant, so we are in the situation where + // we want to un-nest the value out of the struct.new it is in. Note + // that for later work, as we cannot add a global in parallel. + + // There can only be one global in a value that is not constant, which + // is the global we want to read from. + assert(value.globals.size() == 1); + + // Create a global.get with temporary name, leaving only the updating + // of the name to later work. + auto* get = builder.makeGlobalGet(value.globals[0], + value.getExpression()->type); + + globalsToUnnest.emplace_back( + GlobalToUnnest{value.globals[0], fieldIndex, get}); + + return get; + }; + // We have some globals (at least 2), and so must have at least one // value. And we have already exited if we have more than 2 values (see // the early return above) so that only leaves 1 and 2. @@ -345,7 +450,7 @@ struct GlobalStructInference : public Pass { // otherwise return the value. replaceCurrent(builder.makeSequence( builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)), - values[0].makeExpression(wasm))); + getReadValue(values[0]))); return; } assert(values.size() == 2); @@ -353,11 +458,11 @@ struct GlobalStructInference : public Pass { // We have two values. Check that we can pick between them using a // single comparison. While doing so, ensure that the index we can check // on is 0, that is, the first value has a single global. - if (globalsForValue[0].size() == 1) { + if (values[0].globals.size() == 1) { // The checked global is already in index 0. - } else if (globalsForValue[1].size() == 1) { + } else if (values[1].globals.size() == 1) { + // Flip so the value to check is in index 0. std::swap(values[0], values[1]); - std::swap(globalsForValue[0], globalsForValue[1]); } else { // Both indexes have more than one option, so we'd need more than one // comparison. Give up. @@ -365,15 +470,19 @@ struct GlobalStructInference : public Pass { } // Excellent, we can optimize here! Emit a select. - // + + auto checkGlobal = values[0].globals[0]; + // Compute the left and right values before the next line, as the order + // of their execution matters (they may note globals for un-nesting). + auto* left = getReadValue(values[0]); + auto* right = getReadValue(values[1]); // Note that we must trap on null, so add a ref.as_non_null here. - auto checkGlobal = globalsForValue[0][0]; replaceCurrent(builder.makeSelect( builder.makeRefEq(builder.makeRefAs(RefAsNonNull, curr->ref), builder.makeGlobalGet( checkGlobal, wasm.getGlobal(checkGlobal)->type)), - values[0].makeExpression(wasm), - values[1].makeExpression(wasm))); + left, + right)); } void visitFunction(Function* func) { @@ -381,12 +490,61 @@ struct GlobalStructInference : public Pass { ReFinalize().walkFunctionInModule(func, getModule()); } } - - private: - GlobalStructInference& parent; }; - FunctionOptimizer(*this).run(getPassRunner(), module); + // Find the optimization opportunitites in parallel. + ModuleUtils::ParallelFunctionAnalysis optimization( + *module, [&](Function* func, GlobalsToUnnest& globalsToUnnest) { + if (func->imported()) { + return; + } + + FunctionOptimizer optimizer(*this, globalsToUnnest); + optimizer.walkFunctionInModule(func, module); + }); + + // Un-nest any globals as needed, using the deterministic order of the + // functions in the module. + Builder builder(*module); + auto addedGlobals = false; + for (auto& func : module->functions) { + // Each work item here is a global with a struct.new, from which we want + // to read a particular index, from a particular global.get. + for (auto& [globalName, index, get] : optimization.map[func.get()]) { + auto* global = module->getGlobal(globalName); + auto* structNew = global->init->cast(); + assert(index < structNew->operands.size()); + auto*& operand = structNew->operands[index]; + + // If we already un-nested this then we don't need to repeat that work. + if (auto* nestedGet = operand->dynCast()) { + // We already un-nested, and this global.get refers to the new global. + // Simply copy the target. + get->name = nestedGet->name; + assert(get->type == nestedGet->type); + } else { + // Add a new global, initialized to the operand. + auto newName = Names::getValidGlobalName( + *module, + global->name.toString() + ".unnested." + std::to_string(index)); + module->addGlobal(builder.makeGlobal( + newName, get->type, operand, Builder::Immutable)); + // Replace the operand with a get of that new global, and update the + // original get to read the same. + operand = builder.makeGlobalGet(newName, get->type); + get->name = newName; + addedGlobals = true; + } + } + } + + if (addedGlobals) { + // Sort the globals so that added ones appear before their uses. + PassRunner runner(module); + runner.add("reorder-globals-always"); + runner.setIsNested(true); + runner.run(); + } } }; diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast index 15afea5ed48..57d8137f493 100644 --- a/test/lit/passes/gsi.wast +++ b/test/lit/passes/gsi.wast @@ -841,18 +841,22 @@ ) ) -;; One global has a non-constant field, so we cannot optimize. +;; One global has a non-constant field. We can still optimize, if we move that +;; field out into another global, that is, if we un-nest it. The select will +;; then pick either the constant or a global.get of the new un-nested global. (module ;; CHECK: (type $struct (struct (field i32))) (type $struct (struct i32)) ;; CHECK: (type $1 (func (param (ref null $struct)))) + ;; CHECK: (global $global1.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 41) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct - ;; CHECK-NEXT: (i32.add - ;; CHECK-NEXT: (i32.const 41) - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1.unnested.0) ;; CHECK-NEXT: )) (global $global1 (ref $struct) (struct.new $struct (i32.add @@ -868,6 +872,409 @@ (i32.const 1337) )) + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) +) + +;; As above, but with the globals flipped. Now the second global has a non- +;; constant field. +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global2.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 41) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.const 1337) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.add + (i32.const 41) + (i32.const 1) + ) + )) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) +) + +;; As above, but now both globals have non-constant fields. We un-nest both. +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global1.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (i32.const 37) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global2.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 41) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.add + (i32.const 13) + (i32.const 37) + ) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.add + (i32.const 41) + (i32.const 1) + ) + )) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) +) + +;; Multiple and overlapping un-nesting situations. +(module + ;; CHECK: (type $struct (struct (field i32) (field i32))) + (type $struct (struct i32 i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global1.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (i32.const 37) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global2.unnested.0 i32 (i32.add + ;; CHECK-NEXT: (i32.const 41) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global1.unnested.1 i32 (i32.add + ;; CHECK-NEXT: (i32.const 99) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (global.get $global1.unnested.1) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.add + (i32.const 13) + (i32.const 37) + ) + (i32.add + (i32.const 99) + (i32.const 1) + ) + )) + + ;; CHECK: (global $global2.unnested.1 i32 (i32.add + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (global.get $global2.unnested.1) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.add + (i32.const 41) + (i32.const 1) + ) + (i32.add + (i32.const 100) + (i32.const 2) + ) + )) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + ;; We only need to un-nest once for these two. + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) + + ;; CHECK: (func $test2 (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.0) + ;; CHECK-NEXT: (global.get $global2.unnested.0) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.1) + ;; CHECK-NEXT: (global.get $global2.unnested.1) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (global.get $global1.unnested.1) + ;; CHECK-NEXT: (global.get $global2.unnested.1) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.get $global1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test2 (param $struct (ref null $struct)) + ;; Add another get of 0 in another function. + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ;; Add gets of the second field in the struct. + (drop + (struct.get $struct 1 + (local.get $struct) + ) + ) + (drop + (struct.get $struct 1 + (local.get $struct) + ) + ) + ) +) + +;; Three globals with non-constant fields. We do not optimize as we cannot pick +;; between three values with a single comparison. +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.add + (i32.const 42) + (i32.const 0) + ) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.add + (i32.const 1337) + (i32.const 0) + ) + )) + + ;; CHECK: (global $global3 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 99999) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global3 (ref $struct) (struct.new $struct + (i32.add + (i32.const 99999) + (i32.const 0) + ) + )) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + (drop + (struct.get $struct 0 + (local.get $struct) + ) + ) + ) +) + +;; As above, but now two of the three's non-constant fields are identical. That +;; does not help us: they are still non-constant, and we do nothing. (But, other +;; passes might simplify things by un-nesting the identical code.) +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.add + (i32.const 42) + (i32.const 0) + ) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.add + (i32.const 42) + (i32.const 0) + ) + )) + + ;; CHECK: (global $global3 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 99999) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: )) + (global $global3 (ref $struct) (struct.new $struct + (i32.add + (i32.const 99999) + (i32.const 0) + ) + )) + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $struct 0 From 02625158ebd0a15eaa6524fdbbc3af23497bb34f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 21 Jun 2024 08:30:55 -0700 Subject: [PATCH 406/553] wasm2js: Fix the names of temp vars with named reference types (#6689) We were missing code to mangle such names for JS. Without that, the name of a temp var for the type `(ref $foo)` would end up with `(`, `)` in the name, which is not valid in JS. --- src/wasm2js.h | 1 + test/wasm2js/refs.2asm.js | 10 +++++++++- test/wasm2js/refs.2asm.js.opt | 8 +++++++- test/wasm2js/refs.wast | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 321734688e7..7fa923ceb07 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -217,6 +217,7 @@ class Wasm2JSBuilder { std::to_string(index)) .c_str(), false); + ret = fromName(ret, NameScope::Local); } if (func->localIndices.find(ret) == func->localIndices.end()) { Builder::addVar(func, ret, type); diff --git a/test/wasm2js/refs.2asm.js b/test/wasm2js/refs.2asm.js index f4c08408f70..45e510e3759 100644 --- a/test/wasm2js/refs.2asm.js +++ b/test/wasm2js/refs.2asm.js @@ -61,6 +61,12 @@ function asmFunc(imports) { funcref_temps(funcref_temps, +(+((wasm2js_funcref$0 = $2, wasm2js_funcref$1 = $3 || wasm2js_trap(), wasm2js_i32$0 = 0, wasm2js_i32$0 ? wasm2js_funcref$0 : wasm2js_funcref$1) == null | 0))); } + function named_type_temps() { + var $0 = null, wasm2js__ref_null_$func_0_$0_1 = null, wasm2js__ref_null_$func_0_$1_1 = null, wasm2js_i32$0 = 0; + $0 = named_type_temps; + return wasm2js__ref_null_$func_0_$0 = null, wasm2js__ref_null_$func_0_$1 = $0 || wasm2js_trap(), wasm2js_i32$0 = 0, wasm2js_i32$0 ? wasm2js__ref_null_$func_0_$0 : wasm2js__ref_null_$func_0_$1; + } + return { "null_": null_, "is_null": is_null, @@ -69,7 +75,8 @@ function asmFunc(imports) { "ref_as": ref_as, "use_global": use_global, "use_global_ref": use_global_ref, - "funcref_temps": funcref_temps + "funcref_temps": funcref_temps, + "named_type_temps": named_type_temps }; } @@ -83,3 +90,4 @@ export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; export var use_global_ref = retasmFunc.use_global_ref; export var funcref_temps = retasmFunc.funcref_temps; +export var named_type_temps = retasmFunc.named_type_temps; diff --git a/test/wasm2js/refs.2asm.js.opt b/test/wasm2js/refs.2asm.js.opt index 0071a15b53e..ee8c25a7ccf 100644 --- a/test/wasm2js/refs.2asm.js.opt +++ b/test/wasm2js/refs.2asm.js.opt @@ -53,6 +53,10 @@ function asmFunc(imports) { funcref_temps(funcref_temps, 0.0); } + function named_type_temps() { + return named_type_temps; + } + return { "null_": null_, "is_null": is_null, @@ -61,7 +65,8 @@ function asmFunc(imports) { "ref_as": ref_as, "use_global": use_global, "use_global_ref": use_global_ref, - "funcref_temps": funcref_temps + "funcref_temps": funcref_temps, + "named_type_temps": named_type_temps }; } @@ -75,3 +80,4 @@ export var ref_as = retasmFunc.ref_as; export var use_global = retasmFunc.use_global; export var use_global_ref = retasmFunc.use_global_ref; export var funcref_temps = retasmFunc.funcref_temps; +export var named_type_temps = retasmFunc.named_type_temps; diff --git a/test/wasm2js/refs.wast b/test/wasm2js/refs.wast index 087567e8ce7..57eec8fff89 100644 --- a/test/wasm2js/refs.wast +++ b/test/wasm2js/refs.wast @@ -1,4 +1,6 @@ (module + (type $func (func (result funcref))) + (global $global (mut anyref) (ref.null any)) (global $global-ref (mut funcref) (ref.func $use-global-ref)) @@ -81,4 +83,24 @@ ) ) ) + + (func $named_type_temps (export "named_type_temps") (result funcref) + ;; This nested expression ends up needing to use temp vars, and one such + ;; name contains the type $func. We should emit that in form that is + ;; mangled for JS, without '(' which appears in the stringified name of the + ;; type, "(ref null $func)". + (select (result (ref null $func)) + (ref.null nofunc) + (if (result (ref $func)) + (i32.const 1) + (then + (ref.func $named_type_temps) + ) + (else + (unreachable) + ) + ) + (i32.const 0) + ) + ) ) From a27d952a4be7399ed30c53fcf035caacb54b7c84 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Fri, 21 Jun 2024 21:59:55 +0100 Subject: [PATCH 407/553] Add TraceCalls pass (#6619) This pass receives a list of functions to trace, and then wraps them in calls to imports. This can be useful for tracing malloc/free calls, for example, but is generic. Fixes #6548 --- src/passes/CMakeLists.txt | 1 + src/passes/TraceCalls.cpp | 218 ++++++++++++++++++ src/passes/pass.cpp | 4 + src/passes/passes.h | 1 + test/lit/help/wasm-opt.test | 4 + test/lit/help/wasm2js.test | 4 + test/lit/passes/trace-calls.wast | 156 +++++++++++++ .../trace-calls_multi-value-result.wast | 9 + 8 files changed, 397 insertions(+) create mode 100644 src/passes/TraceCalls.cpp create mode 100644 test/lit/passes/trace-calls.wast create mode 100644 test/lit/passes/trace-calls_multi-value-result.wast diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index b17730279ad..703b27e056d 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -93,6 +93,7 @@ set(passes_SOURCES StringLowering.cpp Strip.cpp StripTargetFeatures.cpp + TraceCalls.cpp RedundantSetElimination.cpp RemoveImports.cpp RemoveMemory.cpp diff --git a/src/passes/TraceCalls.cpp b/src/passes/TraceCalls.cpp new file mode 100644 index 00000000000..01278c2e9e6 --- /dev/null +++ b/src/passes/TraceCalls.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2024 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. + */ + +// +// Instruments the build with code to intercept selected function calls. +// This can be e.g. used to trace allocations (malloc, free, calloc, realloc) +// and build tools for memory usage analysis. +// The pass supports SIMD but the multi-value feature is not supported yet. +// +// Instrumenting void free(void*): + +// Instrumenting function `void* malloc(int32_t)` with a user-defined +// name of the tracer `trace_alloc` and function `void free(void*)` +// with the default name of the tracer `trace_free` (`trace_` prefix +// is added by default): +// wasm-opt --trace-calls=malloc:trace_alloc,free -o test-opt.wasm test.wasm +// +// Before: +// (call $malloc +// (local.const 32)) +// (call $free (i32.const 64)) +// +// After: +// (local $0 i32) +// (local $1 i32) +// (local $2 i32) +// (block (result i32) +// (call $trace_alloc +// (local.get $0) +// (local.tee $1 +// (call $malloc +// (local.tee $0 (i32.const 2)) +// ) +// ) +// ) +// ) +// (block +// (call $free +// (local.tee $3 +// (i32.const 64) +// ) +// ) +// (call $trace_free +// (local.get $3) +// ) +// ) + +#include + +#include "asmjs/shared-constants.h" +#include "ir/import-utils.h" +#include "pass.h" +#include "support/string.h" +#include "wasm-builder.h" + +namespace wasm { + +using TracedFunctions = std::map; + +struct AddTraceWrappers : public WalkerPass> { + AddTraceWrappers(TracedFunctions tracedFunctions) + : tracedFunctions(std::move(tracedFunctions)) {} + void visitCall(Call* curr) { + auto* target = getModule()->getFunction(curr->target); + + auto iter = tracedFunctions.find(target->name); + if (iter != tracedFunctions.end()) { + addInstrumentation(curr, target, iter->second); + } + } + +private: + void addInstrumentation(Call* curr, + const wasm::Function* target, + const Name& wrapperName) { + Builder builder(*getModule()); + std::vector realCallParams, trackerCallParams; + + for (const auto& op : curr->operands) { + auto localVar = builder.addVar(getFunction(), op->type); + realCallParams.push_back(builder.makeLocalTee(localVar, op, op->type)); + trackerCallParams.push_back(builder.makeLocalGet(localVar, op->type)); + } + + auto resultType = target->type.getSignature().results; + auto realCall = builder.makeCall(target->name, realCallParams, resultType); + + if (resultType.isConcrete()) { + auto resultLocal = builder.addVar(getFunction(), resultType); + trackerCallParams.insert( + trackerCallParams.begin(), + builder.makeLocalTee(resultLocal, realCall, resultType)); + + replaceCurrent(builder.makeBlock( + {builder.makeCall( + wrapperName, trackerCallParams, Type::BasicType::none), + builder.makeLocalGet(resultLocal, resultType)})); + } else { + replaceCurrent(builder.makeBlock( + {realCall, + builder.makeCall( + wrapperName, trackerCallParams, Type::BasicType::none)})); + } + } + + TracedFunctions tracedFunctions; +}; + +struct TraceCalls : public Pass { + // Adds calls to new imports. + bool addsEffects() override { return true; } + + void run(Module* module) override { + auto functionsDefinitions = getPassOptions().getArgument( + "trace-calls", + "TraceCalls usage: wasm-opt " + "--trace-calls=FUNCTION_TO_TRACE[:TRACER_NAME][,...]"); + + auto tracedFunctions = parseArgument(functionsDefinitions); + + for (const auto& tracedFunction : tracedFunctions) { + auto func = module->getFunctionOrNull(tracedFunction.first); + if (!func) { + std::cerr << "[TraceCalls] Function '" << tracedFunction.first + << "' not found" << std::endl; + } else { + addImport(module, *func, tracedFunction.second); + } + } + + AddTraceWrappers(std::move(tracedFunctions)).run(getPassRunner(), module); + } + +private: + Type getTracerParamsType(ImportInfo& info, const Function& func) { + auto resultsType = func.type.getSignature().results; + if (resultsType.isTuple()) { + Fatal() << "Failed to instrument function '" << func.name + << "': Multi-value result type is not supported"; + } + + std::vector tracerParamTypes; + if (resultsType.isConcrete()) { + tracerParamTypes.push_back(resultsType); + } + for (auto& op : func.type.getSignature().params) { + tracerParamTypes.push_back(op); + } + + return Type(tracerParamTypes); + } + + TracedFunctions parseArgument(const std::string& arg) { + TracedFunctions tracedFunctions; + + for (const auto& definition : String::Split(arg, ",")) { + if (definition.empty()) { + // Empty definition, ignore. + continue; + } + + std::string originName, traceName; + parseFunctionName(definition, originName, traceName); + + tracedFunctions[Name(originName)] = Name(traceName); + } + + return tracedFunctions; + } + + void parseFunctionName(const std::string& str, + std::string& originName, + std::string& traceName) { + auto parts = String::Split(str, ":"); + switch (parts.size()) { + case 1: + originName = parts[0]; + traceName = "trace_" + originName; + break; + case 2: + originName = parts[0]; + traceName = parts[1]; + break; + default: + Fatal() << "Failed to parse function name ('" << str + << "'): expected format FUNCTION_TO_TRACE[:TRACER_NAME]"; + } + } + + void addImport(Module* wasm, const Function& f, const Name& tracerName) { + ImportInfo info(*wasm); + + if (!info.getImportedFunction(ENV, tracerName)) { + auto import = Builder::makeFunction( + tracerName, Signature(getTracerParamsType(info, f), Type::none), {}); + import->module = ENV; + import->base = tracerName; + wasm->addFunction(std::move(import)); + } + } +}; + +Pass* createTraceCallsPass() { return new TraceCalls(); } + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ad0cc448c27..fd910609242 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -234,6 +234,10 @@ void PassRegistry::registerPasses() { registerPass("i64-to-i32-lowering", "lower all uses of i64s to use i32s instead", createI64ToI32LoweringPass); + registerPass( + "trace-calls", + "instrument the build with code to intercept specific function calls", + createTraceCallsPass); registerPass( "instrument-locals", "instrument the build with code to intercept all loads and stores", diff --git a/src/passes/passes.h b/src/passes/passes.h index 337a681ab22..02b164279a5 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -74,6 +74,7 @@ Pass* createLocalCSEPass(); Pass* createLocalSubtypingPass(); Pass* createLogExecutionPass(); Pass* createIntrinsicLoweringPass(); +Pass* createTraceCallsPass(); Pass* createInstrumentLocalsPass(); Pass* createInstrumentMemoryPass(); Pass* createLoopInvariantCodeMotionPass(); diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 9dd38e03e57..59409dcff70 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -500,6 +500,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --table64-lowering lower 64-bit tables 32-bit ones ;; CHECK-NEXT: +;; CHECK-NEXT: --trace-calls instrument the build with code +;; CHECK-NEXT: to intercept specific function +;; CHECK-NEXT: calls +;; CHECK-NEXT: ;; CHECK-NEXT: --translate-to-exnref translate old Phase 3 EH ;; CHECK-NEXT: instructions to new ones with ;; CHECK-NEXT: exnref diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 72efcd223f5..3c1da7ff2ab 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -454,6 +454,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --table64-lowering lower 64-bit tables 32-bit ones ;; CHECK-NEXT: +;; CHECK-NEXT: --trace-calls instrument the build with code +;; CHECK-NEXT: to intercept specific function +;; CHECK-NEXT: calls +;; CHECK-NEXT: ;; CHECK-NEXT: --translate-to-exnref translate old Phase 3 EH ;; CHECK-NEXT: instructions to new ones with ;; CHECK-NEXT: exnref diff --git a/test/lit/passes/trace-calls.wast b/test/lit/passes/trace-calls.wast new file mode 100644 index 00000000000..d12e959c6b0 --- /dev/null +++ b/test/lit/passes/trace-calls.wast @@ -0,0 +1,156 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt --enable-simd --trace-calls="noparamsnoresults,singleparamnoresults,multiparamsnoresults:tracempnr,noparamssingleresult,multiparamssingleresult" %s -S -o - | filecheck %s + +(module + + (import "env" "no_params_no_results" + (func $noparamsnoresults)) + (import "env" "single_param_no_results" + (func $singleparamnoresults (param f64))) + (import "env" "multi_params_no_results" + (func $multiparamsnoresults (param i32 i64 f32))) + (import "env" "no_params_single_result" + (func $noparamssingleresult (result v128))) + (import "env" "multi_params_single_result" + (func $multiparamssingleresult (param i32 v128)(result v128))) + (import "env" "dont_trace_me" + (func $donttraceme)) + + + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (result v128))) + + ;; CHECK: (type $2 (func (param f64))) + + ;; CHECK: (type $3 (func (param i32 i64 f32))) + + ;; CHECK: (type $4 (func (param i32 v128) (result v128))) + + ;; CHECK: (type $5 (func (param v128 i32 v128))) + + ;; CHECK: (type $6 (func (param v128))) + + ;; CHECK: (import "env" "no_params_no_results" (func $noparamsnoresults)) + + ;; CHECK: (import "env" "single_param_no_results" (func $singleparamnoresults (param f64))) + + ;; CHECK: (import "env" "multi_params_no_results" (func $multiparamsnoresults (param i32 i64 f32))) + + ;; CHECK: (import "env" "no_params_single_result" (func $noparamssingleresult (result v128))) + + ;; CHECK: (import "env" "multi_params_single_result" (func $multiparamssingleresult (param i32 v128) (result v128))) + + ;; CHECK: (import "env" "dont_trace_me" (func $donttraceme)) + + ;; CHECK: (import "env" "tracempnr" (func $tracempnr (param i32 i64 f32))) + + ;; CHECK: (import "env" "trace_multiparamssingleresult" (func $trace_multiparamssingleresult (param v128 i32 v128))) + + ;; CHECK: (import "env" "trace_noparamsnoresults" (func $trace_noparamsnoresults)) + + ;; CHECK: (import "env" "trace_noparamssingleresult" (func $trace_noparamssingleresult (param v128))) + + ;; CHECK: (import "env" "trace_singleparamnoresults" (func $trace_singleparamnoresults (param f64))) + + ;; CHECK: (func $test_no_params_no_results + ;; CHECK-NEXT: (call $noparamsnoresults) + ;; CHECK-NEXT: (call $trace_noparamsnoresults) + ;; CHECK-NEXT: ) + (func $test_no_params_no_results + (call $noparamsnoresults) + ) + + ;; CHECK: (func $test_single_param_no_results + ;; CHECK-NEXT: (local $0 f64) + ;; CHECK-NEXT: (call $singleparamnoresults + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (f64.const 4.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $trace_singleparamnoresults + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test_single_param_no_results + (call $singleparamnoresults (f64.const 4.5)) + ) + + ;; we specify a custom name (tracempnr) for the tracer function + ;; CHECK: (func $test_multi_params_no_results + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i64) + ;; CHECK-NEXT: (local $2 f32) + ;; CHECK-NEXT: (call $multiparamsnoresults + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i64.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (f32.const 1.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $tracempnr + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test_multi_params_no_results + (call $multiparamsnoresults + (i32.const 5) + (i64.const 6) + (f32.const 1.5) + ) + ) + + ;; CHECK: (func $test_no_params_single_result (result v128) + ;; CHECK-NEXT: (local $0 v128) + ;; CHECK-NEXT: (call $trace_noparamssingleresult + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (call $noparamssingleresult) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + (func $test_no_params_single_result (result v128) + call $noparamssingleresult + ) + + ;; CHECK: (func $test_multi_params_single_result (result v128) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 v128) + ;; CHECK-NEXT: (local $2 v128) + ;; CHECK-NEXT: (call $trace_multiparamssingleresult + ;; CHECK-NEXT: (local.tee $2 + ;; CHECK-NEXT: (call $multiparamssingleresult + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + (func $test_multi_params_single_result (result v128) + (call $multiparamssingleresult + (i32.const 3) + (v128.const i32x4 1 2 3 4)) + ) + + ;; this function should not be traced + ;; CHECK: (func $test_dont_trace_me + ;; CHECK-NEXT: (call $donttraceme) + ;; CHECK-NEXT: ) + (func $test_dont_trace_me + (call $donttraceme) + ) +) diff --git a/test/lit/passes/trace-calls_multi-value-result.wast b/test/lit/passes/trace-calls_multi-value-result.wast new file mode 100644 index 00000000000..ee4445dbd85 --- /dev/null +++ b/test/lit/passes/trace-calls_multi-value-result.wast @@ -0,0 +1,9 @@ +;; Test that a traced function with a multi-value result type +;; results in a useful error message + +;; RUN: not wasm-opt --enable-simd --enable-multivalue --trace-calls=multi_param_result %s 2>&1 | filecheck %s + +;; CHECK: Fatal: Failed to instrument function 'multi_param_result': Multi-value result type is not supported +(module + (import "env" "multi_param_result" (func $multi_param_result (result i32 i32))) +) From ed35193eef158d4685a88ed00d742d969d366c64 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 24 Jun 2024 12:17:11 -0700 Subject: [PATCH 408/553] Add a proper error for bad select results (#6697) The result cannot be `none` or `unreachable` etc. Fixes #6694 --- src/wasm/wasm-binary.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index dc97dbbc31b..b76a789dedb 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6865,7 +6865,11 @@ void WasmBinaryReader::visitSelect(Select* curr, uint8_t code) { size_t numTypes = getU32LEB(); std::vector types; for (size_t i = 0; i < numTypes; i++) { - types.push_back(getType()); + auto t = getType(); + if (!t.isConcrete()) { + throwError("bad select type"); + } + types.push_back(t); } curr->type = Type(types); } From 78b3c40310e886fb93480008fc55cdcd4fffa52c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 24 Jun 2024 12:17:53 -0700 Subject: [PATCH 409/553] [WasmGC] Add missing ArrayNew variants to Properties::isGenerative (#6691) Fixes #6690 --- src/ir/properties.cpp | 2 + test/lit/passes/local-cse_all-features.wast | 92 +++++++++++++++++++-- 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp index 1346f6cad37..dd9a10a8ee0 100644 --- a/src/ir/properties.cpp +++ b/src/ir/properties.cpp @@ -35,6 +35,8 @@ struct GenerativityScanner : public PostWalker { void visitCallRef(CallRef* curr) { generative = true; } void visitStructNew(StructNew* curr) { generative = true; } void visitArrayNew(ArrayNew* curr) { generative = true; } + void visitArrayNewData(ArrayNewData* curr) { generative = true; } + void visitArrayNewElem(ArrayNewElem* curr) { generative = true; } void visitArrayNewFixed(ArrayNewFixed* curr) { generative = true; } }; diff --git a/test/lit/passes/local-cse_all-features.wast b/test/lit/passes/local-cse_all-features.wast index 368936ae91c..8878d595fe9 100644 --- a/test/lit/passes/local-cse_all-features.wast +++ b/test/lit/passes/local-cse_all-features.wast @@ -64,16 +64,30 @@ ;; CHECK: (type $B (array (mut i32))) (type $B (array (mut i32))) - ;; CHECK: (type $2 (func (param (ref $A)))) ;; CHECK: (type $3 (func)) - ;; CHECK: (type $4 (func (param (ref null $A)))) + ;; CHECK: (type $C (array (mut funcref))) + (type $C (array (mut funcref))) + + ;; CHECK: (type $5 (func (param (ref null $A)))) + + ;; CHECK: (type $6 (func (param (ref null $B) (ref $A)))) + + ;; CHECK: (memory $memory 1) + (memory $memory 1) - ;; CHECK: (type $5 (func (param (ref null $B) (ref $A)))) + ;; CHECK: (data $data "abcdefg") + (data $data "abcdefg") - ;; CHECK: (func $struct-gets-nullable (type $4) (param $ref (ref null $A)) + ;; CHECK: (table $table 10 funcref) + (table $table 10 funcref) + + ;; CHECK: (elem $elem (i32.const 0) $creations) + (elem $elem (i32.const 0) funcref (ref.func $creations)) + + ;; CHECK: (func $struct-gets-nullable (type $5) (param $ref (ref null $A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $1 @@ -205,6 +219,40 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_data $B $data + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_data $B $data + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $C $elem + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_elem $C $elem + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_fixed $B 1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_fixed $B 1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $creations ;; Allocating GC data has no side effects, but each allocation is unique @@ -231,6 +279,40 @@ (i32.const 1) ) ) + (drop + (array.new_data $B $data + (i32.const 1) + (i32.const 5) + ) + ) + (drop + (array.new_data $B $data + (i32.const 1) + (i32.const 5) + ) + ) + (drop + (array.new_elem $C $elem + (i32.const 1) + (i32.const 5) + ) + ) + (drop + (array.new_elem $C $elem + (i32.const 1) + (i32.const 5) + ) + ) + (drop + (array.new_fixed $B 1 + (i32.const 1) + ) + ) + (drop + (array.new_fixed $B 1 + (i32.const 1) + ) + ) ) ;; CHECK: (func $nested-generativity (type $3) @@ -263,7 +345,7 @@ ) ) - ;; CHECK: (func $structs-and-arrays-do-not-alias (type $5) (param $array (ref null $B)) (param $struct (ref $A)) + ;; CHECK: (func $structs-and-arrays-do-not-alias (type $6) (param $array (ref null $B)) (param $struct (ref $A)) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (array.set $B ;; CHECK-NEXT: (local.get $array) From 4e07d867f8c4cbcf0180ad439a08c46353bc3751 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 25 Jun 2024 09:05:05 -0700 Subject: [PATCH 410/553] [NFC] Remove a minor compile-time optimization in Heap2Local (#6699) We tracked which expressions we saw an allocated struct/array reach, and then quickly exited when another one did (as when two allocations mix, we can optimize neither). It turns out that this helps very little in actual measurements (looks like within noise - likely we are ruling out the un-optimizable cases early otherwise anyhow). Also the complexity it adds is a problem for an improvement I want to make to the pass, so remove it. --- src/passes/Heap2Local.cpp | 49 +++++---------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 9d1763ddc1b..519c45fdcd1 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -170,16 +170,8 @@ namespace { // Core analysis that provides an escapes() method to check if an allocation // escapes in a way that prevents optimizing it away as described above. It also // stashes information about the relevant expressions as it goes, which helps -// optimization later (|seen| and |reached|). +// optimization later (|reached|). struct EscapeAnalyzer { - // All the expressions that have already been seen by the optimizer, see the - // comment above on exclusivity: once we have seen something when analyzing - // one allocation, if we reach it again then we can exit early since seeing it - // a second time proves we lost exclusivity. We must track this across - // multiple instances of EscapeAnalyzer as each handles a particular - // allocation. - std::unordered_set& seen; - // To find what escapes, we need to follow where values flow, both up to // parents, and via branches, and through locals. // TODO: for efficiency, only scan reference types in LocalGraph @@ -190,14 +182,13 @@ struct EscapeAnalyzer { const PassOptions& passOptions; Module& wasm; - EscapeAnalyzer(std::unordered_set& seen, - const LocalGraph& localGraph, + EscapeAnalyzer(const LocalGraph& localGraph, const Parents& parents, const BranchUtils::BranchTargets& branchTargets, const PassOptions& passOptions, Module& wasm) - : seen(seen), localGraph(localGraph), parents(parents), - branchTargets(branchTargets), passOptions(passOptions), wasm(wasm) {} + : localGraph(localGraph), parents(parents), branchTargets(branchTargets), + passOptions(passOptions), wasm(wasm) {} // We must track all the local.sets that write the allocation, to verify // exclusivity. @@ -261,30 +252,6 @@ struct EscapeAnalyzer { assert(interaction == ParentChildInteraction::FullyConsumes || interaction == ParentChildInteraction::Flows); - // If we've already seen an expression, stop since we cannot optimize - // things that overlap in any way (see the notes on exclusivity, above). - // Note that we use a nonrepeating queue here, so we already do not visit - // the same thing more than once; what this check does is verify we don't - // look at something that another allocation reached, which would be in a - // different call to this function and use a different queue (any overlap - // between calls would prove non-exclusivity). - // - // Note that we do this after the check for Escapes/Mixes above: it is - // possible for a parent to receive two children and handle them - // differently: - // - // (struct.set - // (local.get $ref) - // (local.get $value) - // ) - // - // The value escapes, but the ref does not, and might be optimized. If we - // added the parent to |seen| for both children, the reference would get - // blocked from being optimized. - if (!seen.emplace(parent).second) { - return true; - } - // We can proceed, as the parent interacts with us properly, and we are // the only allocation to get here. @@ -1027,10 +994,6 @@ struct Heap2Local { // flow to. localGraph.computeSetInfluences(); - // All the expressions we have already looked at. We use this to avoid - // repeated work, see above. - std::unordered_set seen; - // Find all the relevant allocations in the function: StructNew, ArrayNew, // ArrayNewFixed. struct AllocationFinder : public PostWalker { @@ -1090,7 +1053,7 @@ struct Heap2Local { } EscapeAnalyzer analyzer( - seen, localGraph, parents, branchTargets, passOptions, wasm); + localGraph, parents, branchTargets, passOptions, wasm); if (!analyzer.escapes(allocation)) { // Convert the allocation and all its uses into a struct. Then convert // the struct into locals. @@ -1110,7 +1073,7 @@ struct Heap2Local { // Check for escaping, noting relevant information as we go. If this does // not escape, optimize it into locals. EscapeAnalyzer analyzer( - seen, localGraph, parents, branchTargets, passOptions, wasm); + localGraph, parents, branchTargets, passOptions, wasm); if (!analyzer.escapes(allocation)) { Struct2Local(allocation, analyzer, func, wasm); } From a9f6bc020ad8f483d14ad03cfb957da5dd1d290b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 25 Jun 2024 09:05:45 -0700 Subject: [PATCH 411/553] Add a missing binary reading check for BrOn's reference child's type (#6700) That child must be a reference, as `finalize()` assumes so. To avoid an assertion, error early. Fixes #6696 --- src/wasm/wasm-binary.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b76a789dedb..b2347820576 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7320,6 +7320,9 @@ bool WasmBinaryReader::maybeVisitBrOn(Expression*& out, uint32_t code) { } auto name = getBreakTarget(getU32LEB()).name; auto* ref = popNonVoidExpression(); + if (!ref->type.isRef() && ref->type != Type::unreachable) { + throwError("bad input type for br_on*"); + } if (isCast) { auto inputNullability = (flags & 1) ? Nullable : NonNullable; auto castNullability = (flags & 2) ? Nullable : NonNullable; From 0a0ee6fe67f10a22503a964c31161c4584286d87 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 25 Jun 2024 09:05:59 -0700 Subject: [PATCH 412/553] Add missing struct/array type checks in binary reader (#6701) Fixes #6695 --- src/wasm/wasm-binary.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b2347820576..1644c295045 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7346,6 +7346,9 @@ bool WasmBinaryReader::maybeVisitStructNew(Expression*& out, uint32_t code) { if (code == BinaryConsts::StructNew || code == BinaryConsts::StructNewDefault) { auto heapType = getIndexedHeapType(); + if (!heapType.isStruct()) { + throwError("Expected struct heaptype"); + } std::vector operands; if (code == BinaryConsts::StructNew) { auto numOperands = heapType.getStruct().fields.size(); @@ -7393,6 +7396,9 @@ bool WasmBinaryReader::maybeVisitStructSet(Expression*& out, uint32_t code) { } auto* curr = allocator.alloc(); auto heapType = getIndexedHeapType(); + if (!heapType.isStruct()) { + throwError("Expected struct heaptype"); + } curr->index = getU32LEB(); curr->value = popNonVoidExpression(); curr->ref = popNonVoidExpression(); @@ -7405,6 +7411,9 @@ bool WasmBinaryReader::maybeVisitStructSet(Expression*& out, uint32_t code) { bool WasmBinaryReader::maybeVisitArrayNewData(Expression*& out, uint32_t code) { if (code == BinaryConsts::ArrayNew || code == BinaryConsts::ArrayNewDefault) { auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } auto* size = popNonVoidExpression(); Expression* init = nullptr; if (code == BinaryConsts::ArrayNew) { @@ -7421,6 +7430,9 @@ bool WasmBinaryReader::maybeVisitArrayNewElem(Expression*& out, uint32_t code) { code == BinaryConsts::ArrayNewElem) { auto isData = code == BinaryConsts::ArrayNewData; auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } auto segIdx = getU32LEB(); auto* size = popNonVoidExpression(); auto* offset = popNonVoidExpression(); @@ -7444,6 +7456,9 @@ bool WasmBinaryReader::maybeVisitArrayNewFixed(Expression*& out, uint32_t code) { if (code == BinaryConsts::ArrayNewFixed) { auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } auto size = getU32LEB(); std::vector values(size); for (size_t i = 0; i < size; i++) { @@ -7484,6 +7499,9 @@ bool WasmBinaryReader::maybeVisitArraySet(Expression*& out, uint32_t code) { return false; } auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } auto* value = popNonVoidExpression(); auto* index = popNonVoidExpression(); auto* ref = popNonVoidExpression(); @@ -7506,7 +7524,13 @@ bool WasmBinaryReader::maybeVisitArrayCopy(Expression*& out, uint32_t code) { return false; } auto destHeapType = getIndexedHeapType(); + if (!destHeapType.isArray()) { + throwError("Expected array heaptype"); + } auto srcHeapType = getIndexedHeapType(); + if (!srcHeapType.isArray()) { + throwError("Expected array heaptype"); + } auto* length = popNonVoidExpression(); auto* srcIndex = popNonVoidExpression(); auto* srcRef = popNonVoidExpression(); @@ -7524,6 +7548,9 @@ bool WasmBinaryReader::maybeVisitArrayFill(Expression*& out, uint32_t code) { return false; } auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } auto* size = popNonVoidExpression(); auto* value = popNonVoidExpression(); auto* index = popNonVoidExpression(); @@ -7545,6 +7572,9 @@ bool WasmBinaryReader::maybeVisitArrayInit(Expression*& out, uint32_t code) { return false; } auto heapType = getIndexedHeapType(); + if (!heapType.isArray()) { + throwError("Expected array heaptype"); + } Index segIdx = getU32LEB(); auto* size = popNonVoidExpression(); auto* offset = popNonVoidExpression(); From 4cd8b61c5d4817f753a54ef9f501db66969e310f Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 25 Jun 2024 09:35:17 -0700 Subject: [PATCH 413/553] [threads] Validate shared-to-unshared edges in heap types (#6698) Add spec tests checking validation for structs and arrays. --- src/wasm-type.h | 2 + src/wasm/wasm-type.cpp | 69 +++++++++++++++++------- test/lit/passes/type-merging-shared.wast | 8 +-- test/spec/shared-array.wast | 69 ++++++++++++++++++++++++ test/spec/shared-struct.wast | 69 ++++++++++++++++++++++++ 5 files changed, 195 insertions(+), 22 deletions(-) create mode 100644 test/spec/shared-array.wast create mode 100644 test/spec/shared-struct.wast diff --git a/src/wasm-type.h b/src/wasm-type.h index 95c3605a593..51d945b5373 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -671,6 +671,8 @@ struct TypeBuilder { ForwardChildReference, // A continuation reference that does not refer to a function type. InvalidFuncType, + // A non-shared field of a shared heap type. + InvalidUnsharedField, }; struct Error { diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index ae6fd4b305f..92c68d8bef0 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1697,6 +1697,8 @@ std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) { return os << "Heap type has an undeclared child"; case TypeBuilder::ErrorReason::InvalidFuncType: return os << "Continuation has invalid function type"; + case TypeBuilder::ErrorReason::InvalidUnsharedField: + return os << "Heap type has an invalid unshared field"; } WASM_UNREACHABLE("Unexpected error reason"); } @@ -2628,6 +2630,53 @@ bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { WASM_UNREACHABLE("unknown kind"); } +std::optional +validateType(HeapTypeInfo& info, std::unordered_set& seenTypes) { + if (auto* super = info.supertype) { + // The supertype must be canonical (i.e. defined in a previous rec group) + // or have already been defined in this rec group. + if (super->isTemp && !seenTypes.count(HeapType(uintptr_t(super)))) { + return TypeBuilder::ErrorReason::ForwardSupertypeReference; + } + // The supertype must have a valid structure. + if (!isValidSupertype(info, *super)) { + return TypeBuilder::ErrorReason::InvalidSupertype; + } + } + if (info.isContinuation()) { + if (!info.continuation.type.isSignature()) { + return TypeBuilder::ErrorReason::InvalidFuncType; + } + } + if (info.share == Shared) { + switch (info.kind) { + case HeapTypeInfo::SignatureKind: + // TODO: Figure out and enforce shared function rules. + break; + case HeapTypeInfo::ContinuationKind: + if (!info.continuation.type.isShared()) { + return TypeBuilder::ErrorReason::InvalidFuncType; + } + break; + case HeapTypeInfo::StructKind: + for (auto& field : info.struct_.fields) { + if (field.type.isRef() && !field.type.getHeapType().isShared()) { + return TypeBuilder::ErrorReason::InvalidUnsharedField; + } + } + break; + case HeapTypeInfo::ArrayKind: { + auto elem = info.array.element.type; + if (elem.isRef() && !elem.getHeapType().isShared()) { + return TypeBuilder::ErrorReason::InvalidUnsharedField; + } + break; + } + } + } + return std::nullopt; +} + void updateReferencedHeapTypes( std::unique_ptr& info, const std::unordered_map& canonicalized) { @@ -2695,24 +2744,8 @@ buildRecGroup(std::unique_ptr&& groupInfo, std::unordered_set seenTypes; for (size_t i = 0; i < typeInfos.size(); ++i) { auto& info = typeInfos[i]; - if (auto* super = info->supertype) { - // The supertype must be canonical (i.e. defined in a previous rec group) - // or have already been defined in this rec group. - if (super->isTemp && !seenTypes.count(HeapType(uintptr_t(super)))) { - return {TypeBuilder::Error{ - i, TypeBuilder::ErrorReason::ForwardSupertypeReference}}; - } - // The supertype must have a valid structure. - if (!isValidSupertype(*info, *super)) { - return { - TypeBuilder::Error{i, TypeBuilder::ErrorReason::InvalidSupertype}}; - } - } - if (info->isContinuation()) { - if (!info->continuation.type.isSignature()) { - return { - TypeBuilder::Error{i, TypeBuilder::ErrorReason::InvalidFuncType}}; - } + if (auto err = validateType(*info, seenTypes)) { + return {TypeBuilder::Error{i, *err}}; } seenTypes.insert(asHeapType(info)); } diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast index 2457cd57259..e0281507942 100644 --- a/test/lit/passes/type-merging-shared.wast +++ b/test/lit/passes/type-merging-shared.wast @@ -79,11 +79,11 @@ (module ;; Shared and unshared basic heap types similarly cannot be merged. ;; CHECK: (rec - ;; CHECK-NEXT: (type $A' (shared (struct (field anyref)))) + ;; CHECK-NEXT: (type $A' (struct (field anyref))) - ;; CHECK: (type $A (shared (struct (field (ref null (shared any)))))) - (type $A (shared (struct (ref null (shared any))))) - (type $A' (shared (struct (ref null any)))) + ;; CHECK: (type $A (struct (field (ref null (shared any))))) + (type $A (struct (ref null (shared any)))) + (type $A' (struct (ref null any))) ;; CHECK: (type $2 (func)) diff --git a/test/spec/shared-array.wast b/test/spec/shared-array.wast new file mode 100644 index 00000000000..a687c1d36d0 --- /dev/null +++ b/test/spec/shared-array.wast @@ -0,0 +1,69 @@ +;; Shared array declaration syntax +(module + (type (shared (array i8))) + (type (sub final (shared (array i8)))) + (rec + (type (sub final (shared (array i8)))) + ) + + (global (ref 0) (array.new_default 1 (i32.const 1))) + (global (ref 1) (array.new_default 2 (i32.const 1))) + (global (ref 2) (array.new_default 0 (i32.const 1))) +) + +;; Shared arrays are distinct from non-shared arrays +(assert_invalid + (module + (type (shared (array i8))) + (type (array i8)) + + (global (ref 0) (array.new_default 1 (i32.const 1))) + ) + "not a subtype" +) + +(assert_invalid + (module + (type (shared (array i8))) + (type (array i8)) + + (global (ref 1) (array.new 0)) + ) + "not a subtype" +) + +;; Shared arrays may not be subtypes of non-shared arrays +(assert_invalid + (module + (type (sub (array i8))) + (type (sub 0 (shared (array i8)))) + ) + "invalid supertype" +) + +;; Non-shared arrays may not be subtypes of shared arrays +(assert_invalid + (module + (type (sub (shared (array i8)))) + (type (sub 0 (array i8))) + ) + "invalid supertype" +) + +;; Shared arrays may not contain non-shared references +(assert_invalid + (module + (type (shared (array anyref))) + ) + "invalid field" +) + +;; But they may contain shared references +(module + (type (shared (array (ref null (shared any))))) +) + +;; Non-shared arrays may contain shared references +(module + (type (array (ref null (shared any)))) +) diff --git a/test/spec/shared-struct.wast b/test/spec/shared-struct.wast new file mode 100644 index 00000000000..b2c82caff93 --- /dev/null +++ b/test/spec/shared-struct.wast @@ -0,0 +1,69 @@ +;; Shared struct declaration syntax +(module + (type (shared (struct))) + (type (sub final (shared (struct)))) + (rec + (type (sub final (shared (struct)))) + ) + + (global (ref 0) (struct.new 1)) + (global (ref 1) (struct.new 2)) + (global (ref 2) (struct.new 0)) +) + +;; Shared structs are distinct from non-shared structs +(assert_invalid + (module + (type (shared (struct))) + (type (struct)) + + (global (ref 0) (struct.new 1)) + ) + "not a subtype" +) + +(assert_invalid + (module + (type (shared (struct))) + (type (struct)) + + (global (ref 1) (struct.new 0)) + ) + "not a subtype" +) + +;; Shared structs may not be subtypes of non-shared structs +(assert_invalid + (module + (type (sub (struct))) + (type (sub 0 (shared (struct)))) + ) + "invalid supertype" +) + +;; Non-shared structs may not be subtypes of shared structs +(assert_invalid + (module + (type (sub (shared (struct)))) + (type (sub 0 (struct))) + ) + "invalid supertype" +) + +;; Shared structs may not contain non-shared references +(assert_invalid + (module + (type (shared (struct anyref))) + ) + "invalid field" +) + +;; But they may contain shared references +(module + (type (shared (struct (ref null (shared any))))) +) + +;; Non-shared structs may contain shared references +(module + (type (struct (ref null (shared any)))) +) From 654ee6e2504f11fb0e982a2cf276bafa750f694b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 25 Jun 2024 12:39:05 -0700 Subject: [PATCH 414/553] [threads] Validate shared-polymorphic instructions (#6702) Such as `ref.eq`, `i31.get_{s,u}`, and `array.len`. Also validate that struct and array operations work on shared structs and arrays. --- scripts/fuzz_opt.py | 1 + src/wasm/wasm-binary.cpp | 9 +- src/wasm/wasm-validator.cpp | 131 ++++++++++++++--------------- test/spec/shared-array.wast | 46 ++++++++++ test/spec/shared-polymorphism.wast | 12 +++ test/spec/shared-struct.wast | 23 +++++ 6 files changed, 150 insertions(+), 72 deletions(-) create mode 100644 test/spec/shared-polymorphism.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 0804c0387e1..192c0d362b6 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -353,6 +353,7 @@ def is_git_repo(): # Shared types implementation in progress 'type-merging-shared.wast', 'shared-types.wast', + 'shared-polymorphism.wast', 'shared-struct.wast', ] diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 1644c295045..c4aaec5e908 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2272,11 +2272,16 @@ void WasmBinaryReader::readTypes() { TypeBuilder builder(getU32LEB()); BYN_TRACE("num: " << builder.size() << std::endl); - auto readHeapType = [&]() { + auto readHeapType = [&]() -> HeapType { int64_t htCode = getS64LEB(); // TODO: Actually s33 + auto share = Unshared; + if (htCode == BinaryConsts::EncodedType::Shared) { + share = Shared; + htCode = getS64LEB(); // TODO: Actually s33 + } HeapType ht; if (getBasicHeapType(htCode, ht)) { - return ht; + return ht.getBasic(share); } if (size_t(htCode) >= builder.size()) { throwError("invalid type index: " + std::to_string(htCode)); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 13993c82518..281f3ec4599 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -209,6 +209,18 @@ struct ValidationInfo { fail(text, curr, func); return false; } + + bool shouldBeSubTypeIgnoringShared(Type left, + Type right, + Expression* curr, + const char* text, + Function* func = nullptr) { + assert(right.isRef() && right.getHeapType().isBasic()); + auto share = left.isRef() ? left.getHeapType().getShared() : Unshared; + auto ht = right.getHeapType(); + auto matchedRight = Type(ht.getBasic(share), right.getNullability()); + return shouldBeSubType(left, matchedRight, curr, text, func); + } }; struct FunctionValidator : public WalkerPass> { @@ -526,6 +538,13 @@ struct FunctionValidator : public WalkerPass> { return info.shouldBeSubType(left, right, curr, text, getFunction()); } + bool shouldBeSubTypeIgnoringShared(Type left, + Type right, + Expression* curr, + const char* text) { + return info.shouldBeSubTypeIgnoringShared(left, right, curr, text); + } + void validateOffset(Address offset, Memory* mem, Expression* curr); void validateAlignment( size_t align, Type type, Index bytes, bool isAtomic, Expression* curr); @@ -2256,14 +2275,16 @@ void FunctionValidator::visitRefEq(RefEq* curr) { Type eqref = Type(HeapType::eq, Nullable); shouldBeTrue( getModule()->features.hasGC(), curr, "ref.eq requires gc [--enable-gc]"); - shouldBeSubType(curr->left->type, - eqref, - curr->left, - "ref.eq's left argument should be a subtype of eqref"); - shouldBeSubType(curr->right->type, - eqref, - curr->right, - "ref.eq's right argument should be a subtype of eqref"); + shouldBeSubTypeIgnoringShared( + curr->left->type, + eqref, + curr->left, + "ref.eq's left argument should be a subtype of eqref"); + shouldBeSubTypeIgnoringShared( + curr->right->type, + eqref, + curr->right, + "ref.eq's right argument should be a subtype of eqref"); } void FunctionValidator::visitTableGet(TableGet* curr) { @@ -2689,10 +2710,10 @@ void FunctionValidator::visitI31Get(I31Get* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "i31.get_s/u requires gc [--enable-gc]"); - shouldBeSubType(curr->i31->type, - Type(HeapType::i31, Nullable), - curr->i31, - "i31.get_s/u's argument should be i31ref"); + shouldBeSubTypeIgnoringShared(curr->i31->type, + Type(HeapType::i31, Nullable), + curr->i31, + "i31.get_s/u's argument should be i31ref"); } void FunctionValidator::visitRefTest(RefTest* curr) { @@ -3008,24 +3029,15 @@ void FunctionValidator::visitArrayGet(ArrayGet* curr) { getModule()->features.hasGC(), curr, "array.get requires gc [--enable-gc]"); shouldBeEqualOrFirstIsUnreachable( curr->index->type, Type(Type::i32), curr, "array.get index must be an i32"); - if (curr->type == Type::unreachable) { - return; - } - if (!shouldBeSubType(curr->ref->type, - Type(HeapType::array, Nullable), - curr, - "array.get target should be an array reference")) { + const char* mustBeArray = + "array.get target should be a specific array reference"; + if (curr->type == Type::unreachable || + !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) || + curr->ref->type.getHeapType().isBottom() || + !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) { return; } auto heapType = curr->ref->type.getHeapType(); - if (heapType == HeapType::none) { - return; - } - if (!shouldBeTrue(heapType != HeapType::array, - curr, - "array.get target should be a specific array reference")) { - return; - } const auto& element = heapType.getArray().element; // If the type is not packed, it must be marked internally as unsigned, by // convention. @@ -3044,19 +3056,11 @@ void FunctionValidator::visitArraySet(ArraySet* curr) { if (curr->type == Type::unreachable) { return; } - if (!shouldBeSubType(curr->ref->type, - Type(HeapType::array, Nullable), - curr, - "array.set target should be an array reference")) { - return; - } - auto heapType = curr->ref->type.getHeapType(); - if (heapType == HeapType::none) { - return; - } - if (!shouldBeTrue(heapType != HeapType::array, - curr, - "array.set target should be a specific array reference")) { + const char* mustBeArray = "array.set target should be an array reference"; + if (curr->type == Type::unreachable || + !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) || + curr->ref->type.getHeapType().isBottom() || + !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) { return; } const auto& element = curr->ref->type.getHeapType().getArray().element; @@ -3072,10 +3076,11 @@ void FunctionValidator::visitArrayLen(ArrayLen* curr) { getModule()->features.hasGC(), curr, "array.len requires gc [--enable-gc]"); shouldBeEqualOrFirstIsUnreachable( curr->type, Type(Type::i32), curr, "array.len result must be an i32"); - shouldBeSubType(curr->ref->type, - Type(HeapType::array, Nullable), - curr, - "array.len argument must be an array reference"); + shouldBeSubTypeIgnoringShared( + curr->ref->type, + Type(HeapType::array, Nullable), + curr, + "array.len argument must be an array reference"); } void FunctionValidator::visitArrayCopy(ArrayCopy* curr) { @@ -3145,22 +3150,15 @@ void FunctionValidator::visitArrayFill(ArrayFill* curr) { "array.fill index must be an i32"); shouldBeEqualOrFirstIsUnreachable( curr->size->type, Type(Type::i32), curr, "array.fill size must be an i32"); - if (curr->type == Type::unreachable) { - return; - } - if (!shouldBeSubType(curr->ref->type, - Type(HeapType::array, Nullable), - curr, - "array.fill destination should be an array reference")) { + const char* mustBeArray = + "array.fill destination should be an array reference"; + if (curr->type == Type::unreachable || + !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) || + curr->ref->type.getHeapType().isBottom() || + !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) { return; } auto heapType = curr->ref->type.getHeapType(); - if (heapType == HeapType::none || - !shouldBeTrue(heapType.isArray(), - curr, - "array.fill destination should be an array reference")) { - return; - } auto element = heapType.getArray().element; shouldBeSubType(curr->value->type, element.type, @@ -3187,22 +3185,15 @@ void FunctionValidator::visitArrayInit(ArrayInit* curr) { Type(Type::i32), curr, "array.init_* size must be an i32"); - if (curr->type == Type::unreachable) { - return; - } - if (!shouldBeSubType(curr->ref->type, - Type(HeapType::array, Nullable), - curr, - "array.init_* destination must be an array reference")) { + const char* mustBeArray = + "array.init_* destination must be an array reference"; + if (curr->type == Type::unreachable || + !shouldBeTrue(curr->ref->type.isRef(), curr, mustBeArray) || + curr->ref->type.getHeapType().isBottom() || + !shouldBeTrue(curr->ref->type.isArray(), curr, mustBeArray)) { return; } auto heapType = curr->ref->type.getHeapType(); - if (heapType == HeapType::none || - !shouldBeTrue(heapType.isArray(), - curr, - "array.init_* destination must be an array reference")) { - return; - } auto element = heapType.getArray().element; shouldBeTrue( element.mutable_, curr, "array.init_* destination must be mutable"); diff --git a/test/spec/shared-array.wast b/test/spec/shared-array.wast index a687c1d36d0..7aa3877316a 100644 --- a/test/spec/shared-array.wast +++ b/test/spec/shared-array.wast @@ -67,3 +67,49 @@ (module (type (array (ref null (shared any)))) ) + +;; Array instructions work on shared arrays. +(module + (type $i8 (shared (array (mut i8)))) + (type $i32 (shared (array (mut i32)))) + (type $unshared (array (mut i8))) + + (data) + (elem) + + (func (array.new $i8 (i32.const 0) (i32.const 0)) (drop)) + + (func (array.new_default $i8 (i32.const 0)) (drop)) + + (func (array.new_fixed $i8 0) (drop)) + + (func (param (ref null $i8)) + (array.get_s $i8 (local.get 0) (i32.const 0)) (drop)) + + (func (param (ref null $i8)) + (array.get_u $i8 (local.get 0) (i32.const 0)) (drop)) + + (func (param (ref null $i32)) + (array.get $i32 (local.get 0) (i32.const 0)) (drop)) + + (func (param (ref null $i8)) + (array.set $i8 (local.get 0) (i32.const 0) (i32.const 0))) + + (func (param (ref null $i8) (ref null $i8)) + (array.copy $i8 $i8 (local.get 0) (i32.const 0) (local.get 1) (i32.const 0) (i32.const 0))) + + (func (param (ref null $i8) (ref null $unshared)) + (array.copy $i8 $unshared (local.get 0) (i32.const 0) (local.get 1) (i32.const 0) (i32.const 0))) + + (func (param (ref null $unshared) (ref null $i8)) + (array.copy $unshared $i8 (local.get 0) (i32.const 0) (local.get 1) (i32.const 0) (i32.const 0))) + + (func (param (ref null $i8)) + (array.fill $i8 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) + + (func (param (ref null $i8)) + (array.init_data $i8 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) + + (func (param (ref null $i8)) + (array.init_data $i8 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) +) diff --git a/test/spec/shared-polymorphism.wast b/test/spec/shared-polymorphism.wast new file mode 100644 index 00000000000..547829f1170 --- /dev/null +++ b/test/spec/shared-polymorphism.wast @@ -0,0 +1,12 @@ +;; Some instructions are shared-polymorphic and work with shared or unshared +;; references. +(module + (func (drop (ref.eq (ref.null (shared none)) (ref.null (shared none))))) + (func (drop (ref.eq (ref.null (shared none)) (ref.null none)))) + (func (drop (ref.eq (ref.null none) (ref.null (shared none))))) + + (func (param (ref null (shared i31))) (drop (i31.get_s (local.get 0)))) + (func (param (ref null (shared i31))) (drop (i31.get_u (local.get 0)))) + + (func (param (ref null (shared array))) (drop (array.len (local.get 0)))) +) diff --git a/test/spec/shared-struct.wast b/test/spec/shared-struct.wast index b2c82caff93..28139bb2809 100644 --- a/test/spec/shared-struct.wast +++ b/test/spec/shared-struct.wast @@ -67,3 +67,26 @@ (module (type (struct (ref null (shared any)))) ) + +;; Struct instructions work on shared structs. +(module + (type $i8 (shared (struct (mut i8)))) + (type $i32 (shared (struct (mut i32)))) + (type $unshared (struct (mut i8))) + + (func (struct.new $i8 (i32.const 0)) (drop)) + + (func (struct.new_default $i8) (drop)) + + (func (param (ref null $i8)) + (struct.get_s $i8 0 (local.get 0)) (drop)) + + (func (param (ref null $i8)) + (struct.get_u $i8 0 (local.get 0)) (drop)) + + (func (param (ref null $i32)) + (struct.get $i32 0 (local.get 0)) (drop)) + + (func (param (ref null $i8)) + (struct.set $i8 0 (local.get 0) (i32.const 0))) +) From d6b4f0107a32066e7f3efbb4e9eb518ddcd914f5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 26 Jun 2024 08:10:52 -0700 Subject: [PATCH 415/553] [WasmGC] Heap2Local: Optimize RefEq (#6703) If an allocation does not escape, then we can compute ref.eq for it: when compared to itself the result is 1, and when compared to anything else it is 0 (since it did not escape, anything else must be different). --- src/passes/Heap2Local.cpp | 44 ++++- test/lit/passes/heap2local.wast | 318 +++++++++++++++++++++++++++++++- 2 files changed, 352 insertions(+), 10 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 519c45fdcd1..39c77bec489 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -349,6 +349,12 @@ struct EscapeAnalyzer { void visitLocalSet(LocalSet* curr) { escapes = false; } // Reference operations. TODO add more + void visitRefEq(RefEq* curr) { + // The reference is compared for identity, but nothing more. + escapes = false; + fullyConsumes = true; + } + void visitRefAs(RefAs* curr) { // TODO General OptimizeInstructions integration, that is, since we know // that our allocation is what flows into this RefAs, we can @@ -507,14 +513,18 @@ struct EscapeAnalyzer { // efficient, but it would need to be more complex. struct Struct2Local : PostWalker { StructNew* allocation; - const EscapeAnalyzer& analyzer; + + // The analyzer is not |const| because we update |analyzer.reached| as we go + // (see replaceCurrent, below). + EscapeAnalyzer& analyzer; + Function* func; Module& wasm; Builder builder; const FieldList& fields; Struct2Local(StructNew* allocation, - const EscapeAnalyzer& analyzer, + EscapeAnalyzer& analyzer, Function* func, Module& wasm) : allocation(allocation), analyzer(analyzer), func(func), wasm(wasm), @@ -539,6 +549,15 @@ struct Struct2Local : PostWalker { // In rare cases we may need to refinalize, see below. bool refinalize = false; + Expression* replaceCurrent(Expression* expression) { + PostWalker::replaceCurrent(expression); + // Also update |reached|: we are replacing something that was reached, so + // logically the replacement is also reached. This update is necessary if + // the parent of an expression cares about whether a child was reached. + analyzer.reached.insert(expression); + return expression; + } + // Rewrite the code in visit* methods. The general approach taken is to // replace the allocation with a null reference (which may require changing // types in some places, like making a block return value nullable), and to @@ -688,6 +707,27 @@ struct Struct2Local : PostWalker { replaceCurrent(builder.makeBlock(contents)); } + void visitRefEq(RefEq* curr) { + if (!analyzer.reached.count(curr)) { + return; + } + + if (curr->type == Type::unreachable) { + // The result does not matter. Leave things as they are (and let DCE + // handle it). + return; + } + + // If our reference is compared to itself, the result is 1. If it is + // compared to something else, the result must be 0, as our reference does + // not escape to any other place. + int32_t result = analyzer.reached.count(curr->left) > 0 && + analyzer.reached.count(curr->right) > 0; + // For simplicity, simply drop the RefEq and put a constant result after. + replaceCurrent(builder.makeSequence(builder.makeDrop(curr), + builder.makeConst(Literal(result)))); + } + void visitRefAs(RefAs* curr) { if (!analyzer.reached.count(curr)) { return; diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 80eb9bd2614..bd613e18c4b 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -13,9 +13,9 @@ ;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive))))) - ;; CHECK: (type $4 (func (param (ref null $struct.A)))) + ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (type $5 (func (result i32))) + ;; CHECK: (type $5 (func (param (ref null $struct.A)))) ;; CHECK: (type $6 (func (result anyref))) @@ -36,6 +36,10 @@ ;; CHECK: (type $11 (func (param i32))) + ;; CHECK: (type $12 (func (param eqref) (result i32))) + + ;; CHECK: (type $13 (func (param eqref eqref) (result i32))) + ;; CHECK: (func $simple (type $1) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) @@ -474,7 +478,7 @@ ) ) - ;; CHECK: (func $send-ref (type $4) (param $0 (ref null $struct.A)) + ;; CHECK: (func $send-ref (type $5) (param $0 (ref null $struct.A)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $send-ref (param (ref null $struct.A)) @@ -887,7 +891,7 @@ ) ) - ;; CHECK: (func $tee (type $5) (result i32) + ;; CHECK: (func $tee (type $4) (result i32) ;; CHECK-NEXT: (local $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) @@ -1786,7 +1790,7 @@ ) ) - ;; CHECK: (func $ref-as-non-null-through-local (type $5) (result i32) + ;; CHECK: (func $ref-as-non-null-through-local (type $4) (result i32) ;; CHECK-NEXT: (local $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) @@ -1959,7 +1963,7 @@ (local.get $0) ) - ;; CHECK: (func $to-param (type $4) (param $ref (ref null $struct.A)) + ;; CHECK: (func $to-param (type $5) (param $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop @@ -2006,7 +2010,7 @@ ) ) - ;; CHECK: (func $to-param-loop (type $4) (param $ref (ref null $struct.A)) + ;; CHECK: (func $to-param-loop (type $5) (param $ref (ref null $struct.A)) ;; CHECK-NEXT: (loop $loop ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $struct.A 0 @@ -2046,7 +2050,7 @@ ) ) - ;; CHECK: (func $ref-cast (type $5) (result i32) + ;; CHECK: (func $ref-cast (type $4) (result i32) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) ;; CHECK-NEXT: (local $2 i32) @@ -2080,6 +2084,304 @@ ) ) ) + + ;; CHECK: (func $ref-eq (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq (result i32) + ;; Comparing an allocation to something else results in 0, and we can + ;; optimize away the allocation. + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (ref.null eq) + ) + ) + + ;; CHECK: (func $ref-eq-flip (type $12) (param $other eqref) (result i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $other) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq-flip (param $other eqref) (result i32) + ;; As above, but flipped, and compared to a local. + (ref.eq + (local.get $other) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + + ;; CHECK: (func $ref-eq-self (type $4) (result i32) + ;; CHECK-NEXT: (local $eq eqref) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $ref-eq-self (result i32) + (local $eq eqref) + ;; Comparing to oneself results in 1, and we can optimize away the + ;; allocation. + (ref.eq + (local.tee $eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + (local.get $eq) + ) + ) + + ;; CHECK: (func $ref-eq-unreachable (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unreachable (result i32) + ;; When a child is unreachable, the result does not matter (but we should + ;; still emit validating code). + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (unreachable) + ) + ) + + ;; CHECK: (func $ref-eq-unreachable-flipped (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unreachable-flipped (result i32) + ;; As above, but with children flipped. + (ref.eq + (unreachable) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + + ;; CHECK: (func $ref-eq-unrelated (type $13) (param $x eqref) (param $y eqref) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unrelated (param $x eqref) (param $y eqref) (result i32) + ;; We know nothing about either ref.eq arm, and do nothing, despite + ;; another allocation in the function (which ensures we enter the + ;; optimization part of the pass; that other allocation can be removed). + (drop + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + (ref.eq + (local.get $x) + (local.get $y) + ) + ) + + ;; CHECK: (func $ref-eq-two (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 f64) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (f64.const 2.2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq-two (result i32) + ;; Two separate allocations. We can optimize them away, and the result is 0. + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (struct.new $struct.A + (i32.const 1) + (f64.const 2.2) + ) + ) + ) ) (module From ff8095d8d3be56ba249014ab799cbddb3fd3ba10 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 26 Jun 2024 11:19:04 -0700 Subject: [PATCH 416/553] [threads] Fuzz shared types in type fuzzer (#6704) Give the type fuzzer the ability to generate shared heap types when the shared-everything feature is enabled. It correctly ensures that shared structs and arrays cannot reference unshared heap types, but that unshared heap types can reference any heap type. Update the main fuzzer so that for the time being it never uses the shared-everything feature when generating additional heap types, so it never generates shared types. We can lift this restriction once the main fuzzer has been updated to properly handle shared types. As a drive-by, fix some logic for subtracting feature sets from each other that is used in this commit. --- src/tools/fuzzing/fuzzing.cpp | 5 +- src/tools/fuzzing/heap-types.cpp | 227 ++++++++++++++++++------------- src/tools/wasm-fuzz-types.cpp | 3 +- src/wasm-features.h | 5 +- test/lit/fuzz-types.test | 86 ++++++------ 5 files changed, 182 insertions(+), 144 deletions(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 6b54ac56dd9..555de5db148 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -246,8 +246,11 @@ void TranslateToFuzzReader::setupHeapTypes() { // For GC, also generate random types. if (wasm.features.hasGC()) { + // Do not generate shared types until the fuzzer can be updated to handle + // them. + auto features = wasm.features - FeatureSet::SharedEverything; auto generator = - HeapTypeGenerator::create(random, wasm.features, upTo(MAX_NEW_GC_TYPES)); + HeapTypeGenerator::create(random, features, upTo(MAX_NEW_GC_TYPES)); auto result = generator.builder.build(); if (auto* err = result.getError()) { Fatal() << "Failed to build heap types: " << err->reason << " at index " diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 127d4f5ba7a..a1c879b4286 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -62,8 +62,8 @@ struct HeapTypeGeneratorImpl { supertypeIndices(n), rand(rand), features(features) { // Set up the subtype relationships. Start with some number of root types, // then after that start creating subtypes of existing types. Determine the - // top-level kind of each type in advance so that we can appropriately use - // types we haven't constructed yet. + // top-level kind and shareability of each type in advance so that we can + // appropriately use types we haven't constructed yet. typeKinds.reserve(builder.size()); supertypeIndices.reserve(builder.size()); Index numRoots = 1 + rand.upTo(builder.size()); @@ -74,11 +74,14 @@ struct HeapTypeGeneratorImpl { if (i < numRoots || rand.oneIn(2)) { // This is a root type with no supertype. Choose a kind for this type. typeKinds.emplace_back(generateHeapTypeKind()); + builder[i].setShared( + !features.hasSharedEverything() || rand.oneIn(2) ? Unshared : Shared); } else { // This is a subtype. Choose one of the previous types to be the // supertype. Index super = rand.upTo(i); builder[i].subTypeOf(builder[super]); + builder[i].setShared(HeapType(builder[super]).getShared()); supertypeIndices[i] = super; subtypeIndices[super].push_back(i); typeKinds.push_back(typeKinds[super]); @@ -113,14 +116,15 @@ struct HeapTypeGeneratorImpl { // Create the heap types. for (; index < builder.size(); ++index) { auto kind = typeKinds[index]; + auto share = HeapType(builder[index]).getShared(); if (!supertypeIndices[index]) { // No nontrivial supertype, so create a root type. if (std::get_if(&kind)) { builder[index] = generateSignature(); } else if (std::get_if(&kind)) { - builder[index] = generateStruct(); + builder[index] = generateStruct(share); } else if (std::get_if(&kind)) { - builder[index] = generateArray(); + builder[index] = generateArray(share); } else { WASM_UNREACHABLE("unexpected kind"); } @@ -130,7 +134,7 @@ struct HeapTypeGeneratorImpl { if (supertype.isSignature()) { builder[index] = generateSubSignature(supertype.getSignature()); } else if (supertype.isStruct()) { - builder[index] = generateSubStruct(supertype.getStruct()); + builder[index] = generateSubStruct(supertype.getStruct(), share); } else if (supertype.isArray()) { builder[index] = generateSubArray(supertype.getArray()); } else { @@ -140,19 +144,25 @@ struct HeapTypeGeneratorImpl { } } - HeapType::BasicHeapType generateBasicHeapType() { + HeapType::BasicHeapType generateBasicHeapType(Shareability share) { // Choose bottom types more rarely. + // TODO: string, exn, and cont types if (rand.oneIn(16)) { - return rand.pick(HeapType::noext, HeapType::nofunc, HeapType::none); + HeapType ht = + rand.pick(HeapType::noext, HeapType::nofunc, HeapType::none); + return ht.getBasic(share); } - // TODO: string types - return rand.pick(HeapType::func, - HeapType::ext, - HeapType::any, - HeapType::eq, - HeapType::i31, - HeapType::struct_, - HeapType::array); + HeapType ht = rand.pick(HeapType::func, + HeapType::ext, + HeapType::any, + HeapType::eq, + HeapType::i31, + HeapType::struct_, + HeapType::array); + if (share == Unshared && features.hasSharedEverything() && rand.oneIn(2)) { + share = Shared; + } + return ht.getBasic(share); } Type::BasicType generateBasicType() { @@ -162,35 +172,47 @@ struct HeapTypeGeneratorImpl { .add(FeatureSet::SIMD, Type::v128)); } - HeapType generateHeapType() { + HeapType generateHeapType(Shareability share) { if (rand.oneIn(4)) { - return generateBasicHeapType(); - } else { - Index i = rand.upTo(recGroupEnds[index]); - return builder[i]; + return generateBasicHeapType(share); + } + if (share == Shared) { + // We can only reference other shared types. + std::vector eligible; + for (Index i = 0, n = recGroupEnds[index]; i < n; ++i) { + if (HeapType(builder[i]).getShared() == Shared) { + eligible.push_back(i); + } + } + if (eligible.empty()) { + return generateBasicHeapType(share); + } + return builder[rand.pick(eligible)]; } + // Any heap type can be referenced in an unshared context. + return builder[rand.upTo(recGroupEnds[index])]; } - Type generateRefType() { - auto heapType = generateHeapType(); + Type generateRefType(Shareability share) { + auto heapType = generateHeapType(share); auto nullability = rand.oneIn(2) ? Nullable : NonNullable; return builder.getTempRefType(heapType, nullability); } - Type generateSingleType() { + Type generateSingleType(Shareability share) { switch (rand.upTo(2)) { case 0: return generateBasicType(); case 1: - return generateRefType(); + return generateRefType(share); } WASM_UNREACHABLE("unexpected"); } - Type generateTupleType() { + Type generateTupleType(Shareability share) { std::vector types(2 + rand.upTo(MAX_TUPLE_SIZE - 1)); for (auto& type : types) { - type = generateSingleType(); + type = generateSingleType(share); } return builder.getTempTupleType(Tuple(types)); } @@ -199,55 +221,57 @@ struct HeapTypeGeneratorImpl { if (rand.oneIn(6)) { return Type::none; } else if (features.hasMultivalue() && rand.oneIn(5)) { - return generateTupleType(); + return generateTupleType(Unshared); } else { - return generateSingleType(); + return generateSingleType(Unshared); } } Signature generateSignature() { std::vector types(rand.upToSquared(MAX_PARAMS)); for (auto& type : types) { - type = generateSingleType(); + type = generateSingleType(Unshared); } auto params = builder.getTempTupleType(types); return {params, generateReturnType()}; } - Field generateField() { + Field generateField(Shareability share) { auto mutability = rand.oneIn(2) ? Mutable : Immutable; if (rand.oneIn(6)) { return {rand.oneIn(2) ? Field::i8 : Field::i16, mutability}; } else { - return {generateSingleType(), mutability}; + return {generateSingleType(share), mutability}; } } - Struct generateStruct() { + Struct generateStruct(Shareability share) { std::vector fields(rand.upTo(MAX_STRUCT_SIZE + 1)); for (auto& field : fields) { - field = generateField(); + field = generateField(share); } return {fields}; } - Array generateArray() { return {generateField()}; } + Array generateArray(Shareability share) { return {generateField(share)}; } - template std::vector getKindCandidates() { + template + std::vector getKindCandidates(Shareability share) { std::vector candidates; // Iterate through the top level kinds, finding matches for `Kind`. Since we // are constructing a child, we can only look through the end of the current // recursion group. for (Index i = 0, end = recGroupEnds[index]; i < end; ++i) { - if (std::get_if(&typeKinds[i])) { + if (std::get_if(&typeKinds[i]) && + share == HeapType(builder[i]).getShared()) { candidates.push_back(builder[i]); } } return candidates; } - template std::optional pickKind() { - auto candidates = getKindCandidates(); + template std::optional pickKind(Shareability share) { + auto candidates = getKindCandidates(share); if (candidates.size()) { return rand.pick(candidates); } else { @@ -255,65 +279,71 @@ struct HeapTypeGeneratorImpl { } } - HeapType pickSubFunc() { + HeapType pickSubFunc(Shareability share) { auto choice = rand.upTo(8); switch (choice) { case 0: - return HeapType::func; + return HeapTypes::func.getBasic(share); case 1: - return HeapType::nofunc; - default: - if (auto type = pickKind()) { + return HeapTypes::nofunc.getBasic(share); + default: { + if (auto type = pickKind(share)) { return *type; } - return (choice % 2) ? HeapType::func : HeapType::nofunc; + HeapType ht = (choice % 2) ? HeapType::func : HeapType::nofunc; + return ht.getBasic(share); + } } } - HeapType pickSubStruct() { + HeapType pickSubStruct(Shareability share) { auto choice = rand.upTo(8); switch (choice) { case 0: - return HeapType::struct_; + return HeapTypes::struct_.getBasic(share); case 1: - return HeapType::none; - default: - if (auto type = pickKind()) { + return HeapTypes::none.getBasic(share); + default: { + if (auto type = pickKind(share)) { return *type; } - return (choice % 2) ? HeapType::struct_ : HeapType::none; + HeapType ht = (choice % 2) ? HeapType::struct_ : HeapType::none; + return ht.getBasic(share); + } } } - HeapType pickSubArray() { + HeapType pickSubArray(Shareability share) { auto choice = rand.upTo(8); switch (choice) { case 0: - return HeapType::array; + return HeapTypes::array.getBasic(share); case 1: - return HeapType::none; - default: - if (auto type = pickKind()) { + return HeapTypes::none.getBasic(share); + default: { + if (auto type = pickKind(share)) { return *type; } - return (choice % 2) ? HeapType::array : HeapType::none; + HeapType ht = (choice % 2) ? HeapType::array : HeapType::none; + return ht.getBasic(share); + } } } - HeapType pickSubEq() { + HeapType pickSubEq(Shareability share) { auto choice = rand.upTo(16); switch (choice) { case 0: - return HeapType::eq; + return HeapTypes::eq.getBasic(share); case 1: - return HeapType::array; + return HeapTypes::array.getBasic(share); case 2: - return HeapType::struct_; + return HeapTypes::struct_.getBasic(share); case 3: - return HeapType::none; + return HeapTypes::none.getBasic(share); default: { - auto candidates = getKindCandidates(); - auto arrayCandidates = getKindCandidates(); + auto candidates = getKindCandidates(share); + auto arrayCandidates = getKindCandidates(share); candidates.insert( candidates.end(), arrayCandidates.begin(), arrayCandidates.end()); if (candidates.size()) { @@ -321,13 +351,13 @@ struct HeapTypeGeneratorImpl { } switch (choice >> 2) { case 0: - return HeapType::eq; + return HeapTypes::eq.getBasic(share); case 1: - return HeapType::array; + return HeapTypes::array.getBasic(share); case 2: - return HeapType::struct_; + return HeapTypes::struct_.getBasic(share); case 3: - return HeapType::none; + return HeapTypes::none.getBasic(share); default: WASM_UNREACHABLE("unexpected index"); } @@ -335,19 +365,20 @@ struct HeapTypeGeneratorImpl { } } - HeapType pickSubAny() { + HeapType pickSubAny(Shareability share) { switch (rand.upTo(8)) { case 0: - return HeapType::any; + return HeapTypes::any.getBasic(share); case 1: - return HeapType::none; + return HeapTypes::none.getBasic(share); default: - return pickSubEq(); + return pickSubEq(share); } WASM_UNREACHABLE("unexpected index"); } HeapType pickSubHeapType(HeapType type) { + auto share = type.getShared(); auto it = typeIndices.find(type); if (it != typeIndices.end()) { // This is a constructed type, so we know where its subtypes are, but we @@ -365,9 +396,9 @@ struct HeapTypeGeneratorImpl { if (rand.oneIn(candidates.size() * 8)) { auto* kind = &typeKinds[it->second]; if (std::get_if(kind)) { - return HeapType::nofunc; + return HeapTypes::nofunc.getBasic(share); } else { - return HeapType::none; + return HeapTypes::none.getBasic(share); } } return rand.pick(candidates); @@ -377,22 +408,21 @@ struct HeapTypeGeneratorImpl { if (rand.oneIn(8)) { return type.getBottom(); } - assert(!type.isShared() && "TODO: handle shared types"); switch (type.getBasic(Unshared)) { case HeapType::func: - return pickSubFunc(); + return pickSubFunc(share); case HeapType::cont: WASM_UNREACHABLE("not implemented"); case HeapType::any: - return pickSubAny(); + return pickSubAny(share); case HeapType::eq: - return pickSubEq(); + return pickSubEq(share); case HeapType::i31: - return HeapType::i31; + return HeapTypes::i31.getBasic(share); case HeapType::struct_: - return pickSubStruct(); + return pickSubStruct(share); case HeapType::array: - return pickSubArray(); + return pickSubArray(share); case HeapType::ext: case HeapType::exn: case HeapType::string: @@ -408,6 +438,7 @@ struct HeapTypeGeneratorImpl { } HeapType pickSuperHeapType(HeapType type) { + auto share = type.getShared(); std::vector candidates; auto it = typeIndices.find(type); if (it != typeIndices.end()) { @@ -420,17 +451,17 @@ struct HeapTypeGeneratorImpl { } auto* kind = &typeKinds[it->second]; if (std::get_if(kind)) { - candidates.push_back(HeapType::struct_); - candidates.push_back(HeapType::eq); - candidates.push_back(HeapType::any); + candidates.push_back(HeapTypes::struct_.getBasic(share)); + candidates.push_back(HeapTypes::eq.getBasic(share)); + candidates.push_back(HeapTypes::any.getBasic(share)); return rand.pick(candidates); } else if (std::get_if(kind)) { - candidates.push_back(HeapType::array); - candidates.push_back(HeapType::eq); - candidates.push_back(HeapType::any); + candidates.push_back(HeapTypes::array.getBasic(share)); + candidates.push_back(HeapTypes::eq.getBasic(share)); + candidates.push_back(HeapTypes::any.getBasic(share)); return rand.pick(candidates); } else if (std::get_if(kind)) { - candidates.push_back(HeapType::func); + candidates.push_back(HeapTypes::func.getBasic(share)); return rand.pick(candidates); } else { WASM_UNREACHABLE("unexpected kind"); @@ -439,7 +470,6 @@ struct HeapTypeGeneratorImpl { // This is not a constructed type, so it must be a basic type. assert(type.isBasic()); candidates.push_back(type); - assert(!type.isShared() && "TODO: handle shared types"); switch (type.getBasic(Unshared)) { case HeapType::ext: case HeapType::func: @@ -448,28 +478,28 @@ struct HeapTypeGeneratorImpl { case HeapType::any: break; case HeapType::eq: - candidates.push_back(HeapType::any); + candidates.push_back(HeapTypes::any.getBasic(share)); break; case HeapType::i31: case HeapType::struct_: case HeapType::array: - candidates.push_back(HeapType::eq); - candidates.push_back(HeapType::any); + candidates.push_back(HeapTypes::eq.getBasic(share)); + candidates.push_back(HeapTypes::any.getBasic(share)); break; case HeapType::string: - candidates.push_back(HeapType::any); + candidates.push_back(HeapTypes::any.getBasic(share)); break; case HeapType::none: - return pickSubAny(); + return pickSubAny(share); case HeapType::nofunc: - return pickSubFunc(); + return pickSubFunc(share); case HeapType::nocont: WASM_UNREACHABLE("not implemented"); case HeapType::noext: - candidates.push_back(HeapType::ext); + candidates.push_back(HeapTypes::ext.getBasic(share)); break; case HeapType::noexn: - candidates.push_back(HeapType::exn); + candidates.push_back(HeapTypes::exn.getBasic(share)); break; } assert(!candidates.empty()); @@ -552,7 +582,7 @@ struct HeapTypeGeneratorImpl { return {generateSubtype(super.type), Immutable}; } - Struct generateSubStruct(const Struct& super) { + Struct generateSubStruct(const Struct& super, Shareability share) { std::vector fields; // Depth subtyping for (auto field : super.fields) { @@ -561,7 +591,7 @@ struct HeapTypeGeneratorImpl { // Width subtyping Index extra = rand.upTo(MAX_STRUCT_SIZE + 1 - fields.size()); for (Index i = 0; i < extra; ++i) { - fields.push_back(generateField()); + fields.push_back(generateField(share)); } return {fields}; } @@ -900,6 +930,7 @@ std::vector Inhabitator::build() { } } builder[i].setOpen(types[i].isOpen()); + builder[i].setShared(types[i].getShared()); } auto built = builder.build(); diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp index 2be8aa5e7d7..ecd8883b118 100644 --- a/src/tools/wasm-fuzz-types.cpp +++ b/src/tools/wasm-fuzz-types.cpp @@ -262,9 +262,10 @@ void Fuzzer::checkCanonicalization() { } } - // Set finality + // Set finality and shareability for (size_t i = 0; i < types.size(); ++i) { builder[i].setOpen(types[i].isOpen()); + builder[i].setShared(types[i].getShared()); } // Set up recursion groups and record group ends to ensure we only select diff --git a/src/wasm-features.h b/src/wasm-features.h index cda3ce447ef..366b7520008 100644 --- a/src/wasm-features.h +++ b/src/wasm-features.h @@ -193,9 +193,12 @@ struct FeatureSet { return *this; } - FeatureSet operator-(FeatureSet& other) const { + FeatureSet operator-(const FeatureSet& other) const { return features & ~other.features; } + FeatureSet operator-(Feature other) const { + return *this - FeatureSet(other); + } uint32_t features; }; diff --git a/test/lit/fuzz-types.test b/test/lit/fuzz-types.test index ae5c0001900..10d8fe3bc93 100644 --- a/test/lit/fuzz-types.test +++ b/test/lit/fuzz-types.test @@ -1,60 +1,60 @@ -;; RUN: wasm-fuzz-types -v --seed=0 | filecheck %s +;; RUN: wasm-fuzz-types -v --seed=1 | filecheck %s -;; CHECK: Running with seed 0 +;; CHECK: Running with seed 1 ;; CHECK-NEXT: Built 20 types: ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (struct (field i32)))) -;; CHECK-NEXT: (type $1 (sub (func (param (ref $2)) (result externref)))) -;; CHECK-NEXT: (type $2 (sub (struct ))) +;; CHECK-NEXT: (type $0 (sub (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) +;; CHECK-NEXT: (type $1 (sub (func (param (ref $1)) (result f64 (ref $0) f32 (ref null (shared eq)))))) +;; CHECK-NEXT: (type $2 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))))))) +;; CHECK-NEXT: (type $3 (sub (shared (struct )))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $3 (sub $0 (struct (field i32) (field (ref $5)) (field (ref $5))))) -;; CHECK-NEXT: (type $4 (sub $3 (struct (field i32) (field (ref $5)) (field (ref $5)) (field i8) (field (ref null $13)) (field (mut i64))))) -;; CHECK-NEXT: (type $5 (sub (array (mut f64)))) -;; CHECK-NEXT: (type $6 (sub $1 (func (param anyref) (result externref)))) -;; CHECK-NEXT: (type $7 (sub final $2 (struct (field (mut (ref null $14))) (field (ref $3))))) -;; CHECK-NEXT: (type $8 (sub $1 (func (param (ref struct)) (result (ref extern))))) -;; CHECK-NEXT: (type $9 (sub $5 (array (mut f64)))) -;; CHECK-NEXT: (type $10 (sub final $8 (func (param (ref any)) (result (ref noextern))))) -;; CHECK-NEXT: (type $11 (sub (array (mut anyref)))) -;; CHECK-NEXT: (type $12 (sub $2 (struct (field (mut f64))))) -;; CHECK-NEXT: (type $13 (sub final $1 (func (param (ref $2)) (result (ref extern))))) -;; CHECK-NEXT: (type $14 (array (mut (ref null $14)))) +;; CHECK-NEXT: (type $4 (sub (array i32))) +;; CHECK-NEXT: (type $5 (sub $4 (array i32))) +;; CHECK-NEXT: (type $6 (shared (func (param (ref null $3)) (result i32)))) +;; CHECK-NEXT: (type $7 (sub $2 (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))) (field (mut (ref null $3))) (field (mut i16)) (field (mut (ref null $7))) (field (mut (ref null $7))))))) +;; CHECK-NEXT: (type $8 (sub $0 (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $15 (sub final $11 (array (mut anyref)))) -;; CHECK-NEXT: (type $16 (sub final $12 (struct (field (mut f64))))) -;; CHECK-NEXT: (type $17 (sub (struct (field f32) (field (mut i32)) (field i8) (field (ref array))))) -;; CHECK-NEXT: (type $18 (sub $11 (array (mut anyref)))) -;; CHECK-NEXT: (type $19 (sub final $9 (array (mut f64)))) +;; CHECK-NEXT: (type $9 (shared (array i32))) +;; CHECK-NEXT: (type $10 (sub $5 (array i32))) +;; CHECK-NEXT: (type $11 (func (result i32))) +;; CHECK-NEXT: (type $12 (sub (shared (array (ref $3))))) +;; CHECK-NEXT: (type $13 (sub (shared (func (param (ref null $19) v128) (result (ref null $12)))))) +;; CHECK-NEXT: (type $14 (sub final $12 (shared (array (ref $3))))) +;; CHECK-NEXT: (type $15 (sub (shared (func (param (ref null (shared struct)) i31ref) (result nullfuncref))))) +;; CHECK-NEXT: (type $16 (sub $5 (array i32))) +;; CHECK-NEXT: (type $17 (sub (func (param v128) (result f64)))) +;; CHECK-NEXT: (type $18 (sub (array (ref $11)))) +;; CHECK-NEXT: (type $19 (shared (array i8))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ;; CHECK-NEXT: Inhabitable types: ;; CHECK-NEXT: ;; CHECK-NEXT: Built 20 types: ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (struct (field i32)))) -;; CHECK-NEXT: (type $1 (sub (func (param (ref $2)) (result externref)))) -;; CHECK-NEXT: (type $2 (sub (struct ))) +;; CHECK-NEXT: (type $0 (sub (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) +;; CHECK-NEXT: (type $1 (sub (func (param (ref $1)) (result f64 (ref $0) f32 (ref null (shared eq)))))) +;; CHECK-NEXT: (type $2 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))))))) +;; CHECK-NEXT: (type $3 (sub (shared (struct )))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $3 (sub $0 (struct (field i32) (field (ref $5)) (field (ref $5))))) -;; CHECK-NEXT: (type $4 (sub $3 (struct (field i32) (field (ref $5)) (field (ref $5)) (field i8) (field (ref null $13)) (field (mut i64))))) -;; CHECK-NEXT: (type $5 (sub (array (mut f64)))) -;; CHECK-NEXT: (type $6 (sub $1 (func (param anyref) (result externref)))) -;; CHECK-NEXT: (type $7 (sub final $2 (struct (field (mut (ref null $14))) (field (ref $3))))) -;; CHECK-NEXT: (type $8 (sub $1 (func (param (ref struct)) (result (ref extern))))) -;; CHECK-NEXT: (type $9 (sub $5 (array (mut f64)))) -;; CHECK-NEXT: (type $10 (sub final $8 (func (param (ref any)) (result (ref noextern))))) -;; CHECK-NEXT: (type $11 (sub (array (mut anyref)))) -;; CHECK-NEXT: (type $12 (sub $2 (struct (field (mut f64))))) -;; CHECK-NEXT: (type $13 (sub final $1 (func (param (ref $2)) (result (ref extern))))) -;; CHECK-NEXT: (type $14 (array (mut (ref null $14)))) +;; CHECK-NEXT: (type $4 (sub (array i32))) +;; CHECK-NEXT: (type $5 (sub $4 (array i32))) +;; CHECK-NEXT: (type $6 (shared (func (param (ref null $3)) (result i32)))) +;; CHECK-NEXT: (type $7 (sub $2 (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))) (field (mut (ref null $3))) (field (mut i16)) (field (mut (ref null $7))) (field (mut (ref null $7))))))) +;; CHECK-NEXT: (type $8 (sub $0 (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $15 (sub final $11 (array (mut anyref)))) -;; CHECK-NEXT: (type $16 (sub final $12 (struct (field (mut f64))))) -;; CHECK-NEXT: (type $17 (sub (struct (field f32) (field (mut i32)) (field i8) (field (ref array))))) -;; CHECK-NEXT: (type $18 (sub $11 (array (mut anyref)))) -;; CHECK-NEXT: (type $19 (sub final $9 (array (mut f64)))) -) +;; CHECK-NEXT: (type $9 (shared (array i32))) +;; CHECK-NEXT: (type $10 (sub $5 (array i32))) +;; CHECK-NEXT: (type $11 (func (result i32))) +;; CHECK-NEXT: (type $12 (sub (shared (array (ref $3))))) +;; CHECK-NEXT: (type $13 (sub (shared (func (param (ref null $19) v128) (result (ref null $12)))))) +;; CHECK-NEXT: (type $14 (sub final $12 (shared (array (ref $3))))) +;; CHECK-NEXT: (type $15 (sub (shared (func (param (ref null (shared struct)) i31ref) (result nullfuncref))))) +;; CHECK-NEXT: (type $16 (sub $5 (array i32))) +;; CHECK-NEXT: (type $17 (sub (func (param v128) (result f64)))) +;; CHECK-NEXT: (type $18 (sub (array (ref $11)))) +;; CHECK-NEXT: (type $19 (shared (array i8))) +;; CHECK-NEXT: ) From 636d1b2af6f349a9c7fca908bad05108419835e3 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 26 Jun 2024 11:47:22 -0700 Subject: [PATCH 417/553] [threads] Ignore shared-array.wast in fuzzer initial contents (#6706) --- scripts/fuzz_opt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 192c0d362b6..4e1305042d9 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -355,6 +355,7 @@ def is_git_repo(): 'shared-types.wast', 'shared-polymorphism.wast', 'shared-struct.wast', + 'shared-array.wast', ] From 53712b6d6e93449a6faf18a55e0fb29022f158df Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 27 Jun 2024 10:25:05 -0700 Subject: [PATCH 418/553] [NFC] Add HeapType::getFeatures() (#6707) --- src/passes/StringLowering.cpp | 2 +- src/wasm-type.h | 3 + src/wasm/wasm-type.cpp | 176 +++++++++++++++++----------------- src/wasm/wasm-validator.cpp | 3 +- 4 files changed, 95 insertions(+), 89 deletions(-) diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index ca0ba773c76..f735b9ab222 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -283,7 +283,7 @@ struct StringLowering : public StringGathering { // explained we cannot do that - or before it, which is what we do here). for (auto& func : module->functions) { if (func->type.getRecGroup().size() != 1 || - !Type(func->type, Nullable).getFeatures().hasStrings()) { + !func->type.getFeatures().hasStrings()) { continue; } diff --git a/src/wasm-type.h b/src/wasm-type.h index 51d945b5373..69b50c07f26 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -451,6 +451,9 @@ class HeapType { // Return the LUB of two HeapTypes, which may or may not exist. static std::optional getLeastUpperBound(HeapType a, HeapType b); + // Returns the feature set required to use this type. + FeatureSet getFeatures() const; + // Helper allowing the value of `print(...)` to be sent to an ostream. Stores // a `TypeID` because `Type` is incomplete at this point and using a reference // makes it less convenient to use. diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 92c68d8bef0..6328180f81d 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -900,92 +900,7 @@ Type Type::reinterpret() const { FeatureSet Type::getFeatures() const { auto getSingleFeatures = [](Type t) -> FeatureSet { if (t.isRef()) { - // A reference type implies we need that feature. Some also require - // more, such as GC or exceptions, and may require us to look into child - // types. - struct ReferenceFeatureCollector - : HeapTypeChildWalker { - FeatureSet feats = FeatureSet::None; - - void noteChild(HeapType* heapType) { - if (heapType->isBasic()) { - switch (heapType->getBasic(Unshared)) { - case HeapType::ext: - case HeapType::func: - feats |= FeatureSet::ReferenceTypes; - return; - case HeapType::any: - case HeapType::eq: - case HeapType::i31: - case HeapType::struct_: - case HeapType::array: - feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; - return; - case HeapType::string: - feats |= FeatureSet::ReferenceTypes | FeatureSet::Strings; - return; - case HeapType::none: - case HeapType::noext: - case HeapType::nofunc: - // Technically introduced in GC, but used internally as part of - // ref.null with just reference types. - feats |= FeatureSet::ReferenceTypes; - return; - case HeapType::exn: - case HeapType::noexn: - feats |= - FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes; - return; - case HeapType::cont: - case HeapType::nocont: - feats |= FeatureSet::TypedContinuations; - return; - } - } - - if (heapType->getRecGroup().size() > 1 || - heapType->getDeclaredSuperType() || heapType->isOpen()) { - feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; - } - - if (heapType->isShared()) { - feats |= FeatureSet::SharedEverything; - } - - if (heapType->isStruct() || heapType->isArray()) { - feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; - } else if (heapType->isSignature()) { - // This is a function reference, which requires reference types and - // possibly also multivalue (if it has multiple returns). Note that - // technically typed function references also require GC, however, - // we use these types internally regardless of the presence of GC - // (in particular, since during load of the wasm we don't know the - // features yet, so we apply the more refined types), so we don't - // add that in any case here. - feats |= FeatureSet::ReferenceTypes; - auto sig = heapType->getSignature(); - if (sig.results.isTuple()) { - feats |= FeatureSet::Multivalue; - } - } else if (heapType->isContinuation()) { - feats |= FeatureSet::TypedContinuations; - } - - // In addition, scan their non-ref children, to add dependencies on - // things like SIMD. - for (auto child : heapType->getTypeChildren()) { - if (!child.isRef()) { - feats |= child.getFeatures(); - } - } - } - }; - - ReferenceFeatureCollector collector; - auto heapType = t.getHeapType(); - collector.walkRoot(&heapType); - collector.noteChild(&heapType); - return collector.feats; + return t.getHeapType().getFeatures(); } switch (t.getBasic()) { @@ -1604,6 +1519,95 @@ size_t HeapType::getRecGroupIndex() const { return getHeapTypeInfo(*this)->recGroupIndex; } +FeatureSet HeapType::getFeatures() const { + // Collects features from a type + children. + struct ReferenceFeatureCollector + : HeapTypeChildWalker { + FeatureSet feats = FeatureSet::None; + + void noteChild(HeapType* heapType) { + if (heapType->isBasic()) { + switch (heapType->getBasic(Unshared)) { + case HeapType::ext: + case HeapType::func: + feats |= FeatureSet::ReferenceTypes; + return; + case HeapType::any: + case HeapType::eq: + case HeapType::i31: + case HeapType::struct_: + case HeapType::array: + feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; + return; + case HeapType::string: + feats |= FeatureSet::ReferenceTypes | FeatureSet::Strings; + return; + case HeapType::none: + case HeapType::noext: + case HeapType::nofunc: + // Technically introduced in GC, but used internally as part of + // ref.null with just reference types. + feats |= FeatureSet::ReferenceTypes; + return; + case HeapType::exn: + case HeapType::noexn: + feats |= FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes; + return; + case HeapType::cont: + case HeapType::nocont: + feats |= FeatureSet::TypedContinuations; + return; + } + } + + if (heapType->getRecGroup().size() > 1 || + heapType->getDeclaredSuperType() || heapType->isOpen()) { + feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; + } + + if (heapType->isShared()) { + feats |= FeatureSet::SharedEverything; + } + + if (heapType->isStruct() || heapType->isArray()) { + feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; + } else if (heapType->isSignature()) { + // This is a function reference, which requires reference types and + // possibly also multivalue (if it has multiple returns). Note that + // technically typed function references also require GC, however, + // we use these types internally regardless of the presence of GC + // (in particular, since during load of the wasm we don't know the + // features yet, so we apply the more refined types), so we don't + // add that in any case here. + feats |= FeatureSet::ReferenceTypes; + auto sig = heapType->getSignature(); + if (sig.results.isTuple()) { + feats |= FeatureSet::Multivalue; + } + } else if (heapType->isContinuation()) { + feats |= FeatureSet::TypedContinuations; + } + + // In addition, scan their non-ref children, to add dependencies on + // things like SIMD. + for (auto child : heapType->getTypeChildren()) { + if (!child.isRef()) { + feats |= child.getFeatures(); + } + } + } + }; + + ReferenceFeatureCollector collector; + // For internal reasons, the walkRoot/noteChild APIs all require non-const + // pointers. We only use them to scan the type, so it is safe for us to + // send |this| there from a |const| method. + auto* unconst = const_cast(this); + collector.walkRoot(unconst); + collector.noteChild(unconst); + return collector.feats; +} + HeapType RecGroup::Iterator::operator*() const { if (parent->id & 1) { // This is a trivial recursion group. Mask off the low bit to recover the diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 281f3ec4599..a491fb951fd 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3389,8 +3389,7 @@ void FunctionValidator::visitFunction(Function* curr) { // Check for things like having a rec group with GC enabled. The type we're // checking is a reference type even if this an MVP function type, so ignore // the reference types feature here. - features |= - (Type(curr->type, Nullable).getFeatures() & ~FeatureSet::ReferenceTypes); + features |= (curr->type.getFeatures() & ~FeatureSet::ReferenceTypes); for (const auto& param : curr->getParams()) { features |= param.getFeatures(); shouldBeTrue(param.isConcrete(), curr, "params must be concretely typed"); From cdf8139a441c27c16eff02ccee65c463500fc00f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 27 Jun 2024 15:34:07 -0700 Subject: [PATCH 419/553] ConstantFieldPropagation: Add a variation that picks between 2 values using RefTest (#6692) CFP focuses on finding when a field always contains a constant, and then replaces a struct.get with that constant. If we find there are two constant values, then in some cases we can still optimize, if we have a way to pick between them. All we have is the struct.get and its reference, so we must use a ref.test: (struct.get $T x (..ref..)) => (select (..constant1..) (..constant2..) (ref.test $U (..ref..)) ) This is valid if, of all the subtypes of $T, those that pass the test have constant1 in that field, and those that fail the test have constant2. For example, a simple case is where $T has two subtypes, $T is never created itself, and each of the two subtypes has a different constant value. This is a somewhat risky operation, as ref.test is not necessarily cheap. To mitigate that, this is a new pass, --cfp-reftest that is not run by default, and also we only optimize when we can use a ref.test on what we think will be a final type (because ref.test on a final type can be faster in VMs). --- src/passes/ConstantFieldPropagation.cpp | 267 ++++- src/passes/pass.cpp | 3 + src/passes/passes.h | 1 + test/lit/help/wasm-opt.test | 3 + test/lit/help/wasm2js.test | 3 + test/lit/passes/cfp-reftest.wast | 1458 +++++++++++++++++++++++ test/lit/passes/cfp.wast | 4 + 7 files changed, 1723 insertions(+), 16 deletions(-) create mode 100644 test/lit/passes/cfp-reftest.wast diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp index e94da0ade8c..26cc8316b14 100644 --- a/src/passes/ConstantFieldPropagation.cpp +++ b/src/passes/ConstantFieldPropagation.cpp @@ -23,6 +23,30 @@ // write to that field of a different value (even using a subtype of T), then // anywhere we see a get of that field we can place a ref.func of F. // +// A variation of this pass also uses ref.test to optimize. This is riskier, as +// adding a ref.test means we are adding a non-trivial amount of work, and +// whether it helps overall depends on subsequent optimizations, so we do not do +// it by default. In this variation, if we inferred a field has exactly two +// possible values, and we can differentiate between them using a ref.test, then +// we do +// +// (struct.get $T x (..ref..)) +// => +// (select +// (..constant1..) +// (..constant2..) +// (ref.test $U (..ref..)) +// ) +// +// This is valid if, of all the subtypes of $T, those that pass the test have +// constant1 in that field, and those that fail the test have constant2. For +// example, a simple case is where $T has two subtypes, $T is never created +// itself, and each of the two subtypes has a different constant value. (Note +// that we do similar things in e.g. GlobalStructInference, where we turn a +// struct.get into a select, but the risk there is much lower since the +// condition for the select is something like a ref.eq - very cheap - while here +// we emit a ref.test which in general is as expensive as a cast.) +// // FIXME: This pass assumes a closed world. When we start to allow multi-module // wasm GC programs we need to check for type escaping. // @@ -34,6 +58,7 @@ #include "ir/struct-utils.h" #include "ir/utils.h" #include "pass.h" +#include "support/small_vector.h" #include "wasm-builder.h" #include "wasm-traversal.h" #include "wasm.h" @@ -73,17 +98,30 @@ struct FunctionOptimizer : public WalkerPass> { // Only modifies struct.get operations. bool requiresNonNullableLocalFixups() override { return false; } + // We receive the propagated infos, that is, info about field types in a form + // that takes into account subtypes for quick computation, and also the raw + // subtyping and new infos (information about struct.news). std::unique_ptr create() override { - return std::make_unique(infos); + return std::make_unique( + propagatedInfos, subTypes, rawNewInfos, refTest); } - FunctionOptimizer(PCVStructValuesMap& infos) : infos(infos) {} + FunctionOptimizer(const PCVStructValuesMap& propagatedInfos, + const SubTypes& subTypes, + const PCVStructValuesMap& rawNewInfos, + bool refTest) + : propagatedInfos(propagatedInfos), subTypes(subTypes), + rawNewInfos(rawNewInfos), refTest(refTest) {} void visitStructGet(StructGet* curr) { auto type = curr->ref->type; if (type == Type::unreachable) { return; } + auto heapType = type.getHeapType(); + if (!heapType.isStruct()) { + return; + } Builder builder(*getModule()); @@ -92,8 +130,8 @@ struct FunctionOptimizer : public WalkerPass> { // as if nothing was ever noted for that field. PossibleConstantValues info; assert(!info.hasNoted()); - auto iter = infos.find(type.getHeapType()); - if (iter != infos.end()) { + auto iter = propagatedInfos.find(heapType); + if (iter != propagatedInfos.end()) { // There is information on this type, fetch it. info = iter->second[curr->index]; } @@ -113,8 +151,13 @@ struct FunctionOptimizer : public WalkerPass> { return; } - // If the value is not a constant, then it is unknown and we must give up. + // If the value is not a constant, then it is unknown and we must give up + // on simply applying a constant. However, we can try to use a ref.test, if + // that is allowed. if (!info.isConstant()) { + if (refTest) { + optimizeUsingRefTest(curr); + } return; } @@ -122,16 +165,190 @@ struct FunctionOptimizer : public WalkerPass> { // ref.as_non_null (we need to trap as the get would have done so), plus the // constant value. (Leave it to further optimizations to get rid of the // ref.) - Expression* value = info.makeExpression(*getModule()); - auto field = GCTypeUtils::getField(type, curr->index); - assert(field); - value = - Bits::makePackedFieldGet(value, *field, curr->signed_, *getModule()); + auto* value = makeExpression(info, heapType, curr); replaceCurrent(builder.makeSequence( builder.makeDrop(builder.makeRefAs(RefAsNonNull, curr->ref)), value)); changed = true; } + // Given information about a constant value, and the struct type and StructGet + // that reads it, create an expression for that value. + Expression* makeExpression(const PossibleConstantValues& info, + HeapType type, + StructGet* curr) { + auto* value = info.makeExpression(*getModule()); + auto field = GCTypeUtils::getField(type, curr->index); + assert(field); + return Bits::makePackedFieldGet(value, *field, curr->signed_, *getModule()); + } + + void optimizeUsingRefTest(StructGet* curr) { + auto refType = curr->ref->type; + auto refHeapType = refType.getHeapType(); + + // We only handle immutable fields in this function, as we will be looking + // at |rawNewInfos|. That is, we are trying to see when a type and its + // subtypes have different values (so that we can differentiate between them + // using a ref.test), and those differences are lost in |propagatedInfos|, + // which has propagated to relevant types so that we can do a single check + // to see what value could be there. So we need to use something more + // precise, |rawNewInfos|, which tracks the values written to struct.news, + // where we know the type exactly (unlike with a struct.set). But for that + // reason the field must be immutable, so that it is valid to only look at + // the struct.news. (A more complex flow analysis could do better here, but + // would be far beyond the scope of this pass.) + if (GCTypeUtils::getField(refType, curr->index)->mutable_ == Mutable) { + return; + } + + // We seek two possible constant values. For each we track the constant and + // the types that have that constant. For example, if we have types A, B, C + // and A and B have 42 in their field, and C has 1337, then we'd have this: + // + // values = [ { 42, [A, B] }, { 1337, [C] } ]; + struct Value { + PossibleConstantValues constant; + // Use a SmallVector as we'll only have 2 Values, and so the stack usage + // here is fixed. + SmallVector types; + + // Whether this slot is used. If so, |constant| has a value, and |types| + // is not empty. + bool used() const { + if (constant.hasNoted()) { + assert(!types.empty()); + return true; + } + assert(types.empty()); + return false; + } + } values[2]; + + // Handle one of the subtypes of the relevant type. We check what value it + // has for the field, and update |values|. If we hit a problem, we mark us + // as having failed. + auto fail = false; + auto handleType = [&](HeapType type, Index depth) { + if (fail) { + // TODO: Add a mechanism to halt |iterSubTypes| in the middle, as once + // we fail there is no point to further iterating. + return; + } + + auto iter = rawNewInfos.find(type); + if (iter == rawNewInfos.end()) { + // This type has no struct.news, so we can ignore it: it is abstract. + return; + } + + auto value = iter->second[curr->index]; + if (!value.isConstant()) { + // The value here is not constant, so give up entirely. + fail = true; + return; + } + + // Consider the constant value compared to previous ones. + for (Index i = 0; i < 2; i++) { + if (!values[i].used()) { + // There is nothing in this slot: place this value there. + values[i].constant = value; + values[i].types.push_back(type); + break; + } + + // There is something in this slot. If we have the same value, append. + if (values[i].constant == value) { + values[i].types.push_back(type); + break; + } + + // Otherwise, this value is different than values[i], which is fine: + // we can add it as the second value in the next loop iteration - at + // least, we can do that if there is another iteration: If it's already + // the last, we've failed to find only two values. + if (i == 1) { + fail = true; + return; + } + } + }; + subTypes.iterSubTypes(refHeapType, handleType); + + if (fail) { + return; + } + + // We either filled slot 0, or we did not, and if we did not then cannot + // have filled slot 1 after it. + assert(values[0].used() || !values[1].used()); + + if (!values[1].used()) { + // We did not see two constant values (we might have seen just one, or + // even no constant values at all). + return; + } + + // We have exactly two values to pick between. We can pick between those + // values using a single ref.test if the two sets of types are actually + // disjoint. In general we could compute the LUB of each set and see if it + // overlaps with the other, but for efficiency we only want to do this + // optimization if the type we test on is closed/final, since ref.test on a + // final type can be fairly fast (perhaps constant time). We therefore look + // if one of the sets of types contains a single type and it is final, and + // if so then we'll test on it. (However, see a few lines below on how we + // test for finality.) + // TODO: Consider adding a variation on this pass that uses non-final types. + auto isProperTestType = [&](const Value& value) -> std::optional { + auto& types = value.types; + if (types.size() != 1) { + // Too many types. + return {}; + } + + auto type = types[0]; + // Do not test finality using isOpen(), as that may only be applied late + // in the optimization pipeline. We are in closed-world here, so just + // see if there are subtypes in practice (if not, this can be marked as + // final later, and we assume optimistically that it will). + if (!subTypes.getImmediateSubTypes(type).empty()) { + // There are subtypes. + return {}; + } + + // Success, we can test on this. + return type; + }; + + // Look for the index in |values| to test on. + Index testIndex; + if (auto test = isProperTestType(values[0])) { + testIndex = 0; + } else if (auto test = isProperTestType(values[1])) { + testIndex = 1; + } else { + // We failed to find a simple way to separate the types. + return; + } + + // Success! We can replace the struct.get with a select over the two values + // (and a trap on null) with the proper ref.test. + Builder builder(*getModule()); + + auto& testIndexTypes = values[testIndex].types; + assert(testIndexTypes.size() == 1); + auto testType = testIndexTypes[0]; + + auto* nnRef = builder.makeRefAs(RefAsNonNull, curr->ref); + + replaceCurrent(builder.makeSelect( + builder.makeRefTest(nnRef, Type(testType, NonNullable)), + makeExpression(values[testIndex].constant, refHeapType, curr), + makeExpression(values[1 - testIndex].constant, refHeapType, curr))); + + changed = true; + } + void doWalkFunction(Function* func) { WalkerPass>::doWalkFunction(func); @@ -143,7 +360,10 @@ struct FunctionOptimizer : public WalkerPass> { } private: - PCVStructValuesMap& infos; + const PCVStructValuesMap& propagatedInfos; + const SubTypes& subTypes; + const PCVStructValuesMap& rawNewInfos; + const bool refTest; bool changed = false; }; @@ -193,6 +413,11 @@ struct ConstantFieldPropagation : public Pass { // Only modifies struct.get operations. bool requiresNonNullableLocalFixups() override { return false; } + // Whether we are optimizing using ref.test, see above. + const bool refTest; + + ConstantFieldPropagation(bool refTest) : refTest(refTest) {} + void run(Module* module) override { if (!module->features.hasGC()) { return; @@ -214,8 +439,16 @@ struct ConstantFieldPropagation : public Pass { BoolStructValuesMap combinedCopyInfos; functionCopyInfos.combineInto(combinedCopyInfos); + // Prepare data we will need later. SubTypes subTypes(*module); + PCVStructValuesMap rawNewInfos; + if (refTest) { + // The refTest optimizations require the raw new infos (see above), but we + // can skip copying here if we'll never read this. + rawNewInfos = combinedNewInfos; + } + // Handle subtyping. |combinedInfo| so far contains data that represents // each struct.new and struct.set's operation on the struct type used in // that instruction. That is, if we do a struct.set to type T, the value was @@ -288,17 +521,19 @@ struct ConstantFieldPropagation : public Pass { // Optimize. // TODO: Skip this if we cannot optimize anything - FunctionOptimizer(combinedInfos).run(runner, module); - - // TODO: Actually remove the field from the type, where possible? That might - // be best in another pass. + FunctionOptimizer(combinedInfos, subTypes, rawNewInfos, refTest) + .run(runner, module); } }; } // anonymous namespace Pass* createConstantFieldPropagationPass() { - return new ConstantFieldPropagation(); + return new ConstantFieldPropagation(false); +} + +Pass* createConstantFieldPropagationRefTestPass() { + return new ConstantFieldPropagation(true); } } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index fd910609242..b226d6ec9ad 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -121,6 +121,9 @@ void PassRegistry::registerPasses() { registerPass("cfp", "propagate constant struct field values", createConstantFieldPropagationPass); + registerPass("cfp-reftest", + "propagate constant struct field values, using ref.test", + createConstantFieldPropagationRefTestPass); registerPass( "dce", "removes unreachable code", createDeadCodeEliminationPass); registerPass("dealign", diff --git a/src/passes/passes.h b/src/passes/passes.h index 02b164279a5..bd3aabf9f7e 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -32,6 +32,7 @@ Pass* createCodeFoldingPass(); Pass* createCodePushingPass(); Pass* createConstHoistingPass(); Pass* createConstantFieldPropagationPass(); +Pass* createConstantFieldPropagationRefTestPass(); Pass* createDAEPass(); Pass* createDAEOptimizingPass(); Pass* createDataFlowOptsPass(); diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 59409dcff70..76566049e62 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -103,6 +103,9 @@ ;; CHECK-NEXT: --cfp propagate constant struct field ;; CHECK-NEXT: values ;; CHECK-NEXT: +;; CHECK-NEXT: --cfp-reftest propagate constant struct field +;; CHECK-NEXT: values, using ref.test +;; CHECK-NEXT: ;; CHECK-NEXT: --coalesce-locals reduce # of locals by coalescing ;; CHECK-NEXT: ;; CHECK-NEXT: --coalesce-locals-learning reduce # of locals by coalescing diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 3c1da7ff2ab..8e305cfb91d 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -57,6 +57,9 @@ ;; CHECK-NEXT: --cfp propagate constant struct field ;; CHECK-NEXT: values ;; CHECK-NEXT: +;; CHECK-NEXT: --cfp-reftest propagate constant struct field +;; CHECK-NEXT: values, using ref.test +;; CHECK-NEXT: ;; CHECK-NEXT: --coalesce-locals reduce # of locals by coalescing ;; CHECK-NEXT: ;; CHECK-NEXT: --coalesce-locals-learning reduce # of locals by coalescing diff --git a/test/lit/passes/cfp-reftest.wast b/test/lit/passes/cfp-reftest.wast new file mode 100644 index 00000000000..c9fbbdc61a9 --- /dev/null +++ b/test/lit/passes/cfp-reftest.wast @@ -0,0 +1,1458 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --cfp-reftest -all -S -o - | filecheck %s + +;; When a struct.get can only read from two types, and those types have a +;; constant field, we can select between those two values using a ref.test. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + ;; Used below. + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $substruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Rather than load from the struct, we can test between the two types + ;; possible here. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but now the child is a final type. This does not matter as we +;; optimize either way, if the child has no children (since without children it +;; could be marked final later, which we assume). +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct (sub final $struct (struct (field i32) (field f64)))) + (type $substruct (sub final $struct (struct i32 f64))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $substruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but now the subtype has subtypes. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64)))) + (type $subsubstruct (sub $substruct (struct i32 f64))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + ;; Used below. + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (local $x (ref $subsubstruct)) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Keep this type alive. + (local $x (ref $subsubstruct)) + + ;; We only test on final types for efficiency, so we do not optimize here. + ;; The type we'd like to test on here has subtypes so it cannot be marked + ;; final; otherwise if there are no subtypes we assume it will be marked + ;; final later and optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but now one value is not constant. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func (param i32))) + + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) (param $x i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create (param $x i32) + (drop + (struct.new $struct + (local.get $x) ;; this changed + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We cannot optimize here. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but now the other value is not constant. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func (param i32))) + + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) (param $x i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create (param $x i32) + (drop + (struct.new $struct + (i32.const 10) ;; this changed + ) + ) + (drop + (struct.new $substruct + (local.get $x) ;; this changed + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We cannot optimize here. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Almost optimizable, but the field is mutable, so we can't. +(module + ;; CHECK: (type $struct (sub (struct (field (mut i32))))) + (type $struct (sub (struct (mut i32)))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct (sub $struct (struct (field (mut i32)) (field f64)))) + (type $substruct (sub $struct (struct (mut i32) f64))) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + ) + ;; CHECK: (func $get (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We cannot optimize here. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types (in a chain) with three values, 10, 20, 30. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64) (field anyref)))) + (type $subsubstruct (sub $substruct (struct i32 f64 anyref))) + + ;; CHECK: (type $3 (func)) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (type $5 (func (param (ref null $substruct)) (result i32))) + + ;; CHECK: (func $create (type $3) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subsubstruct + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $subsubstruct + (i32.const 30) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Three types are possible here, with three different values, so we do not + ;; optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) + + ;; CHECK: (func $get-sub (type $5) (param $substruct (ref null $substruct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (ref.test (ref $subsubstruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $substruct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-sub (param $substruct (ref null $substruct)) (result i32) + ;; Only two types are relevant here, so we do optimize. + (struct.get $substruct 0 + (local.get $substruct) + ) + ) +) + +;; Three types with two values, 10, 20, 20. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64) (field anyref)))) + (type $subsubstruct (sub $substruct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subsubstruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $subsubstruct + (i32.const 20) ;; this changed + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Three types are possible here, but two have the same value, and we can + ;; differentiate between them with a test. However, the test would be on + ;; $substruct, which is not a final type, so we do not optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types with two values, but non-consecutive: 20, 10, 20. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64) (field anyref)))) + (type $subsubstruct (sub $substruct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subsubstruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 20) ;; this changed + ) + ) + (drop + (struct.new $substruct + (i32.const 10) ;; this changed + (f64.const 3.14159) + ) + ) + (drop + (struct.new $subsubstruct + (i32.const 20) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Three types are possible here, and two have the same value, but we still + ;; cannot optimize: the chain of types has values A->B->A so there is no + ;; ref.test that can differentiate the two sets. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types with two values, 10, 10, 20. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64) (field anyref)))) + (type $subsubstruct (sub $substruct (struct i32 f64 anyref))) + + ;; CHECK: (type $3 (func)) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $3) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subsubstruct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) ;; this changed + ) + ) + (drop + (struct.new $substruct + (i32.const 10) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $subsubstruct + (i32.const 20) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $subsubstruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can differentiate between the first 2 and the last 1 by testing on the + ;; last, so we can optimize here. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types with two values and an abstract type. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) + (type $substruct (sub $struct (struct i32 f64))) + + ;; CHECK: (type $subsubstruct (sub $substruct (struct (field i32) (field f64) (field anyref)))) + (type $subsubstruct (sub $substruct (struct i32 f64 anyref))) + + ;; CHECK: (type $3 (func)) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $3) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subsubstruct + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + ;; We never create $substruct, so it doesn't matter (we use a local to + ;; keep it alive). + (drop + (struct.new $subsubstruct + (i32.const 30) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $subsubstruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can optimize since only two types are actually possible. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types with three values, now in a triangle. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const -20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct.A + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $substruct.B + (i32.const -20) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; Three types are possible here, with three different values, so we do not + ;; optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Three types in a triangle, with only two values. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct.A + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $substruct.B + (i32.const 20) ;; this changed + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; There is no ref.test that can separate the parent from the two children, + ;; so we cannot optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but the singular value is moved. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 20) ;; this changed + ) + ) + (drop + (struct.new $substruct.A + (i32.const 10) ;; this changed + (f64.const 3.14159) + ) + ) + (drop + (struct.new $substruct.B + (i32.const 20) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (ref.test (ref $substruct.A) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can ref.test on $substruct.A now, and optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; As above, but the singular value is moved again. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $struct + (i32.const 20) + ) + ) + (drop + (struct.new $substruct.A + (i32.const 20) ;; this changed + (f64.const 3.14159) + ) + ) + (drop + (struct.new $substruct.B + (i32.const 10) ;; this changed + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (ref.test (ref $substruct.B) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can ref.test on $substruct.B now, and optimize. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; A triangle with an abstract type at the top. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (local $keepalive (ref $struct)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (local $keepalive (ref $struct)) + ;; $struct is never created. + (drop + (struct.new $substruct.A + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $substruct.B + (i32.const 30) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (ref.test (ref $substruct.A) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can optimize here as only two types are non-abstract, and picking + ;; between the two siblings is easy. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; A triangle with an abstract type in a sibling. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (local $keepalive (ref $substruct.A)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.B + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (local $keepalive (ref $substruct.A)) + (drop + (struct.new $struct + (i32.const 10) + ) + ) + ;; $substruct.A is never created. + (drop + (struct.new $substruct.B + (i32.const 30) + (f64.const 3.14159) + (ref.null any) + ) + ) + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $substruct.B) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can optimize here as only two types are non-abstract, and we can test + ;; on the non-abstract sibling. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; A triangle with an abstract type in the other sibling. +(module + ;; CHECK: (type $struct (sub (struct (field i32)))) + (type $struct (sub (struct i32))) + ;; CHECK: (type $substruct.A (sub $struct (struct (field i32) (field f64)))) + (type $substruct.A (sub $struct (struct i32 f64))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $substruct.B (sub $struct (struct (field i32) (field f64) (field anyref)))) + (type $substruct.B (sub $struct (struct i32 f64 anyref))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (local $keepalive (ref $substruct.B)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct.A + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (local $keepalive (ref $substruct.B)) + (drop + (struct.new $struct + (i32.const 10) + ) + ) + (drop + (struct.new $substruct.A + (i32.const 20) + (f64.const 3.14159) + ) + ) + ;; $substruct.B is never created. + ) + ;; CHECK: (func $get (type $4) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $substruct.A) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get (param $struct (ref null $struct)) (result i32) + ;; We can optimize here as only two types are non-abstract, and we can test + ;; on the non-abstract sibling. + (struct.get $struct 0 + (local.get $struct) + ) + ) +) + +;; Several fields and several news. +(module + ;; CHECK: (type $struct (sub (struct (field i32) (field i64) (field f64) (field f32)))) + (type $struct (sub (struct i32 i64 f64 f32))) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field i64) (field f64) (field f32)))) + (type $substruct (sub $struct (struct i32 i64 f64 f32))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $3 (func (param (ref null $struct)) (result i32))) + + ;; CHECK: (type $4 (func (param (ref null $struct)) (result i64))) + + ;; CHECK: (type $5 (func (param (ref null $struct)) (result f64))) + + ;; CHECK: (type $6 (func (param (ref null $struct)) (result f32))) + + ;; CHECK: (func $create (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i64.const 20) + ;; CHECK-NEXT: (f64.const 30.3) + ;; CHECK-NEXT: (f32.const 40.400001525878906) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i64.const 22) + ;; CHECK-NEXT: (f64.const 36.36) + ;; CHECK-NEXT: (f32.const 40.79999923706055) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $substruct + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i64.const 22) + ;; CHECK-NEXT: (f64.const 30.3) + ;; CHECK-NEXT: (f32.const 40.79999923706055) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + ;; The first new is for $struct, the last two for $substruct. + ;; The first two news agree on field 0; the last two on fields 1&3; and the + ;; first and last on field 2. As a result, we can optimize only fields 1&3. + ;; field. + (drop + (struct.new $struct + (i32.const 10) + (i64.const 20) + (f64.const 30.3) + (f32.const 40.4) + ) + ) + (drop + (struct.new $substruct + (i32.const 10) + (i64.const 22) + (f64.const 36.36) + (f32.const 40.8) + ) + ) + (drop + (struct.new $substruct + (i32.const 11) + (i64.const 22) + (f64.const 30.3) + (f32.const 40.8) + ) + ) + ) + ;; CHECK: (func $get-0 (type $3) (param $struct (ref null $struct)) (result i32) + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-0 (param $struct (ref null $struct)) (result i32) + (struct.get $struct 0 + (local.get $struct) + ) + ) + + ;; CHECK: (func $get-1 (type $4) (param $struct (ref null $struct)) (result i64) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i64.const 22) + ;; CHECK-NEXT: (i64.const 20) + ;; CHECK-NEXT: (ref.test (ref $substruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-1 (param $struct (ref null $struct)) (result i64) + (struct.get $struct 1 + (local.get $struct) + ) + ) + + ;; CHECK: (func $get-2 (type $5) (param $struct (ref null $struct)) (result f64) + ;; CHECK-NEXT: (struct.get $struct 2 + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-2 (param $struct (ref null $struct)) (result f64) + (struct.get $struct 2 + (local.get $struct) + ) + ) + + ;; CHECK: (func $get-3 (type $6) (param $struct (ref null $struct)) (result f32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (f32.const 40.79999923706055) + ;; CHECK-NEXT: (f32.const 40.400001525878906) + ;; CHECK-NEXT: (ref.test (ref $substruct) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-3 (param $struct (ref null $struct)) (result f32) + (struct.get $struct 3 + (local.get $struct) + ) + ) +) + +;; Three top-level struct hierarchies. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct (field i32)))) + (type $A (sub (struct i32))) + ;; CHECK: (type $subA (sub $A (struct (field i32) (field f64)))) + (type $subA (sub $A (struct i32 f64))) + + ;; CHECK: (type $B (sub (struct (field i32)))) + (type $B (sub (struct i32))) + + ;; CHECK: (type $subB (sub $B (struct (field i32) (field f64)))) + (type $subB (sub $B (struct i32 f64))) + + ;; CHECK: (type $C (sub (struct (field i32)))) + (type $C (sub (struct i32))) + + ;; CHECK: (type $subC (sub $C (struct (field i32) (field f64)))) + (type $subC (sub $C (struct i32 f64))) + ) + + ;; CHECK: (type $6 (func)) + + ;; CHECK: (type $7 (func (param (ref null $A)) (result i32))) + + ;; CHECK: (type $8 (func (param (ref null $B)) (result i32))) + + ;; CHECK: (type $9 (func (param (ref null $C)) (result i32))) + + ;; CHECK: (func $create (type $6) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $A + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subA + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $B + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subB + ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: (f64.const 2.61828) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $C + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.const 1000) + ;; CHECK-NEXT: (i32.const 2000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $subC + ;; CHECK-NEXT: (i32.const 50) + ;; CHECK-NEXT: (f64.const 999999.9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $create + (drop + (struct.new $A + (i32.const 10) + ) + ) + (drop + (struct.new $subA + (i32.const 20) + (f64.const 3.14159) + ) + ) + (drop + (struct.new $B + (i32.const 30) + ) + ) + (drop + (struct.new $subB + (i32.const 40) + (f64.const 2.61828) + ) + ) + (drop + (struct.new $C + ;; Something not constant enough for us to reason about + (i32.add + (i32.const 1000) + (i32.const 2000) + ) + ) + ) + (drop + (struct.new $subC + (i32.const 50) + (f64.const 999999.9) + ) + ) + ) + ;; CHECK: (func $get-A (type $7) (param $A (ref null $A)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (ref.test (ref $subA) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $A) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-A (param $A (ref null $A)) (result i32) + ;; We can optimize here, picking 10 or 20. + (struct.get $A 0 + (local.get $A) + ) + ) + + ;; CHECK: (func $get-B (type $8) (param $B (ref null $B)) (result i32) + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: (ref.test (ref $subB) + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: (local.get $B) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-B (param $B (ref null $B)) (result i32) + ;; We can optimize here, picking 30 or 40. + (struct.get $B 0 + (local.get $B) + ) + ) + + ;; CHECK: (func $get-C (type $9) (param $C (ref null $C)) (result i32) + ;; CHECK-NEXT: (struct.get $C 0 + ;; CHECK-NEXT: (local.get $C) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get-C (param $C (ref null $C)) (result i32) + ;; We can't optimize here. + (struct.get $C 0 + (local.get $C) + ) + ) +) diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index 0cc1d8c00dc..c3bc81a1bcf 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -767,6 +767,10 @@ ;; Subtyping: Create both a subtype and a supertype, with different constants ;; for the shared field, preventing optimization, as a get of the ;; supertype may receive an instance of the subtype. +;; +;; Note that this may be optimized using a ref.test, in --cfp-reftest, but not +;; in --cfp. This gives us coverage that --cfp does not do the things that +;; --cfp-reftest does (how --cfp-reftest works is tested in cfp-reftest.wast). (module ;; CHECK: (type $struct (sub (struct (field i32)))) (type $struct (sub (struct i32))) From 9792f2c1fd311c3ffd2036288c6e7614a0486481 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Jul 2024 15:42:39 -0700 Subject: [PATCH 420/553] [DebugInfo] Add debug info to the values emitted in GlobalStructInference (#6709) Previously the replacement select got the debug info, but we should also copy it to the values, as often optimizations lead to one of those values remaining by itself. Similar to #6652 in general form. --- src/passes/GlobalStructInference.cpp | 38 +++++++++------ test/lit/passes/gsi-debug.wast | 73 ++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 test/lit/passes/gsi-debug.wast diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index 0ddbe9b0f51..7526cdb76b0 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -50,6 +50,7 @@ #include +#include "ir/debuginfo.h" #include "ir/find_all.h" #include "ir/module-utils.h" #include "ir/names.h" @@ -417,29 +418,36 @@ struct GlobalStructInference : public Pass { // Helper for optimization: Given a Value, returns what we should read // for it. auto getReadValue = [&](const Value& value) -> Expression* { + Expression* ret; if (value.isConstant()) { // This is known to be a constant, so simply emit an expression for // that constant. - return value.getConstant().makeExpression(wasm); - } + ret = value.getConstant().makeExpression(wasm); + } else { + // Otherwise, this is non-constant, so we are in the situation where + // we want to un-nest the value out of the struct.new it is in. Note + // that for later work, as we cannot add a global in parallel. - // Otherwise, this is non-constant, so we are in the situation where - // we want to un-nest the value out of the struct.new it is in. Note - // that for later work, as we cannot add a global in parallel. + // There can only be one global in a value that is not constant, + // which is the global we want to read from. + assert(value.globals.size() == 1); - // There can only be one global in a value that is not constant, which - // is the global we want to read from. - assert(value.globals.size() == 1); + // Create a global.get with temporary name, leaving only the + // updating of the name to later work. + auto* get = builder.makeGlobalGet(value.globals[0], + value.getExpression()->type); - // Create a global.get with temporary name, leaving only the updating - // of the name to later work. - auto* get = builder.makeGlobalGet(value.globals[0], - value.getExpression()->type); + globalsToUnnest.emplace_back( + GlobalToUnnest{value.globals[0], fieldIndex, get}); + + ret = get; + } - globalsToUnnest.emplace_back( - GlobalToUnnest{value.globals[0], fieldIndex, get}); + // This value replaces the struct.get, so it should have the same + // source location. + debuginfo::copyOriginalToReplacement(curr, ret, getFunction()); - return get; + return ret; }; // We have some globals (at least 2), and so must have at least one diff --git a/test/lit/passes/gsi-debug.wast b/test/lit/passes/gsi-debug.wast new file mode 100644 index 00000000000..a55ea3e8ea9 --- /dev/null +++ b/test/lit/passes/gsi-debug.wast @@ -0,0 +1,73 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: env BINARYEN_PRINT_FULL=1 foreach %s %t wasm-opt --gsi -all --closed-world -S -o - | filecheck %s + +;; Test that debug info is copied to the values we replace a struct.get with. +;; We use BINARYEN_PRINT_FULL=1 here because the select that contains the +;; values also gets that debug info, and normally we omit debug info of children +;; when it matches the parent (so we could not tell without +;; BINARYEN_PRINT_FULL=1 whether the children had the debug info or not). +;; (Another way to test this would be to run a followup optimization to remove +;; the select, but that would be more complex.) + +(module + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32)) + + ;; CHECK: (type $1 (func (param (ref null $struct)))) + + ;; CHECK: (global $global1 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.const 42) (; i32 ;) + ;; CHECK-NEXT: )) + (global $global1 (ref $struct) (struct.new $struct + (i32.const 42) + )) + + ;; CHECK: (global $global2 (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i32.const 1337) (; i32 ;) + ;; CHECK-NEXT: )) + (global $global2 (ref $struct) (struct.new $struct + (i32.const 1337) + )) + + ;; A non-reference global does not confuse us. + ;; CHECK: (global $global-other i32 (i32.const 123456)) + (global $global-other i32 (i32.const 123456)) + + ;; CHECK: (func $test (type $1) (param $struct (ref null $struct)) + ;; CHECK-NEXT: ;;@ drop.c:10:1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: ;;@ struct.c:20:2 + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: ;;@ struct.c:20:2 + ;; CHECK-NEXT: (i32.const 42) (; i32 ;) + ;; CHECK-NEXT: ;;@ struct.c:20:2 + ;; CHECK-NEXT: (i32.const 1337) (; i32 ;) + ;; CHECK-NEXT: ;;@ + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: ;;@ + ;; CHECK-NEXT: (ref.as_non_null + ;; CHECK-NEXT: ;;@ local.c:30:3 + ;; CHECK-NEXT: (local.get $struct) (; struct null ;) + ;; CHECK-NEXT: ) (; struct ;) + ;; CHECK-NEXT: ;;@ + ;; CHECK-NEXT: (global.get $global1) (; struct ;) + ;; CHECK-NEXT: ) (; i32 ;) + ;; CHECK-NEXT: ) (; i32 ;) + ;; CHECK-NEXT: ) (; none ;) + ;; CHECK-NEXT: ) + (func $test (param $struct (ref null $struct)) + ;; We can infer that this get can reference either $global1 or $global2, + ;; and nothing else (aside from a null), and can emit a select between + ;; those values. While doing so we copy the debug info as well to the + ;; values in the select. + ;;@ drop.c:10:1 + (drop + ;;@ struct.c:20:2 + (struct.get $struct 0 + ;;@ local.c:30:3 + (local.get $struct) + ) + ) + ) +) + From 81f8f770a1b2adc027cbbbd981781d2ee6952e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Mon, 8 Jul 2024 16:23:00 -0400 Subject: [PATCH 421/553] Rename external conversion instructions (#6716) Rename instructions `extern.internalize` into `any.convert_extern` and `extern.externalize` into `extern.convert_any` to follow more closely the spec. This was changed in https://github.com/WebAssembly/gc/issues/432. The legacy name is still accepted in text inputs and in the C and JS APIs. --- scripts/clang-tidy-diff.sh | 2 +- scripts/gen-s-parser.py | 6 ++- src/binaryen-c.cpp | 6 ++- src/binaryen-c.h | 2 + src/gen-s-parser.inc | 16 +++++++- src/ir/child-typer.h | 4 +- src/ir/effects.h | 2 +- src/ir/possible-contents.cpp | 2 +- src/ir/properties.cpp | 2 +- src/ir/properties.h | 8 ++-- src/js/binaryen.js-post.js | 6 ++- src/passes/OptimizeCasts.cpp | 2 +- src/passes/OptimizeInstructions.cpp | 2 +- src/passes/Print.cpp | 8 ++-- src/passes/TypeGeneralizing.cpp | 4 +- src/tools/wasm-ctor-eval.cpp | 2 +- src/wasm-binary.h | 4 +- src/wasm-builder.h | 2 +- src/wasm-interpreter.h | 6 +-- src/wasm.h | 4 +- src/wasm/wasm-binary.cpp | 12 +++--- src/wasm/wasm-stack.cpp | 8 ++-- src/wasm/wasm-validator.cpp | 12 +++--- src/wasm/wasm.cpp | 4 +- test/binaryen.js/expressions.js | 4 +- test/example/c-api-kitchen-sink.c | 4 +- test/example/c-api-kitchen-sink.txt | 4 +- test/lit/ctor-eval/extern.wast | 12 +++--- test/lit/exec/i31.wast | 2 +- test/lit/extern-conversions.wast | 39 ++++++++++++++----- test/lit/passes/gufa-extern.wast | 16 ++++---- .../optimize-instructions-gc-extern.wast | 20 +++++----- test/lit/passes/optimize-instructions-gc.wast | 4 +- test/lit/passes/type-generalizing.wast | 16 ++++---- test/lit/passes/type-ssa.wast | 16 ++++---- test/lit/wat-kitchen-sink.wast | 8 ++-- test/spec/ref_test.wast | 12 +++--- 37 files changed, 161 insertions(+), 122 deletions(-) diff --git a/scripts/clang-tidy-diff.sh b/scripts/clang-tidy-diff.sh index 632968a3886..17a6a4687ea 100755 --- a/scripts/clang-tidy-diff.sh +++ b/scripts/clang-tidy-diff.sh @@ -24,7 +24,7 @@ function realpath() { CLANG_DIR=$(dirname $(dirname $(realpath $CLANG_TIDY))) CLANG_TIDY_DIFF=$CLANG_DIR/share/clang/clang-tidy-diff.py -ARG="-quiet -p1 -iregex=src/.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)" +ARG="-quiet -p1 -iregex=src/.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm)" if [ ! -e "$CLANG_TIDY_DIFF" ]; then echo "Failed to find clang-tidy-diff.py ($CLANG_TIDY_DIFF)" exit 1 diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 2aa158c59ec..43a85c636ed 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -603,8 +603,10 @@ ("array.init_data", "makeArrayInitData()"), ("array.init_elem", "makeArrayInitElem()"), ("ref.as_non_null", "makeRefAs(RefAsNonNull)"), - ("extern.internalize", "makeRefAs(ExternInternalize)"), - ("extern.externalize", "makeRefAs(ExternExternalize)"), + ("extern.internalize", "makeRefAs(AnyConvertExtern)"), # Deprecated + ("extern.externalize", "makeRefAs(ExternConvertAny)"), # Deprecated + ("any.convert_extern", "makeRefAs(AnyConvertExtern)"), + ("extern.convert_any", "makeRefAs(ExternConvertAny)"), ("string.new_lossy_utf8_array", "makeStringNew(StringNewLossyUTF8Array)"), ("string.new_wtf16_array", "makeStringNew(StringNewWTF16Array)"), ("string.from_code_point", "makeStringNew(StringNewFromCodePoint)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 841fa61eef7..9c9a1c54f33 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1012,8 +1012,10 @@ BinaryenOp BinaryenDotI8x16I7x16SToVecI16x8(void) { return DotI8x16I7x16SToVecI16x8; } BinaryenOp BinaryenRefAsNonNull(void) { return RefAsNonNull; } -BinaryenOp BinaryenRefAsExternInternalize(void) { return ExternInternalize; } -BinaryenOp BinaryenRefAsExternExternalize(void) { return ExternExternalize; } +BinaryenOp BinaryenRefAsExternInternalize(void) { return AnyConvertExtern; } +BinaryenOp BinaryenRefAsExternExternalize(void) { return ExternConvertAny; } +BinaryenOp BinaryenRefAsAnyConvertExtern(void) { return AnyConvertExtern; } +BinaryenOp BinaryenRefAsExternConvertAny(void) { return ExternConvertAny; } BinaryenOp BinaryenBrOnNull(void) { return BrOnNull; } BinaryenOp BinaryenBrOnNonNull(void) { return BrOnNonNull; } BinaryenOp BinaryenBrOnCast(void) { return BrOnCast; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 3f2cab20c08..45230a1175e 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -678,6 +678,8 @@ BINARYEN_API BinaryenOp BinaryenDotI8x16I7x16SToVecI16x8(void); BINARYEN_API BinaryenOp BinaryenRefAsNonNull(void); BINARYEN_API BinaryenOp BinaryenRefAsExternInternalize(void); BINARYEN_API BinaryenOp BinaryenRefAsExternExternalize(void); +BINARYEN_API BinaryenOp BinaryenRefAsAnyConvertExtern(void); +BINARYEN_API BinaryenOp BinaryenRefAsExternConvertAny(void); BINARYEN_API BinaryenOp BinaryenBrOnNull(void); BINARYEN_API BinaryenOp BinaryenBrOnNonNull(void); BINARYEN_API BinaryenOp BinaryenBrOnCast(void); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 03b346113e1..8a3dcba0be2 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -14,6 +14,12 @@ memcpy(buf, op.data(), op.size()); switch (buf[0]) { case 'a': { switch (buf[1]) { + case 'n': + if (op == "any.convert_extern"sv) { + CHECK_ERR(makeRefAs(ctx, pos, annotations, AnyConvertExtern)); + return Ok{}; + } + goto parse_error; case 'r': { switch (buf[6]) { case 'c': @@ -278,15 +284,21 @@ switch (buf[0]) { } case 'e': { switch (buf[7]) { + case 'c': + if (op == "extern.convert_any"sv) { + CHECK_ERR(makeRefAs(ctx, pos, annotations, ExternConvertAny)); + return Ok{}; + } + goto parse_error; case 'e': if (op == "extern.externalize"sv) { - CHECK_ERR(makeRefAs(ctx, pos, annotations, ExternExternalize)); + CHECK_ERR(makeRefAs(ctx, pos, annotations, ExternConvertAny)); return Ok{}; } goto parse_error; case 'i': if (op == "extern.internalize"sv) { - CHECK_ERR(makeRefAs(ctx, pos, annotations, ExternInternalize)); + CHECK_ERR(makeRefAs(ctx, pos, annotations, AnyConvertExtern)); return Ok{}; } goto parse_error; diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 7c09dddb072..5e2dc237dfc 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -949,10 +949,10 @@ template struct ChildTyper : OverriddenVisitor { case RefAsNonNull: noteAnyReference(&curr->value); return; - case ExternInternalize: + case AnyConvertExtern: note(&curr->value, Type(HeapType::ext, Nullable)); return; - case ExternExternalize: + case ExternConvertAny: note(&curr->value, Type(HeapType::any, Nullable)); return; } diff --git a/src/ir/effects.h b/src/ir/effects.h index 46138d03c0f..be949a8bf57 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -926,7 +926,7 @@ class EffectAnalyzer { void visitArrayInitData(ArrayInitData* curr) { visitArrayInit(curr); } void visitArrayInitElem(ArrayInitElem* curr) { visitArrayInit(curr); } void visitRefAs(RefAs* curr) { - if (curr->op == ExternInternalize || curr->op == ExternExternalize) { + if (curr->op == AnyConvertExtern || curr->op == ExternConvertAny) { // These conversions are infallible. return; } diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index ac320c4192a..38fa3e5f6cf 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -697,7 +697,7 @@ struct InfoCollector receiveChildValue(curr->ref, curr); } void visitRefAs(RefAs* curr) { - if (curr->op == ExternExternalize || curr->op == ExternInternalize) { + if (curr->op == ExternConvertAny || curr->op == AnyConvertExtern) { // The external conversion ops emit something of a completely different // type, which we must mark as a root. addRoot(curr); diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp index dd9a10a8ee0..d047718850c 100644 --- a/src/ir/properties.cpp +++ b/src/ir/properties.cpp @@ -65,7 +65,7 @@ static bool isValidInConstantExpression(Module& wasm, Expression* expr) { } if (auto* refAs = expr->dynCast()) { - if (refAs->op == ExternExternalize || refAs->op == ExternInternalize) { + if (refAs->op == ExternConvertAny || refAs->op == AnyConvertExtern) { return true; } } diff --git a/src/ir/properties.h b/src/ir/properties.h index 4b73b72116f..ccb2392b0c1 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -83,7 +83,7 @@ inline bool isNamedControlFlow(Expression* curr) { // isValidInConstantExpression or find better names(#4845) inline bool isSingleConstantExpression(const Expression* curr) { if (auto* refAs = curr->dynCast()) { - if (refAs->op == ExternExternalize || refAs->op == ExternInternalize) { + if (refAs->op == ExternConvertAny || refAs->op == AnyConvertExtern) { return isSingleConstantExpression(refAs->value); } } @@ -124,9 +124,9 @@ inline Literal getLiteral(const Expression* curr) { } else if (auto* s = curr->dynCast()) { return Literal(s->string.toString()); } else if (auto* r = curr->dynCast()) { - if (r->op == ExternExternalize) { + if (r->op == ExternConvertAny) { return getLiteral(r->value).externalize(); - } else if (r->op == ExternInternalize) { + } else if (r->op == AnyConvertExtern) { return getLiteral(r->value).internalize(); } } @@ -329,7 +329,7 @@ inline Expression** getImmediateFallthroughPtr( // Extern conversions are not casts and actually produce new values. // Treating them as fallthroughs would lead to misoptimizations of // subsequent casts. - if (as->op != ExternInternalize && as->op != ExternExternalize) { + if (as->op != AnyConvertExtern && as->op != ExternConvertAny) { return &as->value; } } else if (auto* br = curr->dynCast()) { diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 8d7bd6d7f4d..097c28bc75e 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -564,6 +564,8 @@ function initializeConstants() { 'RefAsNonNull', 'RefAsExternInternalize', 'RefAsExternExternalize', + 'RefAsAnyConvertExtern', + 'RefAsExternConvertAny', 'BrOnNull', 'BrOnNonNull', 'BrOnCast', @@ -2380,8 +2382,8 @@ function wrapModule(module, self = {}) { } }; - // TODO: extern.internalize - // TODO: extern.externalize + // TODO: any.convert_extern + // TODO: extern.convert_any // TODO: ref.test // TODO: ref.cast // TODO: br_on_* diff --git a/src/passes/OptimizeCasts.cpp b/src/passes/OptimizeCasts.cpp index 5edde4d2ffe..efa00948b55 100644 --- a/src/passes/OptimizeCasts.cpp +++ b/src/passes/OptimizeCasts.cpp @@ -90,7 +90,7 @@ // ) // // Note that right now, we only consider RefAs with op RefAsNonNull as a cast. -// RefAs with ExternInternalize and ExternExternalize are not considered casts +// RefAs with AnyConvertExtern and ExternConvertAny are not considered casts // when obtaining fallthroughs, and so are ignored. // // TODO: Look past individual basic blocks? This may be worth considering diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 10c1aac9eb1..c470fa060d3 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -2440,7 +2440,7 @@ struct OptimizeInstructions return; } - if (curr->op == ExternExternalize || curr->op == ExternInternalize) { + if (curr->op == ExternConvertAny || curr->op == AnyConvertExtern) { // We can't optimize these. Even removing a non-null cast is not valid as // they allow nulls to filter through, unlike other RefAs*. return; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 4ca5f722b76..1d07b7f3c14 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2236,11 +2236,11 @@ struct PrintExpressionContents case RefAsNonNull: printMedium(o, "ref.as_non_null"); break; - case ExternInternalize: - printMedium(o, "extern.internalize"); + case AnyConvertExtern: + printMedium(o, "any.convert_extern"); break; - case ExternExternalize: - printMedium(o, "extern.externalize"); + case ExternConvertAny: + printMedium(o, "extern.convert_any"); break; default: WASM_UNREACHABLE("invalid ref.is_*"); diff --git a/src/passes/TypeGeneralizing.cpp b/src/passes/TypeGeneralizing.cpp index 720830400d4..faf01f173e8 100644 --- a/src/passes/TypeGeneralizing.cpp +++ b/src/passes/TypeGeneralizing.cpp @@ -850,10 +850,10 @@ struct TransferFn : OverriddenVisitor { case RefAsNonNull: push(Type(type.getHeapType(), Nullable)); return; - case ExternInternalize: + case AnyConvertExtern: push(Type(HeapType::ext, type.getNullability())); return; - case ExternExternalize: + case ExternConvertAny: push(Type(HeapType::any, type.getNullability())); return; } diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index c025764e717..df4e7a9bf77 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -916,7 +916,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { if (original != value) { // The original is externalized. assert(original.type.getHeapType() == HeapType::ext); - ret = builder.makeRefAs(ExternExternalize, ret); + ret = builder.makeRefAs(ExternConvertAny, ret); } return ret; } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9ce9bf1816b..0b9615c7e0c 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1120,8 +1120,8 @@ enum ASTNodes { RefCastNull = 0x17, BrOnCast = 0x18, BrOnCastFail = 0x19, - ExternInternalize = 0x1a, - ExternExternalize = 0x1b, + AnyConvertExtern = 0x1a, + ExternConvertAny = 0x1b, RefI31 = 0x1c, I31GetS = 0x1d, I31GetU = 0x1e, diff --git a/src/wasm-builder.h b/src/wasm-builder.h index f37e452406f..a20ba46a6d8 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1233,7 +1233,7 @@ class Builder { return makeStringConst(wtf16.str()); } if (type.isRef() && type.getHeapType() == HeapType::ext) { - return makeRefAs(ExternExternalize, + return makeRefAs(ExternConvertAny, makeConstantExpression(value.internalize())); } TODO_SINGLE_COMPOUND(type); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index c12f9cc33c7..93739d1c97d 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1858,9 +1858,9 @@ class ExpressionRunner : public OverriddenVisitor { trap("null ref"); } return value; - case ExternInternalize: + case AnyConvertExtern: return value.internalize(); - case ExternExternalize: + case ExternConvertAny: return value.externalize(); } WASM_UNREACHABLE("unimplemented ref.as_*"); @@ -2436,7 +2436,7 @@ class ConstantExpressionRunner : public ExpressionRunner { } Flow visitRefAs(RefAs* curr) { // TODO: Remove this once interpretation is implemented. - if (curr->op == ExternInternalize || curr->op == ExternExternalize) { + if (curr->op == AnyConvertExtern || curr->op == ExternConvertAny) { return Flow(NONCONSTANT_FLOW); } return ExpressionRunner::visitRefAs(curr); diff --git a/src/wasm.h b/src/wasm.h index ebb5a04f619..4a4ed561f91 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -561,8 +561,8 @@ enum SIMDTernaryOp { enum RefAsOp { RefAsNonNull, - ExternInternalize, - ExternExternalize, + AnyConvertExtern, + ExternConvertAny, }; enum BrOnOp { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index c4aaec5e908..78470324cf4 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4329,8 +4329,8 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { if (maybeVisitStringSliceWTF(curr, opcode)) { break; } - if (opcode == BinaryConsts::ExternInternalize || - opcode == BinaryConsts::ExternExternalize) { + if (opcode == BinaryConsts::AnyConvertExtern || + opcode == BinaryConsts::ExternConvertAny) { visitRefAs((curr = allocator.alloc())->cast(), opcode); break; } @@ -7730,11 +7730,11 @@ void WasmBinaryReader::visitRefAs(RefAs* curr, uint8_t code) { case BinaryConsts::RefAsNonNull: curr->op = RefAsNonNull; break; - case BinaryConsts::ExternInternalize: - curr->op = ExternInternalize; + case BinaryConsts::AnyConvertExtern: + curr->op = AnyConvertExtern; break; - case BinaryConsts::ExternExternalize: - curr->op = ExternExternalize; + case BinaryConsts::ExternConvertAny: + curr->op = ExternConvertAny; break; default: WASM_UNREACHABLE("invalid code for ref.as_*"); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index ac117e2e0ab..40a50706a34 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2334,13 +2334,13 @@ void BinaryInstWriter::visitRefAs(RefAs* curr) { case RefAsNonNull: o << int8_t(BinaryConsts::RefAsNonNull); break; - case ExternInternalize: + case AnyConvertExtern: o << int8_t(BinaryConsts::GCPrefix) - << U32LEB(BinaryConsts::ExternInternalize); + << U32LEB(BinaryConsts::AnyConvertExtern); break; - case ExternExternalize: + case ExternConvertAny: o << int8_t(BinaryConsts::GCPrefix) - << U32LEB(BinaryConsts::ExternExternalize); + << U32LEB(BinaryConsts::ExternConvertAny); break; default: WASM_UNREACHABLE("invalid ref.as_*"); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index a491fb951fd..9732f54a9a1 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2215,30 +2215,30 @@ void FunctionValidator::visitRefAs(RefAs* curr) { default: // TODO: validate all the other ref.as_* break; - case ExternInternalize: { + case AnyConvertExtern: { shouldBeTrue(getModule()->features.hasGC(), curr, - "extern.internalize requries GC [--enable-gc]"); + "any.convert_extern requries GC [--enable-gc]"); if (curr->type == Type::unreachable) { return; } shouldBeSubType(curr->value->type, Type(HeapType::ext, Nullable), curr->value, - "extern.internalize value should be an externref"); + "any.convert_extern value should be an externref"); break; } - case ExternExternalize: { + case ExternConvertAny: { shouldBeTrue(getModule()->features.hasGC(), curr, - "extern.externalize requries GC [--enable-gc]"); + "extern.convert_any requries GC [--enable-gc]"); if (curr->type == Type::unreachable) { return; } shouldBeSubType(curr->value->type, Type(HeapType::any, Nullable), curr->value, - "extern.externalize value should be an anyref"); + "extern.convert_any value should be an anyref"); break; } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index ed05e9b4766..58699ad8bba 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1231,10 +1231,10 @@ void RefAs::finalize() { case RefAsNonNull: type = Type(value->type.getHeapType(), NonNullable); break; - case ExternInternalize: + case AnyConvertExtern: type = Type(HeapType::any, value->type.getNullability()); break; - case ExternExternalize: + case ExternConvertAny: type = Type(HeapType::ext, value->type.getNullability()); break; default: diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index 16e8e8c4e23..bd8ec67931f 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -1451,7 +1451,7 @@ console.log("# RefAs"); assert(theRefAs.value === value); assert(theRefAs.type !== binaryen.i32); // TODO: === (ref any) - theRefAs.op = op = binaryen.Operations.RefAsExternExternalize; + theRefAs.op = op = binaryen.Operations.RefAsExternConvertAny; assert(theRefAs.op === op); theRefAs.op = op = binaryen.Operations.RefAsNonNull; theRefAs.value = value = module.local.get(2, binaryen.anyref); @@ -1467,7 +1467,7 @@ console.log("# RefAs"); "(ref.as_non_null\n (local.get $2)\n)\n" ); - // TODO: extern.externalize and extern.internalize + // TODO: extern.convert_any and any.convert_extern module.dispose(); })(); diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index efd343be9fd..cd305c69b87 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -1050,10 +1050,10 @@ void test_core() { BinaryenRefAsNonNull(), BinaryenRefNull(module, BinaryenTypeNullref())), BinaryenRefAs(module, - BinaryenRefAsExternInternalize(), + BinaryenRefAsAnyConvertExtern(), BinaryenRefNull(module, BinaryenTypeNullExternref())), BinaryenRefAs(module, - BinaryenRefAsExternExternalize(), + BinaryenRefAsExternConvertAny(), BinaryenRefNull(module, BinaryenTypeNullref())), // Exception handling BinaryenTry(module, NULL, tryBody, catchTags, 1, catchBodies, 2, NULL), diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 5ba35fb0e7a..140d8e9485d 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -2137,12 +2137,12 @@ BinaryenFeatureAll: 262143 ) ) (drop - (extern.internalize + (any.convert_extern (ref.null noextern) ) ) (drop - (extern.externalize + (extern.convert_any (ref.null none) ) ) diff --git a/test/lit/ctor-eval/extern.wast b/test/lit/ctor-eval/extern.wast index 9a8779abfea..9591f9034d0 100644 --- a/test/lit/ctor-eval/extern.wast +++ b/test/lit/ctor-eval/extern.wast @@ -16,7 +16,7 @@ ;; This will remain almost the same, even though we eval it, since the ;; serialization of an externalized i31 is what is written here. But the add ;; will be evalled out. - (extern.externalize + (extern.convert_any (ref.i31 (i32.add (i32.const 41) @@ -28,7 +28,7 @@ (func $test2 (result externref) ;; This will be evalled into an externalization of a global.get. - (extern.externalize + (extern.convert_any (array.new_fixed $array 3 (i32.const 1) (i32.const 2) @@ -40,7 +40,7 @@ (func $test3 (result anyref) ;; This will add a global that contains an externalization operation. (struct.new $struct - (extern.externalize + (extern.convert_any (ref.i31 (i32.const 1) ) @@ -60,7 +60,7 @@ ;; CHECK-NEXT: )) ;; CHECK: (global $ctor-eval$global_1 (ref $struct) (struct.new $struct -;; CHECK-NEXT: (extern.externalize +;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -74,7 +74,7 @@ ;; CHECK: (export "test3" (func $test3_5)) ;; CHECK: (func $test1_3 (type $2) (result externref) -;; CHECK-NEXT: (extern.externalize +;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) @@ -82,7 +82,7 @@ ;; CHECK-NEXT: ) ;; CHECK: (func $test2_4 (type $2) (result externref) -;; CHECK-NEXT: (extern.externalize +;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (global.get $ctor-eval$global) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/exec/i31.wast b/test/lit/exec/i31.wast index 0833d490ddb..807641d2440 100644 --- a/test/lit/exec/i31.wast +++ b/test/lit/exec/i31.wast @@ -91,7 +91,7 @@ ;; CHECK-NEXT: [fuzz-exec] note result: return-exted-i31 => i31ref(42) (func $return-exted-i31 (export "return-exted-i31") (result externref) ;; Even an externalized i31 is logged out using its integer value. - (extern.externalize + (extern.convert_any (ref.i31 (i32.const 42) ) diff --git a/test/lit/extern-conversions.wast b/test/lit/extern-conversions.wast index a3e18a2ace1..f8409755749 100644 --- a/test/lit/extern-conversions.wast +++ b/test/lit/extern-conversions.wast @@ -11,29 +11,48 @@ ;; CHECK: (type $1 (func (param externref) (result anyref))) - ;; CHECK: (export "ext" (func $extern.externalize)) + ;; CHECK: (type $2 (func (param externref) (result externref))) - ;; CHECK: (export "int" (func $extern.internalize)) + ;; CHECK: (export "ext" (func $extern.convert_any)) - ;; CHECK: (func $extern.externalize (type $0) (param $0 (ref any)) (result (ref extern)) - ;; CHECK-NEXT: (extern.externalize + ;; CHECK: (export "int" (func $any.convert_extern)) + + ;; CHECK: (export "legacy" (func $legacy_notation)) + + ;; CHECK: (func $extern.convert_any (type $0) (param $0 (ref any)) (result (ref extern)) + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $extern.externalize (export "ext") (param $x (ref any)) (result (ref extern)) - (extern.externalize + (func $extern.convert_any (export "ext") (param $x (ref any)) (result (ref extern)) + (extern.convert_any (local.get $x) ) ) - ;; CHECK: (func $extern.internalize (type $1) (param $0 externref) (result anyref) - ;; CHECK-NEXT: (extern.internalize + ;; CHECK: (func $any.convert_extern (type $1) (param $0 externref) (result anyref) + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $extern.internalize (export "int") (param $x (ref null extern)) (result (ref null any)) - (extern.internalize + (func $any.convert_extern (export "int") (param $x (ref null extern)) (result (ref null any)) + (any.convert_extern (local.get $x) ) ) + + ;; CHECK: (func $legacy_notation (type $2) (param $0 externref) (result externref) + ;; CHECK-NEXT: (extern.convert_any + ;; CHECK-NEXT: (any.convert_extern + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $legacy_notation (export "legacy") (param $x (ref null extern)) (result (ref null extern)) + (extern.externalize + (extern.internalize + (local.get $x) + ) + ) + ) ) diff --git a/test/lit/passes/gufa-extern.wast b/test/lit/passes/gufa-extern.wast index 7cc604c7618..ebb97cc59e1 100644 --- a/test/lit/passes/gufa-extern.wast +++ b/test/lit/passes/gufa-extern.wast @@ -9,13 +9,13 @@ ;; CHECK: (func $externals (type $0) (param $ext externref) (param $any anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref struct) - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $ext) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $any) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -25,13 +25,13 @@ ;; exported. (drop (ref.cast (ref struct) - (extern.internalize + (any.convert_extern (local.get $ext) ) ) ) (drop - (extern.externalize + (extern.convert_any (local.get $any) ) ) @@ -41,7 +41,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; (replaces unreachable RefCast we can't emit) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -49,7 +49,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -59,13 +59,13 @@ ;; unreachable. (drop (ref.cast (ref struct) - (extern.internalize + (any.convert_extern (local.get $ext) ) ) ) (drop - (extern.externalize + (extern.convert_any (local.get $any) ) ) diff --git a/test/lit/passes/optimize-instructions-gc-extern.wast b/test/lit/passes/optimize-instructions-gc-extern.wast index 5586651719e..658b2b1153d 100644 --- a/test/lit/passes/optimize-instructions-gc-extern.wast +++ b/test/lit/passes/optimize-instructions-gc-extern.wast @@ -3,53 +3,53 @@ ;; RUN: | filecheck %s (module - ;; CHECK: (func $extern.externalize (type $0) (param $x anyref) (param $y externref) + ;; CHECK: (func $extern.convert_any (type $0) (param $x anyref) (param $y externref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $extern.externalize (export "ext") (param $x (ref null any)) (param $y (ref null extern)) + (func $extern.convert_any (export "ext") (param $x (ref null any)) (param $y (ref null extern)) ;; We should not change anything here, and also not hit an internal error. (drop - (extern.externalize + (extern.convert_any (local.get $x) ) ) (drop - (extern.externalize + (extern.convert_any (ref.as_non_null (local.get $x) ) ) ) (drop - (extern.internalize + (any.convert_extern (local.get $y) ) ) (drop - (extern.internalize + (any.convert_extern (ref.as_non_null (local.get $y) ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index 14db70f3b98..60fca14fc16 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -2756,7 +2756,7 @@ ;; CHECK: (func $cast-internalized-extern (type $43) (param $externref externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast (ref $A) - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $externref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2768,7 +2768,7 @@ ;; the cast cannot succeed. (drop (ref.cast (ref $A) - (extern.internalize + (any.convert_extern (local.get $externref) ) ) diff --git a/test/lit/passes/type-generalizing.wast b/test/lit/passes/type-generalizing.wast index 8278549d083..344509794c2 100644 --- a/test/lit/passes/type-generalizing.wast +++ b/test/lit/passes/type-generalizing.wast @@ -770,7 +770,7 @@ ;; CHECK-NEXT: (local.set $var ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $var) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -780,7 +780,7 @@ (local.get $x) ) ;; Require that typeof($var) <: externref. - (extern.internalize + (any.convert_extern (local.get $var) ) ) @@ -790,7 +790,7 @@ ;; CHECK-NEXT: (local.set $var ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $var) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -800,7 +800,7 @@ (local.get $x) ) ;; Require that typeof($var) <: (ref extern). - (extern.internalize + (any.convert_extern (local.get $var) ) ) @@ -812,7 +812,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $var) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -824,7 +824,7 @@ ) ) ;; Require that typeof($var) <: anyref. - (extern.externalize + (extern.convert_any (local.get $var) ) ) @@ -836,7 +836,7 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $var) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -848,7 +848,7 @@ ) ) ;; Require that typeof($var) <: anyref. - (extern.externalize + (extern.convert_any (local.get $var) ) ) diff --git a/test/lit/passes/type-ssa.wast b/test/lit/passes/type-ssa.wast index 771b4b9aefc..277e2a2ff1b 100644 --- a/test/lit/passes/type-ssa.wast +++ b/test/lit/passes/type-ssa.wast @@ -382,15 +382,15 @@ ;; CHECK: (func $0 (type $2) (param $param anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $struct - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (global.get $g) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.internalize - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (any.convert_extern + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (global.get $g) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $param) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -400,17 +400,17 @@ (drop (struct.new $struct ;; An externalized global. - (extern.externalize + (extern.convert_any (global.get $g) ) ;; An externalized and then internalized global. - (extern.internalize - (extern.externalize + (any.convert_extern + (extern.convert_any (global.get $g) ) ) ;; An externalized parameter. - (extern.externalize + (extern.convert_any (local.get $param) ) ) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 71484977a17..730d9773e0e 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -4416,27 +4416,27 @@ ;; CHECK: (func $any-convert-extern (type $71) (param $0 externref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (any.convert_extern ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $any-convert-extern (param externref) local.get 0 - extern.internalize + any.convert_extern drop ) ;; CHECK: (func $extern-convert-any (type $9) (param $0 anyref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (extern.externalize + ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $extern-convert-any (param anyref) local.get 0 - extern.externalize + extern.convert_any drop ) diff --git a/test/spec/ref_test.wast b/test/spec/ref_test.wast index 13bc34878a9..d0283610635 100644 --- a/test/spec/ref_test.wast +++ b/test/spec/ref_test.wast @@ -19,8 +19,8 @@ (table.set $ta (i32.const 3) (ref.i31 (i32.const 7))) (table.set $ta (i32.const 4) (struct.new_default $st)) (table.set $ta (i32.const 5) (array.new_default $at (i32.const 0))) - (table.set $ta (i32.const 6) (extern.internalize (extern.externalize (ref.i31 (i32.const 0))))) - (table.set $ta (i32.const 7) (extern.internalize (ref.null extern))) + (table.set $ta (i32.const 6) (any.convert_extern (extern.convert_any (ref.i31 (i32.const 0))))) + (table.set $ta (i32.const 7) (any.convert_extern (ref.null extern))) (table.set $tf (i32.const 0) (ref.null nofunc)) (table.set $tf (i32.const 1) (ref.null func)) @@ -28,10 +28,10 @@ (table.set $te (i32.const 0) (ref.null noextern)) (table.set $te (i32.const 1) (ref.null extern)) - (table.set $te (i32.const 2) (extern.externalize (ref.i31 (i32.const 0)))) - (table.set $te (i32.const 3) (extern.externalize (ref.i31 (i32.const 8)))) - (table.set $te (i32.const 4) (extern.externalize (struct.new_default $st))) - (table.set $te (i32.const 5) (extern.externalize (ref.null any))) + (table.set $te (i32.const 2) (extern.convert_any (ref.i31 (i32.const 0)))) + (table.set $te (i32.const 3) (extern.convert_any (ref.i31 (i32.const 8)))) + (table.set $te (i32.const 4) (extern.convert_any (struct.new_default $st))) + (table.set $te (i32.const 5) (extern.convert_any (ref.null any))) ) (func (export "ref_test_null_data") (param $i i32) (result i32) From 4179603f8c21f5676cf4826ec4e41a1513c41540 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 8 Jul 2024 13:33:35 -0700 Subject: [PATCH 422/553] Version 118 (#6720) --- CHANGELOG.md | 3 +++ CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3c72ffa5a8..56199c9831a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ full changeset diff at the end of each section. Current Trunk ------------- +v118 +---- + - StackIR is now handled entirely during binary writing. This is mostly not noticeable, except that: - Text output no longer notes `(; has Stack IR ;)` (as Stack IR only exists diff --git a/CMakeLists.txt b/CMakeLists.txt index fef45bfca8b..95e5be6f949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.10.2) # to reduce this for compatability with emsdk. set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "Minimum OS X deployment version") -project(binaryen LANGUAGES C CXX VERSION 117) +project(binaryen LANGUAGES C CXX VERSION 118) include(GNUInstallDirs) # The C++ standard whose features are required to build Binaryen. From e93babcd71a89bd8c8e170d11652ca7375ef01f3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 8 Jul 2024 14:18:31 -0700 Subject: [PATCH 423/553] StackIR: Optimize away a drop before an unreachable (#6719) Anything else right before an unreachable is removed by the main DCE pass anyhow, but because of the structured form of BinaryenIR we can't remove a drop. That is, this is the difference between (i32.eqz (i32.const 42) (unreachable) ) and (drop (call $foo) ) (unreachable) In both cases the unreachable is preceded by something we don't need, but in the latter case it must remain in BinaryenIR for validation. To optimize this, add a rule in StackIR. Fixes #6715 --- src/wasm/wasm-stack-opts.cpp | 39 +++++++++- test/lit/passes/stack-ir-dce.wast | 118 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 test/lit/passes/stack-ir-dce.wast diff --git a/src/wasm/wasm-stack-opts.cpp b/src/wasm/wasm-stack-opts.cpp index ae9fee3940a..5e18cf26f4c 100644 --- a/src/wasm/wasm-stack-opts.cpp +++ b/src/wasm/wasm-stack-opts.cpp @@ -44,8 +44,9 @@ void StackIROptimizer::run() { vacuum(); } -// Remove unreachable code. void StackIROptimizer::dce() { + // Remove code after an unreachable instruction: anything after it, up to the + // next control flow barrier, can simply be removed. bool inUnreachableCode = false; for (Index i = 0; i < insts.size(); i++) { auto* inst = insts[i]; @@ -64,6 +65,42 @@ void StackIROptimizer::dce() { inUnreachableCode = true; } } + + // Remove code before an Unreachable. Consider this: + // + // (drop + // .. + // ) + // (unreachable) + // + // The drop is not needed, as the unreachable puts the stack in the + // polymorphic state anyhow. Note that we don't need to optimize anything + // other than a drop here, as in general the Binaryen IR DCE pass will handle + // everything else. A drop followed by an unreachable is the only thing that + // pass cannot handle, as the structured form of Binaryen IR does not allow + // removing such a drop, and so we can only do it here in StackIR. + // + // TODO: We can look even further back, say if there is another drop of + // something before, then we can remove that drop as well. To do that + // we'd need to inspect the stack going backwards. + for (Index i = 1; i < insts.size(); i++) { + auto* inst = insts[i]; + if (!inst || inst->op != StackInst::Basic || + !inst->origin->is()) { + continue; + } + + // Look back past nulls. + Index j = i - 1; + while (j > 0 && !insts[j]) { + j--; + } + + auto*& prev = insts[j]; + if (prev && prev->op == StackInst::Basic && prev->origin->is()) { + prev = nullptr; + } + } } // Remove obviously-unneeded code. diff --git a/test/lit/passes/stack-ir-dce.wast b/test/lit/passes/stack-ir-dce.wast new file mode 100644 index 00000000000..24afb48401c --- /dev/null +++ b/test/lit/passes/stack-ir-dce.wast @@ -0,0 +1,118 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s +;; Also verify we roundtrip the output here properly. +;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --roundtrip --print | filecheck %s --check-prefix=ROUNDTRIP + +(module + ;; CHECK: (func $drop-unreachable (type $0) (result i32) + ;; CHECK-NEXT: call $drop-unreachable + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $drop-unreachable (type $0) (result i32) + ;; ROUNDTRIP-NEXT: (drop + ;; ROUNDTRIP-NEXT: (call $drop-unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + (func $drop-unreachable (result i32) + ;; This drop can be removed. + (drop + (call $drop-unreachable) + ) + (unreachable) + ) + + ;; CHECK: (func $unreachable (type $0) (result i32) + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $unreachable (type $0) (result i32) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + (func $unreachable (result i32) + ;; An unreachable with nothing before it. Check we do not error here. + (unreachable) + ) + + ;; CHECK: (func $unreachable-non-drop (type $1) + ;; CHECK-NEXT: call $unreachable-non-drop + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $unreachable-non-drop (type $1) + ;; ROUNDTRIP-NEXT: (call $unreachable-non-drop) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + (func $unreachable-non-drop + ;; An unreachable with something other than a drop before it. Check we do + ;; not error here. + (call $unreachable-non-drop) + (unreachable) + ) + + ;; CHECK: (func $many-drop-unreachable (type $0) (result i32) + ;; CHECK-NEXT: i32.const 1 + ;; CHECK-NEXT: if (result i32) + ;; CHECK-NEXT: call $drop-unreachable + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: else + ;; CHECK-NEXT: call $drop-unreachable + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: end + ;; CHECK-NEXT: drop + ;; CHECK-NEXT: call $drop-unreachable + ;; CHECK-NEXT: unreachable + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $many-drop-unreachable (type $0) (result i32) + ;; ROUNDTRIP-NEXT: (drop + ;; ROUNDTRIP-NEXT: (if (result i32) + ;; ROUNDTRIP-NEXT: (i32.const 1) + ;; ROUNDTRIP-NEXT: (then + ;; ROUNDTRIP-NEXT: (drop + ;; ROUNDTRIP-NEXT: (call $drop-unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (else + ;; ROUNDTRIP-NEXT: (drop + ;; ROUNDTRIP-NEXT: (call $drop-unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (drop + ;; ROUNDTRIP-NEXT: (call $drop-unreachable) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: (unreachable) + ;; ROUNDTRIP-NEXT: ) + (func $many-drop-unreachable (result i32) + ;; Two drop-unreachables in an if. The drop on the if can remain, but all + ;; others are removable. + (drop + (if (result i32) + (i32.const 1) + (then + (drop + (call $drop-unreachable) + ) + (unreachable) + ) + (else + (drop + (call $drop-unreachable) + ) + (unreachable) + ) + ) + ) + ;; Two more outside the if. + (drop + (call $drop-unreachable) + ) + (unreachable) + (drop + (call $drop-unreachable) + ) + (unreachable) + ) +) From 081f28b337e50ff6837d580fed61254e92abe76a Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Tue, 9 Jul 2024 17:16:10 +0100 Subject: [PATCH 424/553] [tests] Remove use of CHECK-SAME (#6717) The `filecheck` command used for tests does not support `CHECK-SAME`, so use should be avoided. --- test/lit/wasm-split/mismatched-hashes.wast | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/lit/wasm-split/mismatched-hashes.wast b/test/lit/wasm-split/mismatched-hashes.wast index 8f2bd69fec5..64bd4cdaa43 100644 --- a/test/lit/wasm-split/mismatched-hashes.wast +++ b/test/lit/wasm-split/mismatched-hashes.wast @@ -11,9 +11,7 @@ ;; RUN: not wasm-split %t.instrumented.wasm --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm \ ;; RUN: 2>&1 | filecheck %s -;; CHECK: error: checksum in profile does not match module checksum. -;; CHECK-SAME: The split module must be the original module that was instrumented -;; CHECK-SAME: to generate the profile. +;; CHECK: error: checksum in profile does not match module checksum. The module to split must be the original, uninstrumented module, not the module used to generate the profile. ;; Check that the matching module succeeds ;; RUN: wasm-split %s --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm From 0750bdbc1f7c356a160493acdb8dc314a68f1f12 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 9 Jul 2024 10:06:15 -0700 Subject: [PATCH 425/553] [C API] Add APIs for getting/setting function types, and a CallRef example (#6721) Fixes #6718 --- src/binaryen-c.cpp | 6 +++++ src/binaryen-c.h | 5 ++++ test/example/c-api-kitchen-sink.c | 37 +++++++++++++++++++++++++++++ test/example/c-api-kitchen-sink.txt | 10 ++++++++ 4 files changed, 58 insertions(+) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 9c9a1c54f33..be80206f568 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -5684,6 +5684,12 @@ void BinaryenFunctionSetBody(BinaryenFunctionRef func, assert(body); ((Function*)func)->body = (Expression*)body; } +BinaryenHeapType BinaryenFunctionGetType(BinaryenFunctionRef func) { + return ((Function*)func)->type.getID(); +} +void BinaryenFunctionSetType(BinaryenFunctionRef func, BinaryenHeapType type) { + ((Function*)func)->type = HeapType(type); +} void BinaryenFunctionOptimize(BinaryenFunctionRef func, BinaryenModuleRef module) { PassRunner passRunner((Module*)module); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 45230a1175e..35f1d8eb8ac 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -3136,6 +3136,11 @@ BinaryenFunctionGetBody(BinaryenFunctionRef func); // Sets the body of the specified `Function`. BINARYEN_API void BinaryenFunctionSetBody(BinaryenFunctionRef func, BinaryenExpressionRef body); +// Gets the type of the specified `Function`. +BINARYEN_API BinaryenHeapType BinaryenFunctionGetType(BinaryenFunctionRef func); +// Sets the type of the specified `Function`. +BINARYEN_API void BinaryenFunctionSetType(BinaryenFunctionRef func, + BinaryenHeapType type); // Runs the standard optimization passes on the function. Uses the currently set // global optimize and shrink level. diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index cd305c69b87..802789173de 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -2194,6 +2194,42 @@ void test_typebuilder() { BinaryenModuleDispose(module); } +void test_callref_and_types() { + BinaryenModuleRef module = BinaryenModuleCreate(); + BinaryenModuleSetFeatures(module, BinaryenFeatureAll()); + + // Create a tiny function. + BinaryenFunctionRef tiny = BinaryenAddFunction(module, + "tiny", + BinaryenTypeNone(), + BinaryenTypeNone(), + NULL, + 0, + BinaryenNop(module)); + + // Get a non-nullable type with that function's heap type. + BinaryenHeapType funcType = + BinaryenTypeFromHeapType(BinaryenFunctionGetType(tiny), false); + + // Add a CallRef with that function and that type. Note that the RefFunc must + // use that type (and not generic funcref, as in the IR the type must always + // be precise). + BinaryenExpressionRef callRef = + BinaryenCallRef(module, + BinaryenRefFunc(module, "tiny", funcType), + NULL, + 0, + BinaryenTypeNone(), + false); + BinaryenFunctionSetBody(tiny, callRef); + + bool didValidate = BinaryenModuleValidate(module); + assert(didValidate); + printf("module with a call_ref:\n"); + BinaryenModulePrint(module); + BinaryenModuleDispose(module); +} + int main() { test_types(); test_features(); @@ -2207,6 +2243,7 @@ int main() { test_for_each(); test_func_opt(); test_typebuilder(); + test_callref_and_types(); return 0; } diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 140d8e9485d..e568cfba01c 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -3053,3 +3053,13 @@ module with recursive GC types: (unreachable) ) ) +module with a call_ref: +(module + (type $0 (func)) + (elem declare func $tiny) + (func $tiny (type $0) + (call_ref $0 + (ref.func $tiny) + ) + ) +) From 76f661203f98820ebc6840ecf627a5eafc038403 Mon Sep 17 00:00:00 2001 From: Benjamin Ling Date: Thu, 11 Jul 2024 02:35:27 +0800 Subject: [PATCH 426/553] Allow --keepfuncs and --splitfuncs to be use alongside a profile data (#6322) There are times after collecting a profile, we wish to manually include specific functions into the primary module. It could be due to non-deterministic profiling or functions for error scenarios (e.g. _trap). This PR helps to unlock this workflow by honoring both the `--keep-funcs` flag as well as the `--profile` flag --- src/tools/wasm-split/split-options.cpp | 19 +++------- src/tools/wasm-split/wasm-split.cpp | 44 ++++++++++++++++++------ test/lit/help/wasm-split.test | 13 +++---- test/lit/wasm-split/basic.wast | 10 ++++++ test/lit/wasm-split/invalid-options.wast | 18 ---------- test/lit/wasm-split/profile-guided.wast | 19 ++++++++++ 6 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/tools/wasm-split/split-options.cpp b/src/tools/wasm-split/split-options.cpp index b166b575cc6..9a93519983f 100644 --- a/src/tools/wasm-split/split-options.cpp +++ b/src/tools/wasm-split/split-options.cpp @@ -129,7 +129,7 @@ WasmSplitOptions::WasmSplitOptions() .add("--keep-funcs", "", "Comma-separated list of functions to keep in the primary module. The " - "rest will be split out. Cannot be used with --profile or " + "rest will be split out. Can be used alongside --profile and " "--split-funcs. You can also pass a file with one function per line " "by passing @filename.", WasmSplitOption, @@ -141,8 +141,9 @@ WasmSplitOptions::WasmSplitOptions() .add("--split-funcs", "", "Comma-separated list of functions to split out to the secondary " - "module. The rest will be kept. Cannot be used with --profile or " - "--keep-funcs. You can also pass a file with one function per line " + "module. The rest will be kept. Can be used alongside --profile and " + "--keep-funcs. This takes precedence over other split options. " + "You can also pass a file with one function per line " "by passing @filename.", WasmSplitOption, {Mode::Split}, @@ -421,18 +422,6 @@ bool WasmSplitOptions::validate() { } } - if (mode == Mode::Split) { - if (profileFile.size() && keepFuncs.size()) { - fail("Cannot use both --profile and --keep-funcs."); - } - if (profileFile.size() && splitFuncs.size()) { - fail("Cannot use both --profile and --split-funcs."); - } - if (keepFuncs.size() && splitFuncs.size()) { - fail("Cannot use both --keep-funcs and --split-funcs."); - } - } - return valid; } diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index d7dc19d677a..abb1646c173 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -212,30 +212,35 @@ void splitModule(const WasmSplitOptions& options) { parseInput(wasm, options); std::set keepFuncs; + std::set splitFuncs; if (options.profileFile.size()) { // Use the profile to set `keepFuncs`. uint64_t hash = hashFile(options.inputFiles[0]); - std::set splitFuncs; getFunctionsToKeepAndSplit( wasm, hash, options.profileFile, keepFuncs, splitFuncs); - } else if (options.keepFuncs.size()) { + } + + if (options.keepFuncs.size()) { // Use the explicitly provided `keepFuncs`. for (auto& func : options.keepFuncs) { if (!options.quiet && wasm.getFunctionOrNull(func) == nullptr) { std::cerr << "warning: function " << func << " does not exist\n"; + continue; } + keepFuncs.insert(func); + splitFuncs.erase(func); } - } else if (options.splitFuncs.size()) { + } + + if (options.splitFuncs.size()) { // Use the explicitly provided `splitFuncs`. - for (auto& func : wasm.functions) { - keepFuncs.insert(func->name); - } for (auto& func : options.splitFuncs) { auto* function = wasm.getFunctionOrNull(func); if (!options.quiet && function == nullptr) { std::cerr << "warning: function " << func << " does not exist\n"; + continue; } if (function && function->imported()) { if (!options.quiet) { @@ -243,20 +248,39 @@ void splitModule(const WasmSplitOptions& options) { << "\n"; } } else { + if (!options.quiet && keepFuncs.count(func) > 0) { + std::cerr + << "warning: function " << func + << " was to be kept in primary module. " + << "However it will now be split out into secondary module.\n"; + } + + splitFuncs.insert(func); keepFuncs.erase(func); } } - } - if (options.jspi) { - // The load secondary module function must be kept in the main module. - keepFuncs.insert(ModuleSplitting::LOAD_SECONDARY_MODULE); + if (keepFuncs.empty()) { + // could be the case where every function has been split out + // or when `splitFuncs` is used standalone, which is the case we'll cover + // here + for (auto& func : wasm.functions) { + if (splitFuncs.count(func->name) == 0) { + keepFuncs.insert(func->name); + } + } + } } if (!options.quiet && keepFuncs.size() == 0) { std::cerr << "warning: not keeping any functions in the primary module\n"; } + if (options.jspi) { + // The load secondary module function must be kept in the main module. + keepFuncs.insert(ModuleSplitting::LOAD_SECONDARY_MODULE); + } + // If warnings are enabled, check that any functions are being split out. if (!options.quiet) { std::set splitFuncs; diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test index 333864bcbbf..c118d302dca 100644 --- a/test/lit/help/wasm-split.test +++ b/test/lit/help/wasm-split.test @@ -30,17 +30,18 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --keep-funcs [split] Comma-separated list of functions ;; CHECK-NEXT: to keep in the primary module. The rest -;; CHECK-NEXT: will be split out. Cannot be used with -;; CHECK-NEXT: --profile or --split-funcs. You can also +;; CHECK-NEXT: will be split out. Can be used alongside +;; CHECK-NEXT: --profile and --split-funcs. You can also ;; CHECK-NEXT: pass a file with one function per line by ;; CHECK-NEXT: passing @filename. ;; CHECK-NEXT: ;; CHECK-NEXT: --split-funcs [split] Comma-separated list of functions ;; CHECK-NEXT: to split out to the secondary module. The -;; CHECK-NEXT: rest will be kept. Cannot be used with -;; CHECK-NEXT: --profile or --keep-funcs. You can also -;; CHECK-NEXT: pass a file with one function per line by -;; CHECK-NEXT: passing @filename. +;; CHECK-NEXT: rest will be kept. Can be used alongside +;; CHECK-NEXT: --profile and --keep-funcs. This takes +;; CHECK-NEXT: precedence over other split options. You +;; CHECK-NEXT: can also pass a file with one function +;; CHECK-NEXT: per line by passing @filename. ;; CHECK-NEXT: ;; CHECK-NEXT: --primary-output,-o1 [split] Output file for the primary ;; CHECK-NEXT: module. diff --git a/test/lit/wasm-split/basic.wast b/test/lit/wasm-split/basic.wast index 2291916a073..99bf17260e3 100644 --- a/test/lit/wasm-split/basic.wast +++ b/test/lit/wasm-split/basic.wast @@ -47,6 +47,12 @@ ;; RUN: wasm-dis %t.split-bar.1.wasm | filecheck %s --check-prefix KEEP-FOO-PRIMARY ;; RUN: wasm-dis %t.split-bar.2.wasm | filecheck %s --check-prefix KEEP-FOO-SECONDARY +;; Check workflow where --split-funcs supersede --keep-funcs +;; RUN: wasm-split %s --export-prefix='%' -g -o1 %t.split-bar.1.wasm -o2 %t.split-bar.2.wasm --keep-funcs=@%S/both.txt --split-funcs=bar -v 2>&1 \ +;; RUN: | filecheck %s --check-prefix SPLIT-BAR-SUPERSEDE +;; RUN: wasm-dis %t.split-bar.1.wasm | filecheck %s --check-prefix KEEP-FOO-PRIMARY +;; RUN: wasm-dis %t.split-bar.2.wasm | filecheck %s --check-prefix KEEP-FOO-SECONDARY + (module (table $table 1 1 funcref) (elem (i32.const 0) $foo) @@ -170,3 +176,7 @@ ;; KEEP-BOTH-SECONDARY: (module ;; KEEP-BOTH-SECONDARY-NEXT: (import "primary" "%table" (table $table 1 1 funcref)) ;; KEEP-BOTH-SECONDARY-NEXT: ) + +;; SPLIT-BAR-SUPERSEDE: warning: function bar was to be kept in primary module. However it will now be split out into secondary module. +;; SPLIT-BAR-SUPERSEDE: Keeping functions: foo{{$}} +;; SPLIT-BAR-SUPERSEDE: Splitting out functions: bar{{$}} diff --git a/test/lit/wasm-split/invalid-options.wast b/test/lit/wasm-split/invalid-options.wast index c5a56b57943..6d197adde48 100644 --- a/test/lit/wasm-split/invalid-options.wast +++ b/test/lit/wasm-split/invalid-options.wast @@ -52,18 +52,6 @@ ;; RUN: not wasm-split %s --merge-profiles -g 2>&1 \ ;; RUN: | filecheck %s --check-prefix MERGE-DEBUGINFO -;; --profile cannot be used with --keep-funcs -;; RUN: not wasm-split %s --profile=foo --keep-funcs=foo 2>&1 \ -;; RUN: | filecheck %s --check-prefix PROFILE-KEEP - -;; --profile cannot be used with --split-funcs -;; RUN: not wasm-split %s --profile=foo --split-funcs=foo 2>&1 \ -;; RUN: | filecheck %s --check-prefix PROFILE-SPLIT - -;; --keep-funcs cannot be used with --split-funcs -;; RUN: not wasm-split %s --keep-funcs=foo --split-funcs=foo 2>&1 \ -;; RUN: | filecheck %s --check-prefix KEEP-SPLIT - ;; INSTRUMENT-PROFILE: error: Option --profile cannot be used in instrument mode. ;; INSTRUMENT-OUT1: error: Option --primary-output cannot be used in instrument mode. @@ -90,10 +78,4 @@ ;; MERGE-DEBUGINFO: error: Option --debuginfo cannot be used in merge-profiles mode. -;; PROFILE-KEEP: error: Cannot use both --profile and --keep-funcs. - -;; PROFILE-SPLIT: error: Cannot use both --profile and --split-funcs. - -;; KEEP-SPLIT: error: Cannot use both --keep-funcs and --split-funcs. - (module) diff --git a/test/lit/wasm-split/profile-guided.wast b/test/lit/wasm-split/profile-guided.wast index 6828c19fcde..709ff4c8f4e 100644 --- a/test/lit/wasm-split/profile-guided.wast +++ b/test/lit/wasm-split/profile-guided.wast @@ -25,6 +25,12 @@ ;; RUN: wasm-split -all %s --profile=%t.none.prof -v -o1 %t.none.1.wasm -o2 %t.none.2.wasm \ ;; RUN: | filecheck %s --check-prefix NONE +;; RUN: wasm-split -all %s --profile=%t.bar.prof --keep-funcs=uncalled -v -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm \ +;; RUN: | filecheck %s --check-prefix PROFILE_KEEP + +;; RUN: wasm-split -all %s --profile=%t.both.prof --split-funcs=shared_callee -v -o1 %t.both.1.wasm -o2 %t.both.2.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix PROFILE_SPLIT + ;; ================================= ;; Do it all again using --in-memory ;; ================================= @@ -52,6 +58,12 @@ ;; RUN: wasm-split -all %s --profile=%t.none.prof -v -o1 %t.none.1.wasm -o2 %t.none.2.wasm \ ;; RUN: | filecheck %s --check-prefix NONE +;; RUN: wasm-split -all %s --profile=%t.bar.prof --keep-funcs=uncalled -v -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm \ +;; RUN: | filecheck %s --check-prefix PROFILE_KEEP + +;; RUN: wasm-split -all %s --profile=%t.both.prof --split-funcs=shared_callee -v -o1 %t.both.1.wasm -o2 %t.both.2.wasm 2>&1 \ +;; RUN: | filecheck %s --check-prefix PROFILE_SPLIT + ;; ======= ;; Results ;; ======= @@ -68,6 +80,13 @@ ;; NONE: Keeping functions: ;; NONE: Splitting out functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee, uncalled +;; PROFILE_KEEP: Keeping functions: bar, bar_callee, shared_callee, uncalled +;; PROFILE_KEEP: Splitting out functions: deep_foo_callee, foo, foo_callee + +;; PROFILE_SPLIT: warning: function shared_callee was to be kept in primary module. However it will now be split out into secondary module. +;; PROFILE_SPLIT: Keeping functions: bar, bar_callee, deep_foo_callee, foo, foo_callee +;; PROFILE_SPLIT: Splitting out functions: shared_callee, uncalled + (module (memory $mem 1 1 shared) (export "memory" (memory $mem)) From 37a86d558994415e722e7f62f5784b1a8b8b4832 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 10 Jul 2024 12:15:22 -0700 Subject: [PATCH 427/553] [StackIR] Allow StackIR to be disabled from the commandline (#6725) Normally we use it when optimizing (above a certain level). This lets the user prevent it from being used even then. Also add optimization options to wasm-metadce so that this is possible there as well and not just in wasm-opt (this also opens the door to running more passes in metadce, which may be useful later). --- scripts/fuzz_opt.py | 1 + src/tools/optimization-options.h | 17 +- src/tools/wasm-metadce.cpp | 4 +- test/lit/help/wasm-metadce.test | 721 ++++++++++++++++++++++--- test/lit/help/wasm-opt.test | 3 + test/lit/help/wasm2js.test | 3 + test/lit/passes/stack-ir-defaults.wast | 66 +++ 7 files changed, 737 insertions(+), 78 deletions(-) create mode 100644 test/lit/passes/stack-ir-defaults.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 4e1305042d9..2707df4c01d 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -1565,6 +1565,7 @@ def write_commands(commands, filename): ('--merge-locals',), ('--monomorphize',), ('--monomorphize-always',), + ('--no-stack-ir',), ('--once-reduction',), ("--optimize-casts",), ("--optimize-instructions",), diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h index 8772edd29d3..af468769d69 100644 --- a/src/tools/optimization-options.h +++ b/src/tools/optimization-options.h @@ -26,12 +26,17 @@ namespace wasm { struct OptimizationOptions : public ToolOptions { + // By default we allow StackIR and enable it by default in higher optimization + // levels, but users can disallow it as well. + bool allowStackIR = true; + void parse(int argc, const char* argv[]) { ToolOptions::parse(argc, argv); // After parsing the arguments, update defaults based on the optimize/shrink // levels. - if (passOptions.optimizeLevel >= 2 || passOptions.shrinkLevel >= 1) { + if (allowStackIR && + (passOptions.optimizeLevel >= 2 || passOptions.shrinkLevel >= 1)) { passOptions.generateStackIR = true; passOptions.optimizeStackIR = true; } @@ -191,6 +196,16 @@ struct OptimizationOptions : public ToolOptions { [&](Options* o, const std::string& arguments) { passOptions.debugInfo = true; }) + .add("--no-stack-ir", + "", + "do not use StackIR (even when it is the default)", + ToolOptionsCategory, + Options::Arguments::Zero, + [&](Options* o, const std::string& arguments) { + allowStackIR = false; + passOptions.generateStackIR = false; + passOptions.optimizeStackIR = false; + }) .add("--always-inline-max-function-size", "-aimfs", "Max size of functions that are always inlined (default " + diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp index 3014702062f..9cc06375ec7 100644 --- a/src/tools/wasm-metadce.cpp +++ b/src/tools/wasm-metadce.cpp @@ -29,11 +29,11 @@ #include "asmjs/shared-constants.h" #include "ir/element-utils.h" #include "ir/module-utils.h" +#include "optimization-options.h" #include "pass.h" #include "support/colors.h" #include "support/file.h" #include "support/json.h" -#include "tool-options.h" #include "wasm-builder.h" #include "wasm-io.h" #include "wasm-validator.h" @@ -371,7 +371,7 @@ int main(int argc, const char* argv[]) { const std::string WasmMetaDCEOption = "wasm-opt options"; - ToolOptions options( + OptimizationOptions options( "wasm-metadce", "This tool performs dead code elimination (DCE) on a larger space " "that the wasm module is just a part of. For example, if you have " diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index 453328df107..5b621caf5e1 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -51,146 +51,717 @@ ;; CHECK-NEXT: wasm-opt options: ;; CHECK-NEXT: ----------------- ;; CHECK-NEXT: -;; CHECK-NEXT: --output,-o Output file (stdout if not specified) +;; CHECK-NEXT: --output,-o Output file (stdout if not +;; CHECK-NEXT: specified) ;; CHECK-NEXT: -;; CHECK-NEXT: --input-source-map,-ism Consume source map from the specified -;; CHECK-NEXT: file +;; CHECK-NEXT: --input-source-map,-ism Consume source map from the +;; CHECK-NEXT: specified file ;; CHECK-NEXT: -;; CHECK-NEXT: --output-source-map,-osm Emit source map to the specified file +;; CHECK-NEXT: --output-source-map,-osm Emit source map to the specified +;; CHECK-NEXT: file ;; CHECK-NEXT: -;; CHECK-NEXT: --output-source-map-url,-osu Emit specified string as source map URL +;; CHECK-NEXT: --output-source-map-url,-osu Emit specified string as source +;; CHECK-NEXT: map URL ;; CHECK-NEXT: -;; CHECK-NEXT: --emit-text,-S Emit text instead of binary for the -;; CHECK-NEXT: output file +;; CHECK-NEXT: --emit-text,-S Emit text instead of binary for +;; CHECK-NEXT: the output file ;; CHECK-NEXT: -;; CHECK-NEXT: --debuginfo,-g Emit names section and debug info +;; CHECK-NEXT: --debuginfo,-g Emit names section and debug +;; CHECK-NEXT: info ;; CHECK-NEXT: -;; CHECK-NEXT: --graph-file,-f Filename of the graph description file +;; CHECK-NEXT: --graph-file,-f Filename of the graph +;; CHECK-NEXT: description file ;; CHECK-NEXT: -;; CHECK-NEXT: --dump,-d Dump the combined graph file (useful for -;; CHECK-NEXT: debugging) +;; CHECK-NEXT: --dump,-d Dump the combined graph file +;; CHECK-NEXT: (useful for debugging) +;; CHECK-NEXT: +;; CHECK-NEXT: +;; CHECK-NEXT: Optimization passes: +;; CHECK-NEXT: -------------------- +;; CHECK-NEXT: +;; CHECK-NEXT: --abstract-type-refining refine and merge abstract +;; CHECK-NEXT: (never-created) types +;; CHECK-NEXT: +;; CHECK-NEXT: --alignment-lowering lower unaligned loads and stores +;; CHECK-NEXT: to smaller aligned ones +;; CHECK-NEXT: +;; CHECK-NEXT: --asyncify async/await style transform, +;; CHECK-NEXT: allowing pausing and resuming +;; CHECK-NEXT: +;; CHECK-NEXT: --avoid-reinterprets Tries to avoid reinterpret +;; CHECK-NEXT: operations via more loads +;; CHECK-NEXT: +;; CHECK-NEXT: --cfp propagate constant struct field +;; CHECK-NEXT: values +;; CHECK-NEXT: +;; CHECK-NEXT: --cfp-reftest propagate constant struct field +;; CHECK-NEXT: values, using ref.test +;; CHECK-NEXT: +;; CHECK-NEXT: --coalesce-locals reduce # of locals by coalescing +;; CHECK-NEXT: +;; CHECK-NEXT: --coalesce-locals-learning reduce # of locals by coalescing +;; CHECK-NEXT: and learning +;; CHECK-NEXT: +;; CHECK-NEXT: --code-folding fold code, merging duplicates +;; CHECK-NEXT: +;; CHECK-NEXT: --code-pushing push code forward, potentially +;; CHECK-NEXT: making it not always execute +;; CHECK-NEXT: +;; CHECK-NEXT: --const-hoisting hoist repeated constants to a +;; CHECK-NEXT: local +;; CHECK-NEXT: +;; CHECK-NEXT: --dae removes arguments to calls in an +;; CHECK-NEXT: lto-like manner +;; CHECK-NEXT: +;; CHECK-NEXT: --dae-optimizing removes arguments to calls in an +;; CHECK-NEXT: lto-like manner, and optimizes +;; CHECK-NEXT: where we removed +;; CHECK-NEXT: +;; CHECK-NEXT: --dce removes unreachable code +;; CHECK-NEXT: +;; CHECK-NEXT: --dealign forces all loads and stores to +;; CHECK-NEXT: have alignment 1 +;; CHECK-NEXT: +;; CHECK-NEXT: --denan instrument the wasm to convert +;; CHECK-NEXT: NaNs into 0 at runtime +;; CHECK-NEXT: +;; CHECK-NEXT: --dfo optimizes using the DataFlow SSA +;; CHECK-NEXT: IR +;; CHECK-NEXT: +;; CHECK-NEXT: --directize turns indirect calls into direct +;; CHECK-NEXT: ones +;; CHECK-NEXT: +;; CHECK-NEXT: --discard-global-effects discards global effect info +;; CHECK-NEXT: +;; CHECK-NEXT: --duplicate-function-elimination removes duplicate functions +;; CHECK-NEXT: +;; CHECK-NEXT: --duplicate-import-elimination removes duplicate imports +;; CHECK-NEXT: +;; CHECK-NEXT: --dwarfdump dump DWARF debug info sections +;; CHECK-NEXT: from the read binary +;; CHECK-NEXT: +;; CHECK-NEXT: --emit-target-features emit the target features section +;; CHECK-NEXT: in the output +;; CHECK-NEXT: +;; CHECK-NEXT: --extract-function leaves just one function (useful +;; CHECK-NEXT: for debugging) +;; CHECK-NEXT: +;; CHECK-NEXT: --extract-function-index leaves just one function +;; CHECK-NEXT: selected by index +;; CHECK-NEXT: +;; CHECK-NEXT: --flatten flattens out code, removing +;; CHECK-NEXT: nesting +;; CHECK-NEXT: +;; CHECK-NEXT: --fpcast-emu emulates function pointer casts, +;; CHECK-NEXT: allowing incorrect indirect +;; CHECK-NEXT: calls to (sometimes) work +;; CHECK-NEXT: +;; CHECK-NEXT: --func-metrics reports function metrics +;; CHECK-NEXT: +;; CHECK-NEXT: --generate-dyncalls generate dynCall fuctions used +;; CHECK-NEXT: by emscripten ABI +;; CHECK-NEXT: +;; CHECK-NEXT: --generate-global-effects generate global effect info +;; CHECK-NEXT: (helps later passes) +;; CHECK-NEXT: +;; CHECK-NEXT: --generate-i64-dyncalls generate dynCall functions used +;; CHECK-NEXT: by emscripten ABI, but only for +;; CHECK-NEXT: functions with i64 in their +;; CHECK-NEXT: signature (which cannot be +;; CHECK-NEXT: invoked via the wasm table +;; CHECK-NEXT: without JavaScript BigInt +;; CHECK-NEXT: support). +;; CHECK-NEXT: +;; CHECK-NEXT: --global-refining refine the types of globals +;; CHECK-NEXT: +;; CHECK-NEXT: --gsi globally optimize struct values +;; CHECK-NEXT: +;; CHECK-NEXT: --gto globally optimize GC types +;; CHECK-NEXT: +;; CHECK-NEXT: --gufa Grand Unified Flow Analysis: +;; CHECK-NEXT: optimize the entire program +;; CHECK-NEXT: using information about what +;; CHECK-NEXT: content can actually appear in +;; CHECK-NEXT: each location +;; CHECK-NEXT: +;; CHECK-NEXT: --gufa-cast-all GUFA plus add casts for all +;; CHECK-NEXT: inferences +;; CHECK-NEXT: +;; CHECK-NEXT: --gufa-optimizing GUFA plus local optimizations in +;; CHECK-NEXT: functions we modified +;; CHECK-NEXT: +;; CHECK-NEXT: --heap2local replace GC allocations with +;; CHECK-NEXT: locals +;; CHECK-NEXT: +;; CHECK-NEXT: --i64-to-i32-lowering lower all uses of i64s to use +;; CHECK-NEXT: i32s instead +;; CHECK-NEXT: +;; CHECK-NEXT: --inline-main inline __original_main into main +;; CHECK-NEXT: +;; CHECK-NEXT: --inlining inline functions (you probably +;; CHECK-NEXT: want inlining-optimizing) +;; CHECK-NEXT: +;; CHECK-NEXT: --inlining-optimizing inline functions and optimizes +;; CHECK-NEXT: where we inlined +;; CHECK-NEXT: +;; CHECK-NEXT: --instrument-locals instrument the build with code +;; CHECK-NEXT: to intercept all loads and +;; CHECK-NEXT: stores +;; CHECK-NEXT: +;; CHECK-NEXT: --instrument-memory instrument the build with code +;; CHECK-NEXT: to intercept all loads and +;; CHECK-NEXT: stores +;; CHECK-NEXT: +;; CHECK-NEXT: --intrinsic-lowering lower away binaryen intrinsics +;; CHECK-NEXT: +;; CHECK-NEXT: --jspi wrap imports and exports for +;; CHECK-NEXT: JavaScript promise integration +;; CHECK-NEXT: +;; CHECK-NEXT: --legalize-and-prune-js-interface legalizes the import/export +;; CHECK-NEXT: boundary and prunes when needed +;; CHECK-NEXT: +;; CHECK-NEXT: --legalize-js-interface legalizes i64 types on the +;; CHECK-NEXT: import/export boundary +;; CHECK-NEXT: +;; CHECK-NEXT: --licm loop invariant code motion +;; CHECK-NEXT: +;; CHECK-NEXT: --limit-segments attempt to merge segments to fit +;; CHECK-NEXT: within web limits +;; CHECK-NEXT: +;; CHECK-NEXT: --local-cse common subexpression elimination +;; CHECK-NEXT: inside basic blocks +;; CHECK-NEXT: +;; CHECK-NEXT: --local-subtyping apply more specific subtypes to +;; CHECK-NEXT: locals where possible +;; CHECK-NEXT: +;; CHECK-NEXT: --log-execution instrument the build with +;; CHECK-NEXT: logging of where execution goes +;; CHECK-NEXT: +;; CHECK-NEXT: --memory-packing packs memory into separate +;; CHECK-NEXT: segments, skipping zeros +;; CHECK-NEXT: +;; CHECK-NEXT: --memory64-lowering lower loads and stores to a +;; CHECK-NEXT: 64-bit memory to instead use a +;; CHECK-NEXT: 32-bit one +;; CHECK-NEXT: +;; CHECK-NEXT: --merge-blocks merges blocks to their parents +;; CHECK-NEXT: +;; CHECK-NEXT: --merge-locals merges locals when beneficial +;; CHECK-NEXT: +;; CHECK-NEXT: --merge-similar-functions merges similar functions when +;; CHECK-NEXT: benefical +;; CHECK-NEXT: +;; CHECK-NEXT: --metrics reports metrics +;; CHECK-NEXT: +;; CHECK-NEXT: --minify-imports minifies import names (only +;; CHECK-NEXT: those, and not export names), +;; CHECK-NEXT: and emits a mapping to the +;; CHECK-NEXT: minified ones +;; CHECK-NEXT: +;; CHECK-NEXT: --minify-imports-and-exports minifies both import and export +;; CHECK-NEXT: names, and emits a mapping to +;; CHECK-NEXT: the minified ones +;; CHECK-NEXT: +;; CHECK-NEXT: --minify-imports-and-exports-and-modules minifies both import and export +;; CHECK-NEXT: names, and emits a mapping to +;; CHECK-NEXT: the minified ones, and minifies +;; CHECK-NEXT: the modules as well +;; CHECK-NEXT: +;; CHECK-NEXT: --mod-asyncify-always-and-only-unwind apply the assumption that +;; CHECK-NEXT: asyncify imports always unwind, +;; CHECK-NEXT: and we never rewind +;; CHECK-NEXT: +;; CHECK-NEXT: --mod-asyncify-never-unwind apply the assumption that +;; CHECK-NEXT: asyncify never unwinds +;; CHECK-NEXT: +;; CHECK-NEXT: --monomorphize creates specialized versions of +;; CHECK-NEXT: functions +;; CHECK-NEXT: +;; CHECK-NEXT: --monomorphize-always creates specialized versions of +;; CHECK-NEXT: functions (even if unhelpful) +;; CHECK-NEXT: +;; CHECK-NEXT: --multi-memory-lowering combines multiple memories into +;; CHECK-NEXT: a single memory +;; CHECK-NEXT: +;; CHECK-NEXT: --multi-memory-lowering-with-bounds-checks combines multiple memories into +;; CHECK-NEXT: a single memory, trapping if the +;; CHECK-NEXT: read or write is larger than the +;; CHECK-NEXT: length of the memory's data +;; CHECK-NEXT: +;; CHECK-NEXT: --name-types (re)name all heap types +;; CHECK-NEXT: +;; CHECK-NEXT: --nm name list +;; CHECK-NEXT: +;; CHECK-NEXT: --no-full-inline mark functions as no-inline (for +;; CHECK-NEXT: full inlining only) +;; CHECK-NEXT: +;; CHECK-NEXT: --no-inline mark functions as no-inline +;; CHECK-NEXT: +;; CHECK-NEXT: --no-partial-inline mark functions as no-inline (for +;; CHECK-NEXT: partial inlining only) +;; CHECK-NEXT: +;; CHECK-NEXT: --once-reduction reduces calls to code that only +;; CHECK-NEXT: runs once +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-added-constants optimizes added constants into +;; CHECK-NEXT: load/store offsets +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-added-constants-propagate optimizes added constants into +;; CHECK-NEXT: load/store offsets, propagating +;; CHECK-NEXT: them across locals too +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-casts eliminate and reuse casts +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-for-js early optimize of the +;; CHECK-NEXT: instruction combinations for js +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-instructions optimizes instruction +;; CHECK-NEXT: combinations +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-j2cl optimizes J2CL specific +;; CHECK-NEXT: constructs. +;; CHECK-NEXT: +;; CHECK-NEXT: --outlining outline instructions +;; CHECK-NEXT: +;; CHECK-NEXT: --pick-load-signs pick load signs based on their +;; CHECK-NEXT: uses +;; CHECK-NEXT: +;; CHECK-NEXT: --poppify Tranform Binaryen IR into Poppy +;; CHECK-NEXT: IR +;; CHECK-NEXT: +;; CHECK-NEXT: --post-emscripten miscellaneous optimizations for +;; CHECK-NEXT: Emscripten-generated code +;; CHECK-NEXT: +;; CHECK-NEXT: --precompute computes compile-time +;; CHECK-NEXT: evaluatable expressions +;; CHECK-NEXT: +;; CHECK-NEXT: --precompute-propagate computes compile-time +;; CHECK-NEXT: evaluatable expressions and +;; CHECK-NEXT: propagates them through locals +;; CHECK-NEXT: +;; CHECK-NEXT: --print print in s-expression format +;; CHECK-NEXT: +;; CHECK-NEXT: --print-call-graph print call graph +;; CHECK-NEXT: +;; CHECK-NEXT: --print-features print options for enabled +;; CHECK-NEXT: features +;; CHECK-NEXT: +;; CHECK-NEXT: --print-full print in full s-expression +;; CHECK-NEXT: format +;; CHECK-NEXT: +;; CHECK-NEXT: --print-function-map print a map of function indexes +;; CHECK-NEXT: to names +;; CHECK-NEXT: +;; CHECK-NEXT: --print-minified print in minified s-expression +;; CHECK-NEXT: format +;; CHECK-NEXT: +;; CHECK-NEXT: --propagate-debug-locs propagate debug location from +;; CHECK-NEXT: parents or previous siblings to +;; CHECK-NEXT: child nodes +;; CHECK-NEXT: +;; CHECK-NEXT: --propagate-globals-globally propagate global values to other +;; CHECK-NEXT: globals (useful for tests) +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-imports removes imports and replaces +;; CHECK-NEXT: them with nops +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-memory removes memory segments +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-non-js-ops removes operations incompatible +;; CHECK-NEXT: with js +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-unused-brs removes breaks from locations +;; CHECK-NEXT: that are not needed +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-unused-module-elements removes unused module elements +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-unused-names removes names from locations +;; CHECK-NEXT: that are never branched to +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-unused-nonfunction-module-elements removes unused module elements +;; CHECK-NEXT: that are not functions +;; CHECK-NEXT: +;; CHECK-NEXT: --remove-unused-types remove unused private GC types +;; CHECK-NEXT: +;; CHECK-NEXT: --reorder-functions sorts functions by access +;; CHECK-NEXT: frequency +;; CHECK-NEXT: +;; CHECK-NEXT: --reorder-functions-by-name sorts functions by name (useful +;; CHECK-NEXT: for debugging) +;; CHECK-NEXT: +;; CHECK-NEXT: --reorder-globals sorts globals by access +;; CHECK-NEXT: frequency +;; CHECK-NEXT: +;; CHECK-NEXT: --reorder-locals sorts locals by access frequency +;; CHECK-NEXT: +;; CHECK-NEXT: --rereloop re-optimize control flow using +;; CHECK-NEXT: the relooper algorithm +;; CHECK-NEXT: +;; CHECK-NEXT: --roundtrip write the module to binary, then +;; CHECK-NEXT: read it +;; CHECK-NEXT: +;; CHECK-NEXT: --rse remove redundant local.sets +;; CHECK-NEXT: +;; CHECK-NEXT: --safe-heap instrument loads and stores to +;; CHECK-NEXT: check for invalid behavior +;; CHECK-NEXT: +;; CHECK-NEXT: --separate-data-segments write data segments to a file +;; CHECK-NEXT: and strip them from the module +;; CHECK-NEXT: +;; CHECK-NEXT: --set-globals sets specified globals to +;; CHECK-NEXT: specified values +;; CHECK-NEXT: +;; CHECK-NEXT: --signature-pruning remove params from function +;; CHECK-NEXT: signature types where possible +;; CHECK-NEXT: +;; CHECK-NEXT: --signature-refining apply more specific subtypes to +;; CHECK-NEXT: signature types where possible +;; CHECK-NEXT: +;; CHECK-NEXT: --signext-lowering lower sign-ext operations to +;; CHECK-NEXT: wasm mvp and disable the sign +;; CHECK-NEXT: extension feature +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-globals miscellaneous globals-related +;; CHECK-NEXT: optimizations +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-globals-optimizing miscellaneous globals-related +;; CHECK-NEXT: optimizations, and optimizes +;; CHECK-NEXT: where we replaced global.gets +;; CHECK-NEXT: with constants +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-locals miscellaneous locals-related +;; CHECK-NEXT: optimizations +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-locals-nonesting miscellaneous locals-related +;; CHECK-NEXT: optimizations (no nesting at +;; CHECK-NEXT: all; preserves flatness) +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-locals-nostructure miscellaneous locals-related +;; CHECK-NEXT: optimizations (no structure) +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-locals-notee miscellaneous locals-related +;; CHECK-NEXT: optimizations (no tees) +;; CHECK-NEXT: +;; CHECK-NEXT: --simplify-locals-notee-nostructure miscellaneous locals-related +;; CHECK-NEXT: optimizations (no tees or +;; CHECK-NEXT: structure) +;; CHECK-NEXT: +;; CHECK-NEXT: --souperify emit Souper IR in text form +;; CHECK-NEXT: +;; CHECK-NEXT: --souperify-single-use emit Souper IR in text form +;; CHECK-NEXT: (single-use nodes only) +;; CHECK-NEXT: +;; CHECK-NEXT: --spill-pointers spill pointers to the C stack +;; CHECK-NEXT: (useful for Boehm-style GC) +;; CHECK-NEXT: +;; CHECK-NEXT: --ssa ssa-ify variables so that they +;; CHECK-NEXT: have a single assignment +;; CHECK-NEXT: +;; CHECK-NEXT: --ssa-nomerge ssa-ify variables so that they +;; CHECK-NEXT: have a single assignment, +;; CHECK-NEXT: ignoring merges +;; CHECK-NEXT: +;; CHECK-NEXT: --stack-check enforce limits on llvm's +;; CHECK-NEXT: __stack_pointer global +;; CHECK-NEXT: +;; CHECK-NEXT: --string-gathering gathers wasm strings to globals +;; CHECK-NEXT: +;; CHECK-NEXT: --string-lowering lowers wasm strings and +;; CHECK-NEXT: operations to imports +;; CHECK-NEXT: +;; CHECK-NEXT: --string-lowering-magic-imports same as string-lowering, but +;; CHECK-NEXT: encodes well-formed strings as +;; CHECK-NEXT: magic imports +;; CHECK-NEXT: +;; CHECK-NEXT: --strip deprecated; same as strip-debug +;; CHECK-NEXT: +;; CHECK-NEXT: --strip-debug strip debug info (including the +;; CHECK-NEXT: names section) +;; CHECK-NEXT: +;; CHECK-NEXT: --strip-dwarf strip dwarf debug info +;; CHECK-NEXT: +;; CHECK-NEXT: --strip-eh strip EH instructions +;; CHECK-NEXT: +;; CHECK-NEXT: --strip-producers strip the wasm producers section +;; CHECK-NEXT: +;; CHECK-NEXT: --strip-target-features strip the wasm target features +;; CHECK-NEXT: section +;; CHECK-NEXT: +;; CHECK-NEXT: --stub-unsupported-js stub out unsupported JS +;; CHECK-NEXT: operations +;; CHECK-NEXT: +;; CHECK-NEXT: --symbolmap (alias for print-function-map) +;; CHECK-NEXT: +;; CHECK-NEXT: --table64-lowering lower 64-bit tables 32-bit ones +;; CHECK-NEXT: +;; CHECK-NEXT: --trace-calls instrument the build with code +;; CHECK-NEXT: to intercept specific function +;; CHECK-NEXT: calls +;; CHECK-NEXT: +;; CHECK-NEXT: --translate-to-exnref translate old Phase 3 EH +;; CHECK-NEXT: instructions to new ones with +;; CHECK-NEXT: exnref +;; CHECK-NEXT: +;; CHECK-NEXT: --translate-to-new-eh deprecated; same as +;; CHECK-NEXT: translate-to-exnref +;; CHECK-NEXT: +;; CHECK-NEXT: --trap-mode-clamp replace trapping operations with +;; CHECK-NEXT: clamping semantics +;; CHECK-NEXT: +;; CHECK-NEXT: --trap-mode-js replace trapping operations with +;; CHECK-NEXT: js semantics +;; CHECK-NEXT: +;; CHECK-NEXT: --tuple-optimization optimize trivial tuples away +;; CHECK-NEXT: +;; CHECK-NEXT: --type-finalizing mark all leaf types as final +;; CHECK-NEXT: +;; CHECK-NEXT: --type-merging merge types to their supertypes +;; CHECK-NEXT: where possible +;; CHECK-NEXT: +;; CHECK-NEXT: --type-refining apply more specific subtypes to +;; CHECK-NEXT: type fields where possible +;; CHECK-NEXT: +;; CHECK-NEXT: --type-ssa create new nominal types to help +;; CHECK-NEXT: other optimizations +;; CHECK-NEXT: +;; CHECK-NEXT: --type-unfinalizing mark all types as non-final +;; CHECK-NEXT: (open) +;; CHECK-NEXT: +;; CHECK-NEXT: --unsubtyping removes unnecessary subtyping +;; CHECK-NEXT: relationships +;; CHECK-NEXT: +;; CHECK-NEXT: --untee removes local.tees, replacing +;; CHECK-NEXT: them with sets and gets +;; CHECK-NEXT: +;; CHECK-NEXT: --vacuum removes obviously unneeded code +;; CHECK-NEXT: +;; CHECK-NEXT: +;; CHECK-NEXT: Optimization options: +;; CHECK-NEXT: --------------------- +;; CHECK-NEXT: +;; CHECK-NEXT: -O execute default optimization +;; CHECK-NEXT: passes (equivalent to -Os) +;; CHECK-NEXT: +;; CHECK-NEXT: -O0 execute no optimization passes +;; CHECK-NEXT: +;; CHECK-NEXT: -O1 execute -O1 optimization passes +;; CHECK-NEXT: (quick&useful opts, useful for +;; CHECK-NEXT: iteration builds) +;; CHECK-NEXT: +;; CHECK-NEXT: -O2 execute -O2 optimization passes +;; CHECK-NEXT: (most opts, generally gets most +;; CHECK-NEXT: perf) +;; CHECK-NEXT: +;; CHECK-NEXT: -O3 execute -O3 optimization passes +;; CHECK-NEXT: (spends potentially a lot of +;; CHECK-NEXT: time optimizing) +;; CHECK-NEXT: +;; CHECK-NEXT: -O4 execute -O4 optimization passes +;; CHECK-NEXT: (also flatten the IR, which can +;; CHECK-NEXT: take a lot more time and memory, +;; CHECK-NEXT: but is useful on more nested / +;; CHECK-NEXT: complex / less-optimized input) +;; CHECK-NEXT: +;; CHECK-NEXT: -Os execute default optimization +;; CHECK-NEXT: passes, focusing on code size +;; CHECK-NEXT: +;; CHECK-NEXT: -Oz execute default optimization +;; CHECK-NEXT: passes, super-focusing on code +;; CHECK-NEXT: size +;; CHECK-NEXT: +;; CHECK-NEXT: --optimize-level,-ol How much to focus on optimizing +;; CHECK-NEXT: code +;; CHECK-NEXT: +;; CHECK-NEXT: --shrink-level,-s How much to focus on shrinking +;; CHECK-NEXT: code size +;; CHECK-NEXT: +;; CHECK-NEXT: --debuginfo,-g Emit names section in wasm +;; CHECK-NEXT: binary (or full debuginfo in +;; CHECK-NEXT: wast) +;; CHECK-NEXT: +;; CHECK-NEXT: --always-inline-max-function-size,-aimfs Max size of functions that are +;; CHECK-NEXT: always inlined (default 2, which +;; CHECK-NEXT: is safe for use with -Os builds) +;; CHECK-NEXT: +;; CHECK-NEXT: --flexible-inline-max-function-size,-fimfs Max size of functions that are +;; CHECK-NEXT: inlined when lightweight (no +;; CHECK-NEXT: loops or function calls) when +;; CHECK-NEXT: optimizing aggressively for +;; CHECK-NEXT: speed (-O3). Default: 20 +;; CHECK-NEXT: +;; CHECK-NEXT: --one-caller-inline-max-function-size,-ocimfs Max size of functions that are +;; CHECK-NEXT: inlined when there is only one +;; CHECK-NEXT: caller (default -1, which means +;; CHECK-NEXT: all such functions are inlined) +;; CHECK-NEXT: +;; CHECK-NEXT: --inline-functions-with-loops,-ifwl Allow inlining functions with +;; CHECK-NEXT: loops +;; CHECK-NEXT: +;; CHECK-NEXT: --partial-inlining-ifs,-pii Number of ifs allowed in partial +;; CHECK-NEXT: inlining (zero means partial +;; CHECK-NEXT: inlining is disabled) (default: +;; CHECK-NEXT: 0) +;; CHECK-NEXT: +;; CHECK-NEXT: --ignore-implicit-traps,-iit Optimize under the helpful +;; CHECK-NEXT: assumption that no surprising +;; CHECK-NEXT: traps occur (from load, div/mod, +;; CHECK-NEXT: etc.) +;; CHECK-NEXT: +;; CHECK-NEXT: --traps-never-happen,-tnh Optimize under the helpful +;; CHECK-NEXT: assumption that no trap is +;; CHECK-NEXT: reached at runtime (from load, +;; CHECK-NEXT: div/mod, etc.) +;; CHECK-NEXT: +;; CHECK-NEXT: --low-memory-unused,-lmu Optimize under the helpful +;; CHECK-NEXT: assumption that the low 1K of +;; CHECK-NEXT: memory is not used by the +;; CHECK-NEXT: application +;; CHECK-NEXT: +;; CHECK-NEXT: --fast-math,-ffm Optimize floats without handling +;; CHECK-NEXT: corner cases of NaNs and +;; CHECK-NEXT: rounding +;; CHECK-NEXT: +;; CHECK-NEXT: --zero-filled-memory,-uim Assume that an imported memory +;; CHECK-NEXT: will be zero-initialized +;; CHECK-NEXT: +;; CHECK-NEXT: --skip-pass,-sp Skip a pass (do not run it) ;; CHECK-NEXT: ;; CHECK-NEXT: ;; CHECK-NEXT: Tool options: ;; CHECK-NEXT: ------------- ;; CHECK-NEXT: -;; CHECK-NEXT: --mvp-features,-mvp Disable all non-MVP features +;; CHECK-NEXT: --mvp-features,-mvp Disable all non-MVP features +;; CHECK-NEXT: +;; CHECK-NEXT: --all-features,-all Enable all features ;; CHECK-NEXT: -;; CHECK-NEXT: --all-features,-all Enable all features +;; CHECK-NEXT: --detect-features (deprecated - this flag does +;; CHECK-NEXT: nothing) ;; CHECK-NEXT: -;; CHECK-NEXT: --detect-features (deprecated - this flag does nothing) +;; CHECK-NEXT: --quiet,-q Emit less verbose output and +;; CHECK-NEXT: hide trivial warnings. ;; CHECK-NEXT: -;; CHECK-NEXT: --quiet,-q Emit less verbose output and hide trivial -;; CHECK-NEXT: warnings. +;; CHECK-NEXT: --experimental-poppy Parse wast files as Poppy IR for +;; CHECK-NEXT: testing purposes. ;; CHECK-NEXT: -;; CHECK-NEXT: --experimental-poppy Parse wast files as Poppy IR for testing -;; CHECK-NEXT: purposes. +;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-sign-ext Enable sign extension operations +;; CHECK-NEXT: --disable-sign-ext Disable sign extension +;; CHECK-NEXT: operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-sign-ext Disable sign extension operations +;; CHECK-NEXT: --enable-threads Enable atomic operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-threads Enable atomic operations +;; CHECK-NEXT: --disable-threads Disable atomic operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-threads Disable atomic operations +;; CHECK-NEXT: --enable-mutable-globals Enable mutable globals ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-mutable-globals Enable mutable globals +;; CHECK-NEXT: --disable-mutable-globals Disable mutable globals ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-mutable-globals Disable mutable globals +;; CHECK-NEXT: --enable-nontrapping-float-to-int Enable nontrapping float-to-int +;; CHECK-NEXT: operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-nontrapping-float-to-int Enable nontrapping float-to-int -;; CHECK-NEXT: operations +;; CHECK-NEXT: --disable-nontrapping-float-to-int Disable nontrapping float-to-int +;; CHECK-NEXT: operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-nontrapping-float-to-int Disable nontrapping float-to-int -;; CHECK-NEXT: operations +;; CHECK-NEXT: --enable-simd Enable SIMD operations and types ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-simd Enable SIMD operations and types +;; CHECK-NEXT: --disable-simd Disable SIMD operations and +;; CHECK-NEXT: types ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-simd Disable SIMD operations and types +;; CHECK-NEXT: --enable-bulk-memory Enable bulk memory operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-bulk-memory Enable bulk memory operations +;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations +;; CHECK-NEXT: --enable-exception-handling Enable exception handling +;; CHECK-NEXT: operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations +;; CHECK-NEXT: --disable-exception-handling Disable exception handling +;; CHECK-NEXT: operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations +;; CHECK-NEXT: --enable-tail-call Enable tail call operations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-tail-call Enable tail call operations +;; CHECK-NEXT: --disable-tail-call Disable tail call operations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-tail-call Disable tail call operations +;; CHECK-NEXT: --enable-reference-types Enable reference types ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-reference-types Enable reference types +;; CHECK-NEXT: --disable-reference-types Disable reference types ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-reference-types Disable reference types +;; CHECK-NEXT: --enable-multivalue Enable multivalue functions ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-multivalue Enable multivalue functions +;; CHECK-NEXT: --disable-multivalue Disable multivalue functions ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-multivalue Disable multivalue functions +;; CHECK-NEXT: --enable-gc Enable garbage collection ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-gc Enable garbage collection +;; CHECK-NEXT: --disable-gc Disable garbage collection ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-gc Disable garbage collection +;; CHECK-NEXT: --enable-memory64 Enable memory64 ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-memory64 Enable memory64 +;; CHECK-NEXT: --disable-memory64 Disable memory64 ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-memory64 Disable memory64 +;; CHECK-NEXT: --enable-relaxed-simd Enable relaxed SIMD ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-relaxed-simd Enable relaxed SIMD +;; CHECK-NEXT: --disable-relaxed-simd Disable relaxed SIMD ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-relaxed-simd Disable relaxed SIMD +;; CHECK-NEXT: --enable-extended-const Enable extended const +;; CHECK-NEXT: expressions ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-extended-const Enable extended const expressions +;; CHECK-NEXT: --disable-extended-const Disable extended const +;; CHECK-NEXT: expressions ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-extended-const Disable extended const expressions +;; CHECK-NEXT: --enable-strings Enable strings ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-strings Enable strings +;; CHECK-NEXT: --disable-strings Disable strings ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-strings Disable strings +;; CHECK-NEXT: --enable-multimemory Enable multimemory ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-multimemory Enable multimemory +;; CHECK-NEXT: --disable-multimemory Disable multimemory ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-multimemory Disable multimemory +;; CHECK-NEXT: --enable-typed-continuations Enable typed continuations ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-typed-continuations Enable typed continuations +;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-typed-continuations Disable typed continuations +;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-shared-everything Enable shared-everything threads +;; CHECK-NEXT: --disable-shared-everything Disable shared-everything +;; CHECK-NEXT: threads ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads +;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: -;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag +;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: -;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag +;; CHECK-NEXT: --no-validation,-n Disables validation, assumes +;; CHECK-NEXT: inputs are correct ;; CHECK-NEXT: -;; CHECK-NEXT: --no-validation,-n Disables validation, assumes inputs are -;; CHECK-NEXT: correct +;; CHECK-NEXT: --pass-arg,-pa An argument passed along to +;; CHECK-NEXT: optimization passes being run. +;; CHECK-NEXT: Must be in the form KEY@VALUE ;; CHECK-NEXT: -;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization -;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: --closed-world,-cw Assume code outside of the +;; CHECK-NEXT: module does not inspect or +;; CHECK-NEXT: interact with GC and function +;; CHECK-NEXT: references, even if they are +;; CHECK-NEXT: passed out. The outside may hold +;; CHECK-NEXT: on to them and pass them back +;; CHECK-NEXT: in, but not inspect their +;; CHECK-NEXT: contents or call them. ;; CHECK-NEXT: -;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does -;; CHECK-NEXT: not inspect or interact with GC and -;; CHECK-NEXT: function references, even if they are -;; CHECK-NEXT: passed out. The outside may hold on to -;; CHECK-NEXT: them and pass them back in, but not -;; CHECK-NEXT: inspect their contents or call them. +;; CHECK-NEXT: --generate-stack-ir generate StackIR during writing ;; CHECK-NEXT: -;; CHECK-NEXT: --generate-stack-ir generate StackIR during writing +;; CHECK-NEXT: --optimize-stack-ir optimize StackIR during writing ;; CHECK-NEXT: -;; CHECK-NEXT: --optimize-stack-ir optimize StackIR during writing +;; CHECK-NEXT: --print-stack-ir print StackIR during writing ;; CHECK-NEXT: -;; CHECK-NEXT: --print-stack-ir print StackIR during writing +;; CHECK-NEXT: --no-stack-ir do not use StackIR (even when it +;; CHECK-NEXT: is the default) ;; CHECK-NEXT: ;; CHECK-NEXT: ;; CHECK-NEXT: General options: ;; CHECK-NEXT: ---------------- ;; CHECK-NEXT: -;; CHECK-NEXT: --version Output version information and exit +;; CHECK-NEXT: --version Output version information and +;; CHECK-NEXT: exit ;; CHECK-NEXT: -;; CHECK-NEXT: --help,-h Show this help message and exit +;; CHECK-NEXT: --help,-h Show this help message and exit ;; CHECK-NEXT: -;; CHECK-NEXT: --debug,-d Print debug information to stderr +;; CHECK-NEXT: --debug,-d Print debug information to +;; CHECK-NEXT: stderr ;; CHECK-NEXT: diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 76566049e62..9f7caf98bee 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -759,6 +759,9 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --print-stack-ir print StackIR during writing ;; CHECK-NEXT: +;; CHECK-NEXT: --no-stack-ir do not use StackIR (even when it +;; CHECK-NEXT: is the default) +;; CHECK-NEXT: ;; CHECK-NEXT: ;; CHECK-NEXT: General options: ;; CHECK-NEXT: ---------------- diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 8e305cfb91d..ca731d27741 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -713,6 +713,9 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --print-stack-ir print StackIR during writing ;; CHECK-NEXT: +;; CHECK-NEXT: --no-stack-ir do not use StackIR (even when it +;; CHECK-NEXT: is the default) +;; CHECK-NEXT: ;; CHECK-NEXT: ;; CHECK-NEXT: General options: ;; CHECK-NEXT: ---------------- diff --git a/test/lit/passes/stack-ir-defaults.wast b/test/lit/passes/stack-ir-defaults.wast new file mode 100644 index 00000000000..1ea8bbf244b --- /dev/null +++ b/test/lit/passes/stack-ir-defaults.wast @@ -0,0 +1,66 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; Request StackIR explicitly. This optimizes. +;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=REQUESTED + +;; As above, but disallow it later. This does not optimize. +;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --no-stack-ir --print-stack-ir | filecheck %s --check-prefix=DISALLOWD + +;; As above, but flip it, so we allow it after disallowing. This optimizes. +;; RUN: wasm-opt %s --no-stack-ir --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=REALLOWED + +;; Running -O will use StackIR by default. This optimizes. +;; RUN: wasm-opt %s -O -all --print-stack-ir | filecheck %s --check-prefix=O_DEFAULT + +;; As above, but disallow it. This does not optimize. +;; RUN: wasm-opt %s -O --no-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=O__DENIED + +;; As above, but flip it. This still does not optimize, as the global state of +;; --no-stack-ir is not overridden (before we explicitly overrode it, while here +;; we -O only requests StackIR if allowed). +;; RUN: wasm-opt %s --no-stack-ir -O -all --print-stack-ir | filecheck %s --check-prefix=O_REALLOW + +(module + ;; REQUESTED: (import "a" "b" (func $import (type $0) (result i32))) + ;; DISALLOWD: (import "a" "b" (func $import (type $0) (result i32))) + ;; REALLOWED: (import "a" "b" (func $import (type $0) (result i32))) + ;; O_DEFAULT: (import "a" "b" (func $import (type $0) (result i32))) + ;; O__DENIED: (import "a" "b" (func $import (type $0) (result i32))) + ;; O_REALLOW: (import "a" "b" (func $import (type $0) (result i32))) + (import "a" "b" (func $import (result i32))) + + ;; REQUESTED: (func $func (type $0) (result i32) + ;; REQUESTED-NEXT: call $import + ;; REQUESTED-NEXT: unreachable + ;; REQUESTED-NEXT: ) + ;; DISALLOWD: (func $func (type $0) (result i32) + ;; DISALLOWD-NEXT: call $import + ;; DISALLOWD-NEXT: drop + ;; DISALLOWD-NEXT: unreachable + ;; DISALLOWD-NEXT: ) + ;; REALLOWED: (func $func (type $0) (result i32) + ;; REALLOWED-NEXT: call $import + ;; REALLOWED-NEXT: unreachable + ;; REALLOWED-NEXT: ) + ;; O_DEFAULT: (func $func (type $0) (result i32) + ;; O_DEFAULT-NEXT: call $import + ;; O_DEFAULT-NEXT: unreachable + ;; O_DEFAULT-NEXT: ) + ;; O__DENIED: (func $func (type $0) (result i32) + ;; O__DENIED-NEXT: call $import + ;; O__DENIED-NEXT: drop + ;; O__DENIED-NEXT: unreachable + ;; O__DENIED-NEXT: ) + ;; O_REALLOW: (func $func (type $0) (result i32) + ;; O_REALLOW-NEXT: call $import + ;; O_REALLOW-NEXT: drop + ;; O_REALLOW-NEXT: unreachable + ;; O_REALLOW-NEXT: ) + (func $func (export "func") (result i32) + ;; This drop can be removed when we optimize using StackIR. + (drop + (call $import) + ) + (unreachable) + ) +) From e05f7629a27220c9951acc511d6f68a49e7b25d9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 11 Jul 2024 09:34:24 -0700 Subject: [PATCH 428/553] [WasmGC] Heap2Local: Optimize RefIs and RefTest (#6705) --- src/passes/Heap2Local.cpp | 63 +++++- test/lit/passes/heap2local.wast | 389 ++++++++++++++++++++++++++++++-- 2 files changed, 438 insertions(+), 14 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 39c77bec489..7aec23ccf1a 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -349,6 +349,12 @@ struct EscapeAnalyzer { void visitLocalSet(LocalSet* curr) { escapes = false; } // Reference operations. TODO add more + void visitRefIsNull(RefIsNull* curr) { + // The reference is compared to null, but nothing more. + escapes = false; + fullyConsumes = true; + } + void visitRefEq(RefEq* curr) { // The reference is compared for identity, but nothing more. escapes = false; @@ -367,6 +373,11 @@ struct EscapeAnalyzer { } } + void visitRefTest(RefTest* curr) { + escapes = false; + fullyConsumes = true; + } + void visitRefCast(RefCast* curr) { // As it is our allocation that flows through here, we need to // check that the cast will not trap, so that we can continue @@ -707,6 +718,17 @@ struct Struct2Local : PostWalker { replaceCurrent(builder.makeBlock(contents)); } + void visitRefIsNull(RefIsNull* curr) { + if (!analyzer.reached.count(curr)) { + return; + } + + // The result must be 0, since the allocation is not null. Drop the RefIs + // and append that. + replaceCurrent(builder.makeSequence( + builder.makeDrop(curr), builder.makeConst(Literal(int32_t(0))))); + } + void visitRefEq(RefEq* curr) { if (!analyzer.reached.count(curr)) { return; @@ -739,6 +761,23 @@ struct Struct2Local : PostWalker { replaceCurrent(curr->value); } + void visitRefTest(RefTest* curr) { + if (!analyzer.reached.count(curr)) { + return; + } + + // This test operates on the allocation, which means we can compute whether + // it will succeed statically. We do not even need + // GCTypeUtils::evaluateCastCheck because we know the allocation's type + // precisely (it cannot be a strict subtype of the type - it is the type). + int32_t result = Type::isSubType(allocation->type, curr->castType); + // Remove the RefTest and leave only its reference child. If we kept it, + // we'd need to refinalize (as the input to the test changes, since the + // reference becomes a null, which has a different type). + replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref), + builder.makeConst(Literal(result)))); + } + void visitRefCast(RefCast* curr) { if (!analyzer.reached.count(curr)) { return; @@ -820,12 +859,15 @@ struct Array2Struct : PostWalker { EscapeAnalyzer& analyzer; Function* func; Builder builder; + // The original type of the allocation, before we turn it into a struct. + Type originalType; Array2Struct(Expression* allocation, EscapeAnalyzer& analyzer, Function* func, Module& wasm) - : allocation(allocation), analyzer(analyzer), func(func), builder(wasm) { + : allocation(allocation), analyzer(analyzer), func(func), builder(wasm), + originalType(allocation->type) { // Build the struct type we need: as many fields as the size of the array, // all of the same type as the array's element. @@ -989,6 +1031,25 @@ struct Array2Struct : PostWalker { noteCurrentIsReached(); } + // Some additional operations need special handling + void visitRefTest(RefTest* curr) { + if (!analyzer.reached.count(curr)) { + return; + } + + // When we ref.test an array allocation, we cannot simply turn the array + // into a struct, as then the test will behave different. (Note that this is + // not a problem for ref.*cast*, as the cast simply goes away when the value + // flows through, and we verify it will do so in the escape analysis.) To + // handle this, check if the test succeeds or not, and write out the outcome + // here (similar to Struct2Local::visitRefTest). Note that we test on + // |originalType| here and not |allocation->type|, as the allocation has + // been turned into a struct. + int32_t result = Type::isSubType(originalType, curr->castType); + replaceCurrent(builder.makeSequence(builder.makeDrop(curr), + builder.makeConst(Literal(result)))); + } + // Get the value in an expression we know must contain a constant index. Index getIndex(Expression* curr) { return curr->cast()->value.getUnsigned(); diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index bd613e18c4b..d642aabb3da 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -4,8 +4,10 @@ ;; RUN: foreach %s %t wasm-opt -all --remove-unused-names --heap2local -S -o - | filecheck %s (module - ;; CHECK: (type $struct.A (struct (field (mut i32)) (field (mut f64)))) - (type $struct.A (struct (field (mut i32)) (field (mut f64)))) + ;; CHECK: (type $struct.A (sub (struct (field (mut i32)) (field (mut f64))))) + (type $struct.A (sub (struct (field (mut i32)) (field (mut f64))))) + + (type $struct.B (sub $struct.A (struct (field (mut i32)) (field (mut f64))))) ;; CHECK: (type $1 (func)) @@ -40,6 +42,10 @@ ;; CHECK: (type $13 (func (param eqref eqref) (result i32))) + ;; CHECK: (type $14 (func (param anyref) (result i32))) + + ;; CHECK: (type $15 (func (param anyref))) + ;; CHECK: (func $simple (type $1) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) @@ -2382,6 +2388,251 @@ ) ) ) + + ;; CHECK: (func $ref-is (type $14) (param $x anyref) (result i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_null + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.is_null + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-is (param $x anyref) (result i32) + ;; A ref.is that we can do nothing for, and should not modify, even though + ;; we optimize later. + (drop + (ref.is_null + (local.get $x) + ) + ) + ;; The result is 0 as the allocation is not null, and we can remove the + ;; allocation. + (ref.is_null + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + + ;; CHECK: (func $ref-test (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 f64) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 f64) + ;; CHECK-NEXT: (local $8 i32) + ;; CHECK-NEXT: (local $9 f64) + ;; CHECK-NEXT: (local $10 i32) + ;; CHECK-NEXT: (local $11 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (f64.const 2.2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (f64.const 4.4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-test + ;; This cast must succeed (it tests the exact type), and we can remove the + ;; allocation. + (drop + (ref.test (ref $struct.A) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + ;; Testing a supertype also works. + (drop + (ref.test (ref null $struct.A) + (struct.new $struct.A + (i32.const 1) + (f64.const 2.2) + ) + ) + ) + (drop + (ref.test (ref null any) + (struct.new $struct.A + (i32.const 3) + (f64.const 4.4) + ) + ) + ) + ) + ;; CHECK: (func $ref-test-bad (type $15) (param $x anyref) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 f64) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local $8 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.test (ref $struct.A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (f64.const 2.2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-test-bad (param $x anyref) + ;; We know nothing about this cast. + (drop + (ref.test (ref $struct.A) + (local.get $x) + ) + ) + ;; These casts must fail, but we can remove the allocation. + (drop + (ref.test (ref $struct.B) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + (drop + (ref.test (ref null $struct.B) + (struct.new $struct.A + (i32.const 1) + (f64.const 2.2) + ) + ) + ) + ) ) (module @@ -2662,9 +2913,9 @@ ;; CHECK: (type $1 (struct (field (mut i32)))) - ;; CHECK: (type $2 (func (result i32))) + ;; CHECK: (type $2 (func)) - ;; CHECK: (type $3 (func)) + ;; CHECK: (type $3 (func (result i32))) ;; CHECK: (type $4 (func (param i32) (result i32))) @@ -2678,7 +2929,9 @@ ;; CHECK: (type $9 (struct (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)))) - ;; CHECK: (func $array.new_default (type $3) + ;; CHECK: (type $10 (func (param anyref))) + + ;; CHECK: (func $array.new_default (type $2) ;; CHECK-NEXT: (local $temp (ref $array)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -2818,7 +3071,7 @@ ) ) - ;; CHECK: (func $array.new (type $2) (result i32) + ;; CHECK: (func $array.new (type $3) (result i32) ;; CHECK-NEXT: (local $temp (ref $array)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3000,7 +3253,7 @@ ) ) - ;; CHECK: (func $array.local.super (type $3) + ;; CHECK: (func $array.local.super (type $2) ;; CHECK-NEXT: (local $temp anyref) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3049,7 +3302,7 @@ ) ) - ;; CHECK: (func $array.folded (type $2) (result i32) + ;; CHECK: (func $array.folded (type $3) (result i32) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3130,7 +3383,7 @@ ) ) - ;; CHECK: (func $array.folded.multiple (type $3) + ;; CHECK: (func $array.folded.multiple (type $2) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3383,7 +3636,7 @@ ) ) - ;; CHECK: (func $array.nested.refinalize.get (type $2) (result i32) + ;; CHECK: (func $array.nested.refinalize.get (type $3) (result i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) @@ -3403,7 +3656,7 @@ ) ) - ;; CHECK: (func $array.nested.refinalize.set (type $3) + ;; CHECK: (func $array.nested.refinalize.set (type $2) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) @@ -3425,7 +3678,7 @@ ) ) - ;; CHECK: (func $array.flowing.type (type $2) (result i32) + ;; CHECK: (func $array.flowing.type (type $3) (result i32) ;; CHECK-NEXT: (local $temp (ref $array)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) @@ -3511,13 +3764,123 @@ ) ) - ;; CHECK: (func $get-i32 (type $2) (result i32) + ;; CHECK: (func $get-i32 (type $3) (result i32) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) (func $get-i32 (result i32) ;; Helper for the above. (i32.const 1337) ) + + ;; CHECK: (func $ref-test (type $2) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-test + ;; This cast must succeed (it tests the exact type), and we can remove the + ;; allocation. + (drop + (ref.test (ref $array) + (array.new_default $array + (i32.const 1) + ) + ) + ) + ;; Testing a supertype also works. + (drop + (ref.test (ref null any) + (array.new_default $array + (i32.const 2) + ) + ) + ) + ) + ;; CHECK: (func $ref-test-bad (type $10) (param $x anyref) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.test (ref $array) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-test-bad (param $x anyref) + ;; We know nothing about this cast. + (drop + (ref.test (ref $array) + (local.get $x) + ) + ) + ;; This cast fails, but we can remove the allocation. + (drop + (ref.test (ref struct) + (array.new_default $array + (i32.const 2) + ) + ) + ) + ) ) ;; Arrays with reference values. From 5a1daf7727e768acebedd57464d2e0788afc85c5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 11 Jul 2024 10:31:31 -0700 Subject: [PATCH 429/553] Monomorphization: Optimize constants (#6711) Previously the pass would monomorphize a call when we were sending more refined types than the target expects. This generalizes the pass to also consider the case where we send a constant in a parameter. To achieve that, this refactors the pass to explicitly define the "call context", which is the code around the call (inputs and outputs) that may end up leading to optimization opportunities when combined with the target function. Also add comments about the overall design + roadmap. The existing test is mostly unmodified, and the diff there is smaller when ignoring whitespace. We do "regress" those tests by adding more local.set operations, as in the refactoring that makes things a lot simpler, that is, to handle the general case of an operand having either a refined type or be a constant, we copy it inside the function, which works either way. This "regression" is only in the testing version of the pass (the normal version runs optimizations, which would remove that extra code). This also enables the pass when GC is disabled. Previously we only handled refined types, so only GC could benefit. Add a test for MVP content specifically to show we operate there as well. --- src/ir/manipulation.h | 4 + src/ir/module-utils.cpp | 11 +- src/ir/module-utils.h | 7 + src/passes/Monomorphize.cpp | 517 +++++++++++--- test/lit/passes/monomorphize-consts.wast | 635 ++++++++++++++++++ test/lit/passes/monomorphize-mvp.wast | 94 +++ ...omorphize.wast => monomorphize-types.wast} | 87 ++- .../no-inline-monomorphize-inlining.wast | 37 +- 8 files changed, 1268 insertions(+), 124 deletions(-) create mode 100644 test/lit/passes/monomorphize-consts.wast create mode 100644 test/lit/passes/monomorphize-mvp.wast rename test/lit/passes/{monomorphize.wast => monomorphize-types.wast} (89%) diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h index 33c7d1bd712..64cd15dc3ce 100644 --- a/src/ir/manipulation.h +++ b/src/ir/manipulation.h @@ -64,6 +64,10 @@ inline OutputType* convert(InputType* input, MixedArena& allocator) { return output; } +// Copy using a flexible custom copy function. This function is called on each +// expression before copying it. If it returns a non-null value then that is +// used (effectively overriding the normal copy), and if it is null then we do a +// normal copy. using CustomCopier = std::function; Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom); diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 5791ed77c66..8ad1270864d 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -46,6 +46,15 @@ Function* copyFunction(Function* func, Module& out, Name newName, std::optional> fileIndexMap) { + auto ret = copyFunctionWithoutAdd(func, out, newName, fileIndexMap); + return out.addFunction(std::move(ret)); +} + +std::unique_ptr +copyFunctionWithoutAdd(Function* func, + Module& out, + Name newName, + std::optional> fileIndexMap) { auto ret = std::make_unique(); ret->name = newName.is() ? newName : func->name; ret->hasExplicitName = func->hasExplicitName; @@ -71,7 +80,7 @@ Function* copyFunction(Function* func, ret->base = func->base; ret->noFullInline = func->noFullInline; ret->noPartialInline = func->noPartialInline; - return out.addFunction(std::move(ret)); + return ret; } Global* copyGlobal(Global* global, Module& out) { diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 0a101e5da75..d9fd69428ea 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -33,6 +33,13 @@ copyFunction(Function* func, Name newName = Name(), std::optional> fileIndexMap = std::nullopt); +// As above, but does not add the copy to the module. +std::unique_ptr copyFunctionWithoutAdd( + Function* func, + Module& out, + Name newName = Name(), + std::optional> fileIndexMap = std::nullopt); + Global* copyGlobal(Global* global, Module& out); Tag* copyTag(Tag* tag, Module& out); diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index 012f247504b..5237f786450 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -15,24 +15,58 @@ */ // -// When we see a call foo(arg1, arg2) and at least one of the arguments has a -// more refined type than is declared in the function being called, create a -// copy of the function with the refined type. That copy can then potentially be -// optimized in useful ways later. +// Monomorphization of code based on callsite context: When we see a call, see +// if the information at the callsite can help us optimize. For example, if a +// parameter is constant, then using that constant in the called function may +// unlock a lot of improvements. We may benefit from monomorphizing in the +// following cases: // -// Inlining also monomorphizes in effect. What this pass does is handle the -// cases where inlining cannot be done. +// * If a call provides a more refined type than the function declares for a +// parameter. +// * If a call provides a constant as a parameter. +// * If a call provides a GC allocation as a parameter. TODO +// * If a call is dropped. TODO also other stuff on the outside? // -// To see when monomorphizing makes sense, this optimizes the target function -// both with and without the more refined types. If the refined types help then -// the version with might remove a cast, for example. Note that while doing so -// we keep the optimization results of the version without - there is no reason -// to forget them since we've gone to the trouble anyhow. So this pass may have -// the side effect of performing minor optimizations on functions. There is also -// a variant of the pass that always monomorphizes, even when it does not seem -// helpful, which is useful for testing, and possibly in cases where we need -// more than just local optimizations to see the benefit - for example, perhaps -// GUFA ends up more powerful later on. +// We realize the benefit by creating a monomorphized (specialized/refined) +// version of the function, and call that instead. For example, if we have +// +// function foo(x) { return x + 22; } +// foo(7); +// +// then monomorphization leads to this: +// +// function foo(x) { return x + 22; } // original unmodified function +// foo_b(); // now calls foo_b +// function foo_b() { return 7 + 22; } // monomorphized, constant 7 applied +// +// This is related to inlining both conceptually and practically. Conceptually, +// one of inlining's big advantages is that we then optimize the called code +// together with the code around the call, and monomorphization does something +// similar. And, this pass does so by "reverse-inlining" content from the +// caller to the monomorphized function: the constant 7 in the example above has +// been "pulled in" from the caller into the callee. Larger amounts of code can +// be moved in that manner, both values sent to the function, and the code that +// receives it (see the mention of dropped calls, before). +// +// As this monormophization uses callsite context (the parameters, where the +// result flows to), we call it "Contextual Monomorphization." The full name is +// "Empirical Contextural Monomorphization" because we decide where to optimize +// based on a "try it and see" (empirical) approach, that measures the benefit. +// That is, we generate the monomorphized function as explained, then optimize +// that function, which contains the original code + code from the callsite +// context that we pulled in. If the optimizer manages to improve that combined +// code in a useful way then we apply the optimization, and if not then we undo. +// +// The empirical approach significantly reduces the need for heuristics. For +// example, rather than have a heuristic for "see if a constant parameter flows +// into a conditional branch," we simply run the optimizer and let it optimize +// that case. All other cases handled by the optimizer work as well, without +// needing to specify them as heuristics, so this gets smarter as the optimizer +// does. +// +// Aside from the main version of this pass there is also a variant useful for +// testing that always monomorphizes non-trivial callsites, without checking if +// the optimizer can help or not (that makes writing testcases simpler). // // TODO: When we optimize we could run multiple cycles: A calls B calls C might // end up with the refined+optimized B now having refined types in its @@ -47,25 +81,21 @@ // end on leaves. That would make it more likely for a single iteration to // do more work, as if A->B->C then we'd do A->B and optimize B and only // then look at B->C. -// TODO: Also run the result-refining part of SignatureRefining, as if we -// refine the result then callers of the function may benefit, even if -// there is no benefit in the function itself. // TODO: If this is too slow, we could "group" things, for example we could // compute the LUB of a bunch of calls to a target and then investigate // that one case and use it in all those callers. // TODO: Not just direct calls? But updating vtables is complex. -// TODO: Not just types? We could monomorphize using Literal values. E.g. for -// function references, if we monomorphized we'd end up specializing qsort -// for the particular functions it is given. // #include "ir/cost.h" #include "ir/find_all.h" +#include "ir/manipulation.h" #include "ir/module-utils.h" #include "ir/names.h" #include "ir/type-updating.h" #include "ir/utils.h" #include "pass.h" +#include "support/hash.h" #include "wasm-type.h" #include "wasm.h" @@ -73,18 +103,200 @@ namespace wasm { namespace { +// Relevant information about a callsite for purposes of monomorphization. +struct CallContext { + // The operands of the call, processed to leave the parts that make sense to + // keep in the context. That is, the operands of the CallContext are the exact + // code that will appear at the start of the monomorphized function. For + // example: + // + // (call $foo + // (i32.const 10) + // (..something complicated..) + // ) + // (func $foo (param $int i32) (param $complex f64) + // .. + // + // The context operands are + // + // [ + // (i32.const 10) ;; Unchanged: this can be pulled into the called + // ;; function, and removed from the caller side. + // (local.get $0) ;; The complicated child cannot; keep it as a value + // ;; sent from the caller, which we will local.get. + // ] + // + // Both the const and the local.get are simply used in the monomorphized + // function, like this: + // + // (func $foo-monomorphized (param $0 ..) + // (..local defs..) + // ;; Apply the first operand, which was pulled into here. + // (local.set $int + // (i32.const 10) + // ) + // ;; Read the second, which remains a parameter to the function. + // (local.set $complex + // (local.get $0) + // ) + // ;; The original body. + // .. + // + // The $int param is no longer a parameter, and it is set in a local at the + // top: we have "reverse-inlined" code from the calling function into the + // caller, pulling the constant 10 into here. The second parameter cannot be + // pulled in, so we must still send it, but we still have a local.set there to + // copy it into a local (this does not matter in this case, but does if the + // sent value is more refined; always using a local.set is simpler and more + // regular). + std::vector operands; + + // Whether the call is dropped. TODO + bool dropped; + + bool operator==(const CallContext& other) const { + if (dropped != other.dropped) { + return false; + } + + // We consider logically equivalent expressions as equal (rather than raw + // pointers), so that contexts with functionally identical shape are + // treated the same. + if (operands.size() != other.operands.size()) { + return false; + } + for (Index i = 0; i < operands.size(); i++) { + if (!ExpressionAnalyzer::equal(operands[i], other.operands[i])) { + return false; + } + } + + return true; + } + + bool operator!=(const CallContext& other) const { return !(*this == other); } + + // Build the context from a given call. This builds up the context operands as + // as explained in the comments above, and updates the call to send any + // remaining values by updating |newOperands| (for example, if all the values + // sent are constants, then |newOperands| will end up empty, as we have + // nothing left to send). + void buildFromCall(Call* call, + std::vector& newOperands, + Module& wasm) { + Builder builder(wasm); + + for (auto* operand : call->operands) { + // Process the operand. This is a copy operation, as we are trying to move + // (copy) code from the callsite into the called function. When we find we + // can copy then we do so, and when we cannot that value remains as a + // value sent from the call. + operands.push_back(ExpressionManipulator::flexibleCopy( + operand, wasm, [&](Expression* child) -> Expression* { + if (canBeMovedIntoContext(child)) { + // This can be moved, great: let the copy happen. + return nullptr; + } + + // This cannot be moved, so we stop here: this is a value that is sent + // into the monomorphized function. It is a new operand in the call, + // and in the context operands it is a local.get, that reads that + // value. + auto paramIndex = newOperands.size(); + newOperands.push_back(child); + // TODO: If one operand is a tee and another a get, we could actually + // reuse the local, effectively showing the monomorphized + // function that the values are the same. (But then the checks + // later down to is would need to check index too.) + return builder.makeLocalGet(paramIndex, child->type); + })); + } + + // TODO: handle drop + dropped = false; + } + + // Checks whether an expression can be moved into the context. + bool canBeMovedIntoContext(Expression* curr) { + // Constant numbers, funcs, strings, etc. can all be copied, so it is ok to + // add them to the context. + // TODO: Allow global.get as well, and anything else that is purely + // copyable. + return Properties::isSingleConstantExpression(curr); + } + + // Check if a context is trivial relative to a call, that is, the context + // contains no information that can allow optimization at all. Such trivial + // contexts can be dismissed early. + bool isTrivial(Call* call, Module& wasm) { + // Dropped contexts are not trivial. + if (dropped) { + return false; + } + + // The context must match the call for us to compare them. + assert(operands.size() == call->operands.size()); + + // If an operand is not simply passed through, then we are not trivial. + auto callParams = wasm.getFunction(call->target)->getParams(); + for (Index i = 0; i < operands.size(); i++) { + // A local.get of the same type implies we just pass through the value. + // Anything else is not trivial. + if (!operands[i]->is() || operands[i]->type != callParams[i]) { + return false; + } + } + + // We found nothing interesting, so this is trivial. + return true; + } +}; + +} // anonymous namespace + +} // namespace wasm + +namespace std { + +template<> struct hash { + size_t operator()(const wasm::CallContext& info) const { + size_t digest = hash{}(info.dropped); + + wasm::rehash(digest, info.operands.size()); + for (auto* operand : info.operands) { + wasm::hash_combine(digest, wasm::ExpressionAnalyzer::hash(operand)); + } + + return digest; + } +}; + +// Useful for debugging. +[[maybe_unused]] void dump(std::ostream& o, wasm::CallContext& context) { + o << "CallContext{\n"; + for (auto* operand : context.operands) { + o << " " << *operand << '\n'; + } + if (context.dropped) { + o << " dropped\n"; + } + o << "}\n"; +} + +} // namespace std + +namespace wasm { + +namespace { + struct Monomorphize : public Pass { - // If set, we run some opts to see if monomorphization helps, and skip it if - // not. + // If set, we run some opts to see if monomorphization helps, and skip cases + // where we do not help out. bool onlyWhenHelpful; Monomorphize(bool onlyWhenHelpful) : onlyWhenHelpful(onlyWhenHelpful) {} void run(Module* module) override { - if (!module->features.hasGC()) { - return; - } - // TODO: parallelize, see comments below // Note the list of all functions. We'll be adding more, and do not want to @@ -94,7 +306,7 @@ struct Monomorphize : public Pass { *module, [&](Function* func) { funcNames.push_back(func->name); }); // Find the calls in each function and optimize where we can, changing them - // to call more refined targets. + // to call the monomorphized targets. for (auto name : funcNames) { auto* func = module->getFunction(name); for (auto* call : FindAll(func->body).list) { @@ -110,59 +322,67 @@ struct Monomorphize : public Pass { continue; } - call->target = getRefinedTarget(call, module); + processCall(call, *module); } } } - // Given a call, make a copy of the function it is calling that has more - // refined arguments that fit the arguments being passed perfectly. - Name getRefinedTarget(Call* call, Module* module) { + // Try to optimize a call. + void processCall(Call* call, Module& wasm) { auto target = call->target; - auto* func = module->getFunction(target); + auto* func = wasm.getFunction(target); if (func->imported()) { // Nothing to do since this calls outside of the module. - return target; - } - auto params = func->getParams(); - bool hasRefinedParam = false; - for (Index i = 0; i < call->operands.size(); i++) { - if (call->operands[i]->type != params[i]) { - hasRefinedParam = true; - break; - } - } - if (!hasRefinedParam) { - // Nothing to do since all params are fully refined already. - return target; + return; } - std::vector refinedTypes; - for (auto* operand : call->operands) { - refinedTypes.push_back(operand->type); - } - auto refinedParams = Type(refinedTypes); - auto iter = funcParamMap.find({target, refinedParams}); - if (iter != funcParamMap.end()) { - return iter->second; + // TODO: ignore calls with unreachable operands for simplicty + + // Compute the call context, and the new operands that the call would send + // if we use that context. + CallContext context; + std::vector newOperands; + context.buildFromCall(call, newOperands, wasm); + + // See if we've already evaluated this function + call context. If so, then + // we've memoized the result. + auto iter = funcContextMap.find({target, context}); + if (iter != funcContextMap.end()) { + auto newTarget = iter->second; + if (newTarget != target) { + // When we computed this before we found a benefit to optimizing, and + // created a new monomorphized function to call. Use it by simply + // applying the new operands we computed, and adjusting the call target. + call->operands.set(newOperands); + call->target = newTarget; + } + return; } - // This is the first time we see this situation. Let's see if it is worth - // monomorphizing. + // This is the first time we see this situation. First, check if the context + // is trivial and has no opportunities for optimization. + if (context.isTrivial(call, wasm)) { + // Memoize the failure, and stop. + funcContextMap[{target, context}] = target; + return; + } - // Create a new function with refined parameters as a copy of the original. - auto refinedTarget = Names::getValidFunctionName(*module, target); - auto* refinedFunc = ModuleUtils::copyFunction(func, *module, refinedTarget); - TypeUpdating::updateParamTypes(refinedFunc, refinedTypes, *module); - refinedFunc->type = HeapType(Signature(refinedParams, func->getResults())); + // Create the monomorphized function that includes the call context. + std::unique_ptr monoFunc = + makeMonoFunctionWithContext(func, context, wasm); - // Assume we'll choose to use the refined target, but if we are being - // careful then we might change our mind. - auto chosenTarget = refinedTarget; + // Decide whether it is worth using the monomorphized function. + auto worthwhile = true; if (onlyWhenHelpful) { // Optimize both functions using minimal opts, hopefully enough to see if - // there is a benefit to the refined types (such as the new types allowing - // a cast to be removed). + // there is a benefit to the context. We optimize both to avoid confusion + // from the function benefiting from simply running another cycle of + // optimization. + // + // Note that we do *not* discard the optimizations to the original + // function if we decide not to optimize. We've already done them, and the + // function is improved, so we may as well keep them. + // // TODO: Atm this can be done many times per function as it is once per // function and per set of types sent to it. Perhaps have some // total limit to avoid slow runtimes. @@ -181,23 +401,155 @@ struct Monomorphize : public Pass { // keep optimizing from the current contents as we go. It's not // obvious which approach is best here. doMinimalOpts(func); - doMinimalOpts(refinedFunc); + doMinimalOpts(monoFunc.get()); auto costBefore = CostAnalyzer(func->body).cost; - auto costAfter = CostAnalyzer(refinedFunc->body).cost; + auto costAfter = CostAnalyzer(monoFunc->body).cost; + // TODO: We should probably only accept improvements above some minimum, + // to avoid optimizing cases where we duplicate a huge function but + // only optimize a tiny part of it compared to the original. if (costAfter >= costBefore) { - // We failed to improve. Remove the new function and return the old - // target. - module->removeFunction(refinedTarget); - chosenTarget = target; + worthwhile = false; } } - // Mark the chosen target in the map, so we don't do this work again: every - // pair of target and refinedParams is only considered once. - funcParamMap[{target, refinedParams}] = chosenTarget; + // Memoize what we decided to call here. + funcContextMap[{target, context}] = worthwhile ? monoFunc->name : target; + + if (worthwhile) { + // We are using the monomorphized function, so update the call and add it + // to the module. + call->operands.set(newOperands); + call->target = monoFunc->name; + + wasm.addFunction(std::move(monoFunc)); + } + } + + // Create a monomorphized function from the original + the call context. It + // may have different parameters, results, and may include parts of the call + // context. + std::unique_ptr makeMonoFunctionWithContext( + Function* func, const CallContext& context, Module& wasm) { + + // The context has an operand for each one in the old function, each of + // which may contain reverse-inlined content. A mismatch here means we did + // not build the context right, or are using it with the wrong function. + assert(context.operands.size() == func->getNumParams()); + + // Pick a new name. + auto newName = Names::getValidFunctionName(wasm, func->name); + + // Copy the function as the base for the new one. + auto newFunc = ModuleUtils::copyFunctionWithoutAdd(func, wasm, newName); + + // Generate the new signature, and apply it to the new function. + std::vector newParams; + for (auto* operand : context.operands) { + // A local.get is a value that arrives in a parameter. Anything else is + // something that we are reverse-inlining into the function, so we don't + // need a param for it. + if (operand->is()) { + newParams.push_back(operand->type); + } + } + // TODO: support changes to results. + auto newResults = func->getResults(); + newFunc->type = Signature(Type(newParams), newResults); + + // We must update local indexes: the new function has a potentially + // different number of parameters, and parameters are at the very bottom of + // the local index space. We are also replacing old params with vars. To + // track this, map each old index to the new one. + std::unordered_map mappedLocals; + auto newParamsMinusOld = + newFunc->getParams().size() - func->getParams().size(); + for (Index i = 0; i < func->getNumLocals(); i++) { + if (func->isParam(i)) { + // Old params become new vars inside the function. Below we'll copy the + // proper values into these vars. + // TODO: We could avoid a var + copy when it is trivial (atm we rely on + // optimizations to remove it). + auto local = Builder::addVar(newFunc.get(), func->getLocalType(i)); + mappedLocals[i] = local; + } else { + // This is a var. The only thing to adjust here is that the parameters + // are changing. + mappedLocals[i] = i + newParamsMinusOld; + } + } + + // Copy over local names to help debugging. + if (!func->localNames.empty()) { + newFunc->localNames.clear(); + newFunc->localIndices.clear(); + for (Index i = 0; i < func->getNumLocals(); i++) { + auto oldName = func->getLocalNameOrDefault(i); + if (oldName.isNull()) { + continue; + } + + auto newIndex = mappedLocals[i]; + auto newName = Names::getValidLocalName(*newFunc.get(), oldName); + newFunc->localNames[newIndex] = newName; + newFunc->localIndices[newName] = newIndex; + } + }; + + Builder builder(wasm); + + // Surrounding the main body is the reverse-inlined content from the call + // context, like this: + // + // (func $monomorphized + // (..reverse-inlined parameter..) + // (..old body..) + // ) + // + // For example, if a function that simply returns its input is called with a + // constant parameter, it will end up like this: + // + // (func $monomorphized + // (local $param i32) + // (local.set $param (i32.const 42)) ;; reverse-inlined parameter + // (local.get $param) ;; copied old body + // ) + // + // We need to add such an local.set in the prelude of the function for each + // operand in the context. + std::vector pre; + for (Index i = 0; i < context.operands.size(); i++) { + auto* operand = context.operands[i]; + + // Write the context operand (the reverse-inlined content) to the local + // we've allocated for this. + auto local = mappedLocals.at(i); + auto* value = ExpressionManipulator::copy(operand, wasm); + pre.push_back(builder.makeLocalSet(local, value)); + } + + // Map locals. + struct LocalUpdater : public PostWalker { + const std::unordered_map& mappedLocals; + LocalUpdater(const std::unordered_map& mappedLocals) + : mappedLocals(mappedLocals) {} + void visitLocalGet(LocalGet* curr) { updateIndex(curr->index); } + void visitLocalSet(LocalSet* curr) { updateIndex(curr->index); } + void updateIndex(Index& index) { + auto iter = mappedLocals.find(index); + assert(iter != mappedLocals.end()); + index = iter->second; + } + } localUpdater(mappedLocals); + localUpdater.walk(newFunc->body); + + if (!pre.empty()) { + // Add the block after the prelude. + pre.push_back(newFunc->body); + newFunc->body = builder.makeBlock(pre); + } - return chosenTarget; + return newFunc; } // Run minimal function-level optimizations on a function. This optimizes at @@ -219,19 +571,20 @@ struct Monomorphize : public Pass { // the entire point is that parameters now have more refined types, which // can lead to locals reading them being refinable as well. runner.add("local-subtyping"); + // TODO: we need local propagation and escape analysis etc. -O3? runner.addDefaultFunctionOptimizationPasses(); runner.setIsNested(true); runner.runOnFunction(func); } - // Maps [func name, param types] to the name of a new function whose params - // have those types. + // Maps [func name, call info] to the name of a new function which is a + // monomorphization of that function, specialized to that call info. // - // Note that this can contain funcParamMap{A, types} = A, that is, that maps + // Note that this can contain funcContextMap{A, ...} = A, that is, that maps // a function name to itself. That indicates we found no benefit from - // refining with those particular types, and saves us from computing it again + // monomorphizing with that context, and saves us from computing it again // later on. - std::unordered_map, Name> funcParamMap; + std::unordered_map, Name> funcContextMap; }; } // anonymous namespace diff --git a/test/lit/passes/monomorphize-consts.wast b/test/lit/passes/monomorphize-consts.wast new file mode 100644 index 00000000000..1dbdf15921c --- /dev/null +++ b/test/lit/passes/monomorphize-consts.wast @@ -0,0 +1,635 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; As in monomorphize-types.wast, test in both "always" mode, which always +;; monomorphizes, and in "careful" mode which does it only when it appears to +;; actually help. + +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL + +(module + ;; Test that constants are monomorphized. + + ;; ALWAYS: (type $0 (func (param i32))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (type $2 (func (param i32 i32 funcref stringref))) + + ;; ALWAYS: (type $3 (func (param i32) (result i32))) + + ;; ALWAYS: (type $4 (func (result i32))) + + ;; ALWAYS: (import "a" "b" (func $import (type $0) (param i32))) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32 i32 funcref stringref))) + + ;; CAREFUL: (type $2 (func (param i32))) + + ;; CAREFUL: (type $3 (func (param i32) (result i32))) + + ;; CAREFUL: (import "a" "b" (func $import (type $2) (param i32))) + (import "a" "b" (func $import (param i32))) + + ;; ALWAYS: (elem declare func $calls) + + ;; ALWAYS: (func $calls (type $1) + ;; ALWAYS-NEXT: (call $target_9 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $target_9 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $target_10 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (elem declare func $calls) + + ;; CAREFUL: (func $calls (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.const 3) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $calls + ;; All but the eqz parameter are constants that can be handled. In ALWAYS + ;; mode we optimize and remove all but that one. In CAREFUL mode we end up + ;; not doing anything, as the target function's body optimizes out anyhow + ;; (so there is no benefit from monomorphization, after opts). + (call $target + (i32.const 1) + (i32.eqz + (i32.const 2) + ) + (ref.func $calls) + (string.const "foo") + ) + + ;; This has the same effective call context, as the constants are identical, + ;; and the non-constant is different, which we keep as a variable anyhow. + ;; This will call the same refined function as the previous call. + (call $target + (i32.const 1) + (i32.eqz + (i32.const 3) ;; this changed + ) + (ref.func $calls) + (string.const "foo") + ) + + ;; This has a different call context: one constant is different, so we'll + ;; call a different refined function. + (call $target + (i32.const 3) ;; this changed + (i32.eqz + (i32.const 2) + ) + (ref.func $calls) + (string.const "foo") + ) + ) + + ;; ALWAYS: (func $more-calls (type $1) + ;; ALWAYS-NEXT: (call $target_9 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 999) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $other-target_11 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 999) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $work_12 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 999) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $more-calls (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 999) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $other-target + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 999) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $work_9 + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 999) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $more-calls + ;; Identical to the first call in the previous function (except for the non- + ;; constant second param, which is ok to be different). We should call the + ;; same refined function before, even though we are in a different + ;; function here. + (call $target + (i32.const 1) + (i32.eqz + (i32.const 999) + ) + (ref.func $calls) + (string.const "foo") + ) + + ;; Call a different function but with the exact same params. This tests that + ;; we handle identical contexts but with different functions. This will call + ;; a different refined function than before + (call $other-target + (i32.const 1) + (i32.eqz + (i32.const 999) + ) + (ref.func $calls) + (string.const "foo") + ) + + ;; Call yet another different function with the same context, this time the + ;; function is worth optimizing even in CAREFUL mode, as the constants + ;; unlock actual work. + (call $work + (i32.const 3) + (i32.eqz + (i32.const 999) + ) + (ref.func $calls) + (string.const "foo") + ) + ) + + ;; ALWAYS: (func $fail (type $1) + ;; ALWAYS-NEXT: (call $target + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 999) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result funcref) + ;; ALWAYS-NEXT: (ref.func $calls) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result stringref) + ;; ALWAYS-NEXT: (string.const "foo") + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $fail (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 999) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result funcref) + ;; CAREFUL-NEXT: (ref.func $calls) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result stringref) + ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $fail + ;; No operand is a constant here, so we do nothing. + (call $target + (i32.eqz + (i32.const 1) + ) + (i32.eqz + (i32.const 999) + ) + (block (result funcref) + (ref.func $calls) + ) + (block (result stringref) + (string.const "foo") + ) + ) + ) + + ;; ALWAYS: (func $mutual-recursion-a (type $3) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (if (result i32) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (i32.add + ;; ALWAYS-NEXT: (call $mutual-recursion-b + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $mutual-recursion-b_13) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (else + ;; ALWAYS-NEXT: (i32.const 42) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $mutual-recursion-a (type $3) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (if (result i32) + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (i32.add + ;; CAREFUL-NEXT: (call $mutual-recursion-b + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $mutual-recursion-b + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (else + ;; CAREFUL-NEXT: (i32.const 42) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $mutual-recursion-a (param $x i32) (result i32) + ;; We ignore direct recursion (see test in other monomorphize-types) but we + ;; do handle mutual recursion normally. This also tests another function + ;; that can be optimized, with a different signature than before. + (if (result i32) + (local.get $x) + (then + (i32.add + ;; This call cannot be monomorphized. + (call $mutual-recursion-b + (local.get $x) + ) + ;; The constant here allows us to monomorphize (in ALWAYS; to see the + ;; benefit in CAREFUL, we need additional cycles, which we do not do + ;; yet). + (call $mutual-recursion-b + (i32.const 0) + ) + ) + ) + (else + (i32.const 42) + ) + ) + ) + + ;; ALWAYS: (func $mutual-recursion-b (type $3) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (i32.add + ;; ALWAYS-NEXT: (call $mutual-recursion-a_14) + ;; ALWAYS-NEXT: (i32.const 1337) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $mutual-recursion-b (type $3) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (i32.add + ;; CAREFUL-NEXT: (call $mutual-recursion-a + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1337) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $mutual-recursion-b (param $x i32) (result i32) + (i32.add + ;; This can be optimized (in ALWAYS; to see the benefit in CAREFUL, we + ;; need additional cycles, which we do not do yet). + (call $mutual-recursion-a + (i32.const 0) + ) + (i32.const 1337) + ) + ) + + ;; ALWAYS: (func $target (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $func) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $str) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 funcref) (param $3 stringref) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + (drop + (local.get $func) + ) + (drop + (local.get $str) + ) + ) + + ;; ALWAYS: (func $other-target (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $func) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $str) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $other-target (type $1) (param $0 i32) (param $1 i32) (param $2 funcref) (param $3 stringref) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $other-target (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; Similar to $target, but the inside is a little reordered. + (drop + (local.get $func) + ) + (drop + (local.get $str) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + + ;; ALWAYS: (func $work (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS-NEXT: (call $import + ;; ALWAYS-NEXT: (i32.add + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (i32.add + ;; ALWAYS-NEXT: (ref.is_null + ;; ALWAYS-NEXT: (local.get $func) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (ref.is_null + ;; ALWAYS-NEXT: (local.get $str) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $import + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $work (type $1) (param $0 i32) (param $1 i32) (param $2 funcref) (param $3 stringref) + ;; CAREFUL-NEXT: (call $import + ;; CAREFUL-NEXT: (i32.add + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (i32.add + ;; CAREFUL-NEXT: (ref.is_null + ;; CAREFUL-NEXT: (local.get $2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (ref.is_null + ;; CAREFUL-NEXT: (local.get $3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $import + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $work (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; Similar to $target, but the inside has actual work that can be optimized + ;; away if we have constants here. Specifically the refs are not null and + ;; $x is 3, so we sent 3 to the import here. + (call $import + (i32.add + (local.get $x) + (i32.add + (ref.is_null + (local.get $func) + ) + (ref.is_null + (local.get $str) + ) + ) + ) + ) + ;; This parameter is unknown, so we can't do any optimization in this part. + (call $import + (local.get $y) + ) + ) +) +;; ALWAYS: (func $target_9 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local $func funcref) +;; ALWAYS-NEXT: (local $str stringref) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $func +;; ALWAYS-NEXT: (ref.func $calls) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $str +;; ALWAYS-NEXT: (string.const "foo") +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $func) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $str) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_10 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local $func funcref) +;; ALWAYS-NEXT: (local $str stringref) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $func +;; ALWAYS-NEXT: (ref.func $calls) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $str +;; ALWAYS-NEXT: (string.const "foo") +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $func) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $str) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $other-target_11 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local $func funcref) +;; ALWAYS-NEXT: (local $str stringref) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $func +;; ALWAYS-NEXT: (ref.func $calls) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $str +;; ALWAYS-NEXT: (string.const "foo") +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $func) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $str) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $work_12 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local $func funcref) +;; ALWAYS-NEXT: (local $str stringref) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $func +;; ALWAYS-NEXT: (ref.func $calls) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $str +;; ALWAYS-NEXT: (string.const "foo") +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (i32.add +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (i32.add +;; ALWAYS-NEXT: (ref.is_null +;; ALWAYS-NEXT: (local.get $func) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (ref.is_null +;; ALWAYS-NEXT: (local.get $str) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $mutual-recursion-b_13 (type $4) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.add +;; ALWAYS-NEXT: (call $mutual-recursion-a +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1337) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $mutual-recursion-a_14 (type $4) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (if (result i32) +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (i32.add +;; ALWAYS-NEXT: (call $mutual-recursion-b +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (call $mutual-recursion-b_13) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (else +;; ALWAYS-NEXT: (i32.const 42) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $work_9 (type $2) (param $0 i32) +;; CAREFUL-NEXT: (call $import +;; CAREFUL-NEXT: (i32.const 3) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: (call $import +;; CAREFUL-NEXT: (local.get $0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) diff --git a/test/lit/passes/monomorphize-mvp.wast b/test/lit/passes/monomorphize-mvp.wast new file mode 100644 index 00000000000..567a4c2ce92 --- /dev/null +++ b/test/lit/passes/monomorphize-mvp.wast @@ -0,0 +1,94 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; As in monomorphize-types.wast, test in both "always" mode, which always +;; monomorphizes, and in "careful" mode which does it only when it appears to +;; actually help. + +;; This file specifically tests that we optimize constants in MVP mode (most +;; of the pass benefits from other features, but we should still do work in +;; MVP). + +;; RUN: foreach %s %t wasm-opt --monomorphize-always -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize -S -o - | filecheck %s --check-prefix CAREFUL + +(module + ;; ALWAYS: (type $0 (func (result i32))) + + ;; ALWAYS: (type $1 (func (param i32 i32) (result i32))) + + ;; ALWAYS: (type $2 (func (param i32) (result i32))) + + ;; ALWAYS: (func $call (result i32) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (i32.eqz + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func (result i32))) + + ;; CAREFUL: (type $1 (func (param i32 i32) (result i32))) + + ;; CAREFUL: (type $2 (func (param i32) (result i32))) + + ;; CAREFUL: (func $call (result i32) + ;; CAREFUL-NEXT: (call $target_2 + ;; CAREFUL-NEXT: (i32.eqz + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call (result i32) + ;; The second parameter can be monomorphized. + (call $target + (i32.eqz + (i32.const 2) + ) + (i32.const 1) + ) + ) + + ;; ALWAYS: (func $target (param $x i32) (param $y i32) (result i32) + ;; ALWAYS-NEXT: (select + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (i32.const 42) + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (param $0 i32) (param $1 i32) (result i32) + ;; CAREFUL-NEXT: (select + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (i32.const 42) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $target (param $x i32) (param $y i32) (result i32) + ;; The monomorphized copies of this function will be able to remove the + ;; select, in CAREFUL (which optimizes). + (select + (local.get $x) + (i32.const 42) + (local.get $y) + ) + ) +) + +;; ALWAYS: (func $target_2 (param $0 i32) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (select +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (i32.const 42) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (param $0 i32) (result i32) +;; CAREFUL-NEXT: (local.get $0) +;; CAREFUL-NEXT: ) diff --git a/test/lit/passes/monomorphize.wast b/test/lit/passes/monomorphize-types.wast similarity index 89% rename from test/lit/passes/monomorphize.wast rename to test/lit/passes/monomorphize-types.wast index 43208a97d62..3133d88c512 100644 --- a/test/lit/passes/monomorphize.wast +++ b/test/lit/passes/monomorphize-types.wast @@ -115,7 +115,11 @@ ) -;; ALWAYS: (func $refinable_4 (type $4) (param $ref (ref $B)) +;; ALWAYS: (func $refinable_4 (type $4) (param $0 (ref $B)) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) @@ -186,17 +190,17 @@ ) -;; ALWAYS: (func $refinable_2 (type $4) (param $ref (ref $B)) +;; ALWAYS: (func $refinable_2 (type $4) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $unref (ref $A)) -;; ALWAYS-NEXT: (local $2 (ref $A)) -;; ALWAYS-NEXT: (local.set $2 -;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (block ;; ALWAYS-NEXT: (local.set $unref -;; ALWAYS-NEXT: (local.get $2) +;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: (local.set $2 +;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $unref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) @@ -306,19 +310,31 @@ ) ) -;; ALWAYS: (func $refinable1_4 (type $5) (param $ref (ref $B)) +;; ALWAYS: (func $refinable1_4 (type $5) (param $0 (ref $B)) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $refinable1_5 (type $6) (param $ref (ref $C)) +;; ALWAYS: (func $refinable1_5 (type $6) (param $0 (ref $C)) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $refinable2_6 (type $5) (param $ref (ref $B)) +;; ALWAYS: (func $refinable2_6 (type $5) (param $0 (ref $B)) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) @@ -501,33 +517,39 @@ ) ) -;; ALWAYS: (func $refinable_3 (type $2) (param $ref (ref $B)) +;; ALWAYS: (func $refinable_3 (type $2) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $x (ref $A)) -;; ALWAYS-NEXT: (call $import -;; ALWAYS-NEXT: (ref.cast (ref $B) -;; ALWAYS-NEXT: (local.get $ref) -;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (local.get $0) ;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: (local.set $x -;; ALWAYS-NEXT: (select (result (ref $B)) -;; ALWAYS-NEXT: (local.get $ref) -;; ALWAYS-NEXT: (struct.new_default $B) -;; ALWAYS-NEXT: (global.get $global) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (ref.cast (ref $B) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: (call $import -;; ALWAYS-NEXT: (ref.cast (ref $B) -;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (select (result (ref $A)) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (struct.new_default $B) +;; ALWAYS-NEXT: (global.get $global) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: (call $import -;; ALWAYS-NEXT: (ref.cast (ref $B) -;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (ref.cast (ref $B) +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: ) -;; ALWAYS-NEXT: (call $import -;; ALWAYS-NEXT: (ref.cast (ref $B) -;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (ref.cast (ref $B) +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (ref.cast (ref $B) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) @@ -586,3 +608,4 @@ ) ) ) + diff --git a/test/lit/passes/no-inline-monomorphize-inlining.wast b/test/lit/passes/no-inline-monomorphize-inlining.wast index be3b5759d95..716d0beda50 100644 --- a/test/lit/passes/no-inline-monomorphize-inlining.wast +++ b/test/lit/passes/no-inline-monomorphize-inlining.wast @@ -3,9 +3,12 @@ ;; Monomorphization creates a new function, which we can then inline. When we ;; mark the original as no-inline, we should not inline the copy, as the copy ;; inherits the metadata. +;; +;; Use --optimize-level=3 to ensure inlining works at the maximum (to avoid it +;; not happening because of size limits etc.). -;; RUN: foreach %s %t wasm-opt --no-inline=*noinline* --monomorphize-always --inlining -all -S -o - | filecheck %s --check-prefix NO_INLINE -;; RUN: foreach %s %t wasm-opt --monomorphize-always --inlining -all -S -o - | filecheck %s --check-prefix YESINLINE +;; RUN: foreach %s %t wasm-opt --no-inline=*noinline* --monomorphize-always --inlining --optimize-level=3 -all -S -o - | filecheck %s --check-prefix NO_INLINE +;; RUN: foreach %s %t wasm-opt --monomorphize-always --inlining --optimize-level=3 -all -S -o - | filecheck %s --check-prefix YESINLINE (module ;; NO_INLINE: (type $A (sub (struct ))) @@ -42,7 +45,9 @@ ;; YESINLINE-NEXT: (local $0 (ref $A)) ;; YESINLINE-NEXT: (local $1 (ref $A)) ;; YESINLINE-NEXT: (local $2 (ref $B)) - ;; YESINLINE-NEXT: (local $3 (ref $B)) + ;; YESINLINE-NEXT: (local $3 (ref $A)) + ;; YESINLINE-NEXT: (local $4 (ref $B)) + ;; YESINLINE-NEXT: (local $5 (ref $A)) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline ;; YESINLINE-NEXT: (local.set $0 @@ -68,18 +73,28 @@ ;; YESINLINE-NEXT: (local.set $2 ;; YESINLINE-NEXT: (struct.new_default $B) ;; YESINLINE-NEXT: ) - ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $2) + ;; YESINLINE-NEXT: (block + ;; YESINLINE-NEXT: (local.set $3 + ;; YESINLINE-NEXT: (local.get $2) + ;; YESINLINE-NEXT: ) + ;; YESINLINE-NEXT: (drop + ;; YESINLINE-NEXT: (local.get $3) + ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline_2$3 - ;; YESINLINE-NEXT: (local.set $3 + ;; YESINLINE-NEXT: (local.set $4 ;; YESINLINE-NEXT: (struct.new_default $B) ;; YESINLINE-NEXT: ) - ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $3) + ;; YESINLINE-NEXT: (block + ;; YESINLINE-NEXT: (local.set $5 + ;; YESINLINE-NEXT: (local.get $4) + ;; YESINLINE-NEXT: ) + ;; YESINLINE-NEXT: (drop + ;; YESINLINE-NEXT: (local.get $5) + ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) @@ -118,7 +133,11 @@ ) ) ) -;; NO_INLINE: (func $refinable_noinline_2 (type $4) (param $ref (ref $B)) +;; NO_INLINE: (func $refinable_noinline_2 (type $4) (param $0 (ref $B)) +;; NO_INLINE-NEXT: (local $ref (ref $A)) +;; NO_INLINE-NEXT: (local.set $ref +;; NO_INLINE-NEXT: (local.get $0) +;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: (drop ;; NO_INLINE-NEXT: (local.get $ref) ;; NO_INLINE-NEXT: ) From 56139818e57327ee3b071e2ab176632d09fdeda0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 11 Jul 2024 11:47:20 -0700 Subject: [PATCH 430/553] Heap2Local: Drop RefEq's two arms (#6729) This is a tiny bit more code but it is more consistent with other operations, and it saves work later. --- src/passes/Heap2Local.cpp | 6 +- test/lit/passes/heap2local.wast | 157 ++++++++++++++++---------------- 2 files changed, 79 insertions(+), 84 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 7aec23ccf1a..720ebba4044 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -745,9 +745,9 @@ struct Struct2Local : PostWalker { // not escape to any other place. int32_t result = analyzer.reached.count(curr->left) > 0 && analyzer.reached.count(curr->right) > 0; - // For simplicity, simply drop the RefEq and put a constant result after. - replaceCurrent(builder.makeSequence(builder.makeDrop(curr), - builder.makeConst(Literal(result)))); + replaceCurrent(builder.makeBlock({builder.makeDrop(curr->left), + builder.makeDrop(curr->right), + builder.makeConst(Literal(result))})); } void visitRefAs(RefAs* curr) { diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index d642aabb3da..11f56cae2f0 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2097,25 +2097,25 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (f64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) (func $ref-eq (result i32) @@ -2136,23 +2136,23 @@ ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (local $4 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (local.get $other) - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (f64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (local.get $other) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -2175,25 +2175,25 @@ ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (local $4 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (f64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (local.get $4) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $ref-eq-self (result i32) @@ -2335,42 +2335,37 @@ ;; CHECK-NEXT: (local $6 i32) ;; CHECK-NEXT: (local $7 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result i32) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $2 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $3 - ;; CHECK-NEXT: (f64.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $3) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $6 - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $7 - ;; CHECK-NEXT: (f64.const 2.2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $4 - ;; CHECK-NEXT: (local.get $6) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $5 - ;; CHECK-NEXT: (local.get $7) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (f64.const 2.2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) From 020e6cc7923419520f6fe825912f17b811770ce8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 11 Jul 2024 12:33:58 -0700 Subject: [PATCH 431/553] [WasmGC] Heap2Local: Optimize RefCast failures (#6727) Previously we just did not optimize cases where our escape analysis showed an allocation flowed into a cast that failed. However, after inlining there can be real-world cases where that happens, even in traps-never-happen mode (if the cast is behind a conditional branch), so it seems worth optimizing. --- src/passes/Heap2Local.cpp | 44 +++++++------- test/lit/passes/heap2local.wast | 104 +++++++++++++++++++++++++++----- 2 files changed, 111 insertions(+), 37 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 720ebba4044..1e747d6ab99 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -379,11 +379,13 @@ struct EscapeAnalyzer { } void visitRefCast(RefCast* curr) { - // As it is our allocation that flows through here, we need to - // check that the cast will not trap, so that we can continue - // to (hopefully) optimize this allocation. - if (Type::isSubType(allocation->type, curr->type)) { - escapes = false; + // Whether the cast succeeds or fails, it does not escape. + escapes = false; + + // If the cast fails then the allocation is fully consumed and does not + // flow any further (instead, we trap). + if (!Type::isSubType(allocation->type, curr->type)) { + fullyConsumes = true; } } @@ -783,24 +785,22 @@ struct Struct2Local : PostWalker { return; } - // It is safe to optimize out this RefCast, since we proved it - // contains our allocation and we have checked that the type of - // the allocation is a subtype of the type of the cast, and so - // cannot trap. - replaceCurrent(curr->ref); + // We know this RefCast receives our allocation, so we can see whether it + // succeeds or fails. + if (Type::isSubType(allocation->type, curr->type)) { + // The cast succeeds, so it is a no-op, and we can skip it, since after we + // remove the allocation it will not even be needed for validation. + replaceCurrent(curr->ref); + } else { + // The cast fails, so this must trap. + replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref), + builder.makeUnreachable())); + } - // We need to refinalize after this, as while we know the cast is not - // logically needed - the value flowing through will not be used - we do - // need validation to succeed even before other optimizations remove the - // code. For example: - // - // (block (result $B) - // (ref.cast $B - // (block (result $A) - // - // Without the cast this does not validate, so we need to refinalize - // (which will fix this, as we replace the unused value with a null, so - // that type will propagate out). + // Either way, we need to refinalize here (we either added an unreachable, + // or we replaced a cast with the value being cast, which may have a less- + // refined type - it will not be used after we remove the allocation, but we + // must still fix that up for validation). refinalize = true; } diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 11f56cae2f0..f00cb60e2da 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2635,24 +2635,34 @@ (type $A (sub (struct (field (ref null $A))))) ;; CHECK: (type $1 (func (result anyref))) - ;; CHECK: (type $B (sub $A (struct (field (ref $A))))) - (type $B (sub $A (struct (field (ref $A))))) + ;; CHECK: (type $B (sub $A (struct (field (ref $A)) (field i32)))) + (type $B (sub $A (struct (field (ref $A)) (field i32)))) + + ;; CHECK: (type $3 (func (result i32))) ;; CHECK: (func $func (type $1) (result anyref) ;; CHECK-NEXT: (local $a (ref $A)) ;; CHECK-NEXT: (local $1 (ref $A)) - ;; CHECK-NEXT: (local $2 (ref $A)) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 (ref $A)) + ;; CHECK-NEXT: (local $4 i32) ;; CHECK-NEXT: (ref.cast (ref $B) ;; CHECK-NEXT: (block (result (ref $A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -2675,6 +2685,7 @@ (struct.new $A (ref.null none) ) + (i32.const 1) ) ) ) @@ -2683,16 +2694,24 @@ ;; CHECK: (func $cast-success (type $1) (result anyref) ;; CHECK-NEXT: (local $0 (ref $A)) - ;; CHECK-NEXT: (local $1 (ref $A)) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 (ref $A)) + ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result nullref) - ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -2706,25 +2725,80 @@ (struct.new $A (ref.null none) ) + (i32.const 1) ) ) ) ) ;; CHECK: (func $cast-failure (type $1) (result anyref) - ;; CHECK-NEXT: (struct.get $B 0 - ;; CHECK-NEXT: (ref.cast (ref $B) - ;; CHECK-NEXT: (struct.new $A - ;; CHECK-NEXT: (struct.new $A - ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (local $0 (ref null $A)) + ;; CHECK-NEXT: (local $1 (ref null $A)) + ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (struct.new $A + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $cast-failure (result anyref) (struct.get $B 0 - ;; The allocated $A arrives here, but the cast will fail, so we do not - ;; optimize. + ;; The allocated $A arrives here, but the cast will fail. We can remove + ;; the allocation and put an unreachable here. (Note that the inner + ;; struct.new survives, which would take another cycle to remove.) + (ref.cast (ref $B) + (struct.new $A + (struct.new $A + (ref.null none) + ) + ) + ) + ) + ) + + ;; CHECK: (func $cast-failure-nofield (type $3) (result i32) + ;; CHECK-NEXT: (local $0 (ref null $A)) + ;; CHECK-NEXT: (local $1 (ref null $A)) + ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (struct.new $A + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cast-failure-nofield (result i32) + ;; As above, but we read from a field that only exists in $B, despite the + ;; allocation that flows here being an $A. We should not error on that. + (struct.get $B 1 ;; this changes from 0 to 1 (ref.cast (ref $B) (struct.new $A (struct.new $A From c64ac5d5a676fdbb9b108e0ad16c293a32a9b611 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 11 Jul 2024 17:06:55 -0400 Subject: [PATCH 432/553] [wasm-split] Use a fresh table when reference types are enabled (#6726) Rather than trying to trampoline primary-to-secondary calls through an existing table, just create a fresh table for this purpose. This ensures that modifications to the existing tables cannot interfere with primary-to-secondary calls and conversely that loading the secondary module cannot overwrite modifications to the tables. --- src/ir/module-splitting.cpp | 31 ++-- test/example/module-splitting.txt | 241 +++++++++++++++++++++++------- test/lit/wasm-split/passive.wast | 30 ++-- test/lit/wasm-split/ref.func.wast | 56 ++++--- 4 files changed, 254 insertions(+), 104 deletions(-) diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 50809a9a4df..22f8b301f44 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -147,15 +147,23 @@ void TableSlotManager::addSlot(Name func, Slot slot) { } TableSlotManager::TableSlotManager(Module& module) : module(module) { + if (module.features.hasReferenceTypes()) { + // Just create a new table to manage all primary-to-secondary calls lazily. + // Do not re-use slots for functions that will already be in existing + // tables, since that is not correct in the face of table mutations. + // TODO: Reduce overhead by creating a separate table for each function type + // if WasmGC is enabled. + return; + } + // TODO: Reject or handle passive element segments - // TODO: If reference types are enabled, just create a fresh table to make bad - // interactions with user code impossible. auto funcref = Type(HeapType::func, Nullable); auto it = std::find_if( module.tables.begin(), module.tables.end(), [&](std::unique_ptr
& table) { return table->type == funcref; }); if (it == module.tables.end()) { + // There is no indirect function table, so we will create one lazily. return; } @@ -560,18 +568,15 @@ void ModuleSplitter::indirectReferencesToSecondaryFunctions() { } gatherer(*this); gatherer.walkModule(&primary); - // Find all RefFuncs in active elementSegments, which we can ignore: tables - // are the means by which we connect the modules, and are handled directly. - // Passive segments, however, are like RefFuncs in code, and we need to not - // ignore them here. + // Ignore references to secondary functions that occur in the active segment + // that will contain the imported placeholders. Indirect calls to table slots + // initialized by that segment will already go to the right place once the + // secondary module has been loaded and the table has been patched. std::unordered_set ignore; - for (auto& seg : primary.elementSegments) { - if (!seg->table.is()) { - continue; - } - for (auto* curr : seg->data) { - if (auto* refFunc = curr->dynCast()) { - ignore.insert(refFunc); + if (tableManager.activeSegment) { + for (auto* expr : tableManager.activeSegment->data) { + if (auto* ref = expr->dynCast()) { + ignore.insert(ref); } } } diff --git a/test/example/module-splitting.txt b/test/example/module-splitting.txt index b083e8967b6..69fabc81665 100644 --- a/test/example/module-splitting.txt +++ b/test/example/module-splitting.txt @@ -399,14 +399,24 @@ After: (type $0 (func (param i32) (result i32))) (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) (table $table 1 funcref) - (elem $0 (i32.const 0) $placeholder_0) + (table $0 1 funcref) + (elem $0 (table $table) (i32.const 0) func $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%table" (table $table)) + (export "%table_1" (table $0)) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) + ) + ) ) Secondary: (module (type $0 (func (param i32) (result i32))) + (import "primary" "%table_1" (table $0 1 funcref)) (import "primary" "%table" (table $table 1 funcref)) - (elem $0 (i32.const 0) $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -427,16 +437,25 @@ After: (module (type $0 (func (param i32) (result i32))) (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) - (import "placeholder" "1" (func $placeholder_1 (type $0) (param i32) (result i32))) (table $table 2 funcref) - (elem $0 (i32.const 0) $placeholder_0 $placeholder_1) + (table $0 1 funcref) + (elem $0 (table $table) (i32.const 0) func $trampoline_foo $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%table" (table $table)) + (export "%table_1" (table $0)) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) + ) + ) ) Secondary: (module (type $0 (func (param i32) (result i32))) + (import "primary" "%table_1" (table $0 1 funcref)) (import "primary" "%table" (table $table 2 funcref)) - (elem $0 (i32.const 0) $foo $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -457,23 +476,33 @@ Keeping: After: (module (type $0 (func (param i32) (result i32))) - (import "placeholder" "42" (func $placeholder_42 (type $0) (param i32) (result i32))) + (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) (table $table 1000 funcref) - (elem $0 (i32.const 42) $placeholder_42) + (table $0 1 funcref) + (elem $0 (table $table) (i32.const 42) func $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $foo)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (func $foo (type $0) (param $0 i32) (result i32) - (call_indirect $table (type $0) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) + ) + ) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) (local.get $0) - (i32.const 42) + (i32.const 0) ) ) ) Secondary: (module (type $0 (func (param i32) (result i32))) + (import "primary" "%table_2" (table $0 1 funcref)) (import "primary" "%table" (table $table 1000 funcref)) - (elem $0 (i32.const 42) $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -498,23 +527,33 @@ After: (import "env" "base" (global $base i32)) (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) (table $table 1000 funcref) - (elem $0 (global.get $base) $placeholder_0) + (table $0 1 funcref) + (elem $0 (table $table) (global.get $base) func $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $foo)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (export "%global" (global $base)) (func $foo (type $0) (param $0 i32) (result i32) - (call_indirect $table (type $0) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) + ) + ) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) (local.get $0) - (global.get $base) + (i32.const 0) ) ) ) Secondary: (module (type $0 (func (param i32) (result i32))) + (import "primary" "%table_2" (table $0 1 funcref)) (import "primary" "%table" (table $table 1000 funcref)) (import "primary" "%global" (global $base i32)) - (elem $0 (global.get $base) $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -538,25 +577,34 @@ After: (type $0 (func (param i32) (result i32))) (import "env" "base" (global $base i32)) (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) - (import "placeholder" "1" (func $placeholder_1 (type $0) (param i32) (result i32))) (table $table 1000 funcref) - (elem $0 (global.get $base) $placeholder_0 $placeholder_1) + (table $0 1 funcref) + (elem $0 (table $table) (global.get $base) func $trampoline_foo $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $foo)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (export "%global" (global $base)) (func $foo (type $0) (param $0 i32) (result i32) - (call_indirect $table (type $0) + (call_indirect $0 (type $0) (local.get $0) - (global.get $base) + (i32.const 0) + ) + ) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) ) ) ) Secondary: (module (type $0 (func (param i32) (result i32))) + (import "primary" "%table_2" (table $0 1 funcref)) (import "primary" "%table" (table $table 1000 funcref)) (import "primary" "%global" (global $base i32)) - (elem $0 (global.get $base) $foo $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -584,34 +632,38 @@ After: (type $0 (func (param i32) (result i32))) (type $1 (func)) (import "env" "base" (global $base i32)) - (import "placeholder" "1" (func $placeholder_1 (type $0) (param i32) (result i32))) + (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) (table $table 1000 funcref) - (elem $0 (global.get $base) $null $placeholder_1) + (table $0 1 funcref) + (elem $0 (table $table) (global.get $base) func $null $trampoline_foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "foo" (func $foo)) - (export "%null" (func $null)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (export "%global" (global $base)) (func $null (type $1) (nop) ) (func $foo (type $0) (param $0 i32) (result i32) - (call_indirect $table (type $0) + (call_indirect $0 (type $0) + (local.get $0) + (i32.const 0) + ) + ) + (func $trampoline_foo (type $0) (param $0 i32) (result i32) + (call_indirect $0 (type $0) (local.get $0) - (i32.add - (global.get $base) - (i32.const 1) - ) + (i32.const 0) ) ) ) Secondary: (module (type $0 (func (param i32) (result i32))) - (type $1 (func)) + (import "primary" "%table_2" (table $0 1 funcref)) (import "primary" "%table" (table $table 1000 funcref)) (import "primary" "%global" (global $base i32)) - (import "primary" "%null" (func $null (type $1))) - (elem $0 (global.get $base) $null $foo) + (elem $0 (table $0) (i32.const 0) func $foo) (func $foo (type $0) (param $0 i32) (result i32) (local.get $0) ) @@ -799,23 +851,36 @@ After: (module (type $0 (func)) (import "placeholder" "0" (func $placeholder_0 (type $0))) - (import "placeholder" "2" (func $placeholder_2 (type $0))) + (import "placeholder" "1" (func $placeholder_1 (type $0))) (table $table 4 funcref) - (elem $0 (i32.const 0) $placeholder_0 $bar $placeholder_2 $quux) + (table $0 2 funcref) + (elem $0 (table $table) (i32.const 0) func $trampoline_foo $bar $trampoline_baz $quux) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1) (export "%table" (table $table)) + (export "%table_1" (table $0)) (func $bar (type $0) (nop) ) (func $quux (type $0) (nop) ) + (func $trampoline_foo (type $0) + (call_indirect $0 (type $0) + (i32.const 0) + ) + ) + (func $trampoline_baz (type $0) + (call_indirect $0 (type $0) + (i32.const 1) + ) + ) ) Secondary: (module (type $0 (func)) + (import "primary" "%table_1" (table $0 2 funcref)) (import "primary" "%table" (table $table 4 funcref)) - (elem $0 (i32.const 0) $foo) - (elem $1 (i32.const 2) $baz) + (elem $0 (table $0) (i32.const 0) func $foo $baz) (func $baz (type $0) (nop) ) @@ -850,11 +915,13 @@ After: (type $0 (func)) (import "env" "base" (global $base i32)) (import "placeholder" "0" (func $placeholder_0 (type $0))) - (import "placeholder" "2" (func $placeholder_2 (type $0))) + (import "placeholder" "1" (func $placeholder_1 (type $0))) (table $table 4 funcref) - (elem $0 (global.get $base) $placeholder_0 $bar $placeholder_2 $quux) - (export "%bar" (func $bar)) + (table $0 2 funcref) + (elem $0 (table $table) (global.get $base) func $trampoline_foo $bar $trampoline_baz $quux) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1) (export "%table" (table $table)) + (export "%table_1" (table $0)) (export "%global" (global $base)) (func $bar (type $0) (nop) @@ -862,14 +929,24 @@ After: (func $quux (type $0) (nop) ) + (func $trampoline_foo (type $0) + (call_indirect $0 (type $0) + (i32.const 0) + ) + ) + (func $trampoline_baz (type $0) + (call_indirect $0 (type $0) + (i32.const 1) + ) + ) ) Secondary: (module (type $0 (func)) + (import "primary" "%table_1" (table $0 2 funcref)) (import "primary" "%table" (table $table 4 funcref)) (import "primary" "%global" (global $base i32)) - (import "primary" "%bar" (func $bar (type $0))) - (elem $0 (global.get $base) $foo $bar $baz) + (elem $0 (table $0) (i32.const 0) func $foo $baz) (func $baz (type $0) (nop) ) @@ -903,20 +980,38 @@ After: (type $0 (func)) (import "placeholder" "0" (func $placeholder_0 (type $0))) (import "placeholder" "1" (func $placeholder_1 (type $0))) - (import "placeholder" "3" (func $placeholder_3 (type $0))) + (import "placeholder" "2" (func $placeholder_2 (type $0))) (table $table 4 funcref) - (elem $0 (i32.const 0) $placeholder_0 $placeholder_1 $baz $placeholder_3) + (table $0 3 funcref) + (elem $0 (table $table) (i32.const 0) func $trampoline_foo $trampoline_bar $baz $trampoline_quux) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1 $placeholder_2) (export "%table" (table $table)) + (export "%table_1" (table $0)) (func $baz (type $0) (nop) ) + (func $trampoline_foo (type $0) + (call_indirect $0 (type $0) + (i32.const 0) + ) + ) + (func $trampoline_bar (type $0) + (call_indirect $0 (type $0) + (i32.const 1) + ) + ) + (func $trampoline_quux (type $0) + (call_indirect $0 (type $0) + (i32.const 2) + ) + ) ) Secondary: (module (type $0 (func)) + (import "primary" "%table_1" (table $0 3 funcref)) (import "primary" "%table" (table $table 4 funcref)) - (elem $0 (i32.const 0) $foo $bar) - (elem $1 (i32.const 3) $quux) + (elem $0 (table $0) (i32.const 0) func $foo $bar $quux) (func $bar (type $0) (nop) ) @@ -955,23 +1050,40 @@ After: (import "env" "base" (global $base i32)) (import "placeholder" "0" (func $placeholder_0 (type $0))) (import "placeholder" "1" (func $placeholder_1 (type $0))) - (import "placeholder" "3" (func $placeholder_3 (type $0))) + (import "placeholder" "2" (func $placeholder_2 (type $0))) (table $table 4 funcref) - (elem $0 (global.get $base) $placeholder_0 $placeholder_1 $baz $placeholder_3) - (export "%baz" (func $baz)) + (table $0 3 funcref) + (elem $0 (table $table) (global.get $base) func $trampoline_foo $trampoline_bar $baz $trampoline_quux) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0 $placeholder_1 $placeholder_2) (export "%table" (table $table)) + (export "%table_1" (table $0)) (export "%global" (global $base)) (func $baz (type $0) (nop) ) + (func $trampoline_foo (type $0) + (call_indirect $0 (type $0) + (i32.const 0) + ) + ) + (func $trampoline_bar (type $0) + (call_indirect $0 (type $0) + (i32.const 1) + ) + ) + (func $trampoline_quux (type $0) + (call_indirect $0 (type $0) + (i32.const 2) + ) + ) ) Secondary: (module (type $0 (func)) + (import "primary" "%table_1" (table $0 3 funcref)) (import "primary" "%table" (table $table 4 funcref)) (import "primary" "%global" (global $base i32)) - (import "primary" "%baz" (func $baz (type $0))) - (elem $0 (global.get $base) $foo $bar $baz $quux) + (elem $0 (table $0) (i32.const 0) func $foo $bar $quux) (func $bar (type $0) (nop) ) @@ -1002,23 +1114,32 @@ After: (module (type $0 (func)) (import "env" "base" (global $base i32)) - (import "placeholder" "1" (func $placeholder_1 (type $0))) + (import "placeholder" "0" (func $placeholder_0 (type $0))) (table $table 2 funcref) - (elem $0 (global.get $base) $foo $placeholder_1) + (table $0 1 funcref) + (elem $0 (table $table) (global.get $base) func $foo $trampoline_bar) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%foo" (func $foo)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (export "%global" (global $base)) (func $foo (type $0) (nop) ) + (func $trampoline_bar (type $0) + (call_indirect $0 (type $0) + (i32.const 0) + ) + ) ) Secondary: (module (type $0 (func)) + (import "primary" "%table_2" (table $0 1 funcref)) (import "primary" "%table" (table $table 2 funcref)) (import "primary" "%global" (global $base i32)) (import "primary" "%foo" (func $foo (type $0))) - (elem $0 (global.get $base) $foo $bar) + (elem $0 (table $0) (i32.const 0) func $bar) (func $bar (type $0) (call $foo) ) @@ -1045,24 +1166,28 @@ Keeping: foo After: (module (type $0 (func (param i32) (result i32))) - (import "placeholder" "1" (func $placeholder_1 (type $0) (param i32) (result i32))) - (table $table 2 2 funcref) - (elem $0 (i32.const 0) $foo $placeholder_1) + (import "placeholder" "0" (func $placeholder_0 (type $0) (param i32) (result i32))) + (table $table 1 1 funcref) + (table $0 1 funcref) + (elem $0 (table $table) (i32.const 0) func $foo) + (elem $0_1 (table $0) (i32.const 0) func $placeholder_0) (export "%foo" (func $foo)) (export "%table" (table $table)) + (export "%table_2" (table $0)) (func $foo (type $0) (param $0 i32) (result i32) - (call_indirect $table (type $0) + (call_indirect $0 (type $0) + (i32.const 0) (i32.const 0) - (i32.const 1) ) ) ) Secondary: (module (type $0 (func (param i32) (result i32))) - (import "primary" "%table" (table $table 2 2 funcref)) + (import "primary" "%table_2" (table $0 1 funcref)) + (import "primary" "%table" (table $table 1 1 funcref)) (import "primary" "%foo" (func $foo (type $0) (param i32) (result i32))) - (elem $0 (i32.const 1) $bar) + (elem $0 (table $0) (i32.const 0) func $bar) (func $bar (type $0) (param $0 i32) (result i32) (call $foo (i32.const 1) diff --git a/test/lit/wasm-split/passive.wast b/test/lit/wasm-split/passive.wast index a72dcada53f..322288201b6 100644 --- a/test/lit/wasm-split/passive.wast +++ b/test/lit/wasm-split/passive.wast @@ -1,31 +1,31 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: wasm-split %s --split-funcs=second-in-table -g -o1 %t.1.wasm -o2 %t.2.wasm -all -;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY -;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY +;; RUN: wasm-split %s -all --split-funcs=second-in-table -g -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-dis -all %t.1.wasm | filecheck %s --check-prefix PRIMARY +;; RUN: wasm-dis -all %t.2.wasm | filecheck %s --check-prefix SECONDARY (module (type $func-array (array (mut funcref))) ;; PRIMARY: (type $0 (func)) - ;; PRIMARY: (import "placeholder" "0" (func $placeholder_0)) + ;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (type $0))) ;; PRIMARY: (table $table 3 funcref) (table $table 3 funcref) - ;; Workaround for https://github.com/WebAssembly/binaryen/issues/6572 - we - ;; error without an active segment. - (elem (i32.const 0)) - - ;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0) + ;; PRIMARY: (table $1 1 funcref) ;; PRIMARY: (elem $passive func $in-table $1) (elem $passive func $in-table $second-in-table) + ;; PRIMARY: (elem $1 (table $1) (i32.const 0) func $placeholder_0) + ;; PRIMARY: (export "table" (table $table)) - ;; PRIMARY: (func $in-table + ;; PRIMARY: (export "table_1" (table $1)) + + ;; PRIMARY: (func $in-table (type $0) ;; PRIMARY-NEXT: (nop) ;; PRIMARY-NEXT: ) (func $in-table @@ -35,11 +35,13 @@ ;; SECONDARY: (type $0 (func)) + ;; SECONDARY: (import "primary" "table_1" (table $timport$0 1 funcref)) + ;; SECONDARY: (import "primary" "table" (table $table 3 funcref)) - ;; SECONDARY: (elem $0 (i32.const 0) $second-in-table) + ;; SECONDARY: (elem $0 (table $timport$0) (i32.const 0) func $second-in-table) - ;; SECONDARY: (func $second-in-table + ;; SECONDARY: (func $second-in-table (type $0) ;; SECONDARY-NEXT: (nop) ;; SECONDARY-NEXT: ) (func $second-in-table @@ -47,8 +49,8 @@ ;; handle it by adding a trampoline from the segment as a new function "$1". ) ) -;; PRIMARY: (func $1 -;; PRIMARY-NEXT: (call_indirect (type $0) +;; PRIMARY: (func $1 (type $0) +;; PRIMARY-NEXT: (call_indirect $1 (type $0) ;; PRIMARY-NEXT: (i32.const 0) ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: ) diff --git a/test/lit/wasm-split/ref.func.wast b/test/lit/wasm-split/ref.func.wast index f7832dcf4c6..39cce5dea82 100644 --- a/test/lit/wasm-split/ref.func.wast +++ b/test/lit/wasm-split/ref.func.wast @@ -1,8 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: wasm-split %s --split-funcs=second,second-in-table -g -o1 %t.1.wasm -o2 %t.2.wasm -all -;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY -;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY +;; RUN: wasm-split %s -all --split-funcs=second,second-in-table -g -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-dis -all %t.1.wasm | filecheck %s --check-prefix PRIMARY +;; RUN: wasm-dis -all %t.2.wasm | filecheck %s --check-prefix SECONDARY ;; Test that we handle ref.func operations properly as we split out $second. ;; ref.funcs that refer to the other module must be fixed up to refer to @@ -10,33 +10,41 @@ (module ;; PRIMARY: (type $0 (func)) - ;; PRIMARY: (import "placeholder" "1" (func $placeholder_1)) + ;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (type $0))) - ;; PRIMARY: (import "placeholder" "2" (func $placeholder_2)) + ;; PRIMARY: (import "placeholder" "1" (func $placeholder_1 (type $0))) ;; PRIMARY: (global $glob1 (ref func) (ref.func $prime)) ;; PRIMARY: (global $glob2 (ref func) (ref.func $2)) - ;; PRIMARY: (table $table 3 3 funcref) + ;; PRIMARY: (table $table 1 1 funcref) (table $table 1 1 funcref) (global $glob1 (ref func) (ref.func $prime)) (global $glob2 (ref func) (ref.func $second)) - ;; PRIMARY: (elem $elem (i32.const 0) $in-table $placeholder_1 $placeholder_2) + ;; PRIMARY: (table $1 2 funcref) + + ;; PRIMARY: (elem $elem (table $table) (i32.const 0) func $in-table $3) (elem $elem (i32.const 0) $in-table $second-in-table) + ;; PRIMARY: (elem $1 (table $1) (i32.const 0) func $placeholder_0 $placeholder_1) + + ;; PRIMARY: (elem declare func $2 $prime) + ;; PRIMARY: (export "prime" (func $prime)) ;; PRIMARY: (export "table" (table $table)) + ;; PRIMARY: (export "table_2" (table $1)) + ;; PRIMARY: (export "global" (global $glob1)) - ;; PRIMARY: (export "global_3" (global $glob2)) + ;; PRIMARY: (export "global_4" (global $glob2)) - ;; PRIMARY: (func $prime + ;; PRIMARY: (func $prime (type $0) ;; PRIMARY-NEXT: (drop ;; PRIMARY-NEXT: (ref.func $prime) ;; PRIMARY-NEXT: ) @@ -55,17 +63,21 @@ ;; SECONDARY: (type $0 (func)) - ;; SECONDARY: (import "primary" "table" (table $table 3 3 funcref)) + ;; SECONDARY: (import "primary" "table_2" (table $timport$0 2 funcref)) + + ;; SECONDARY: (import "primary" "table" (table $table 1 1 funcref)) ;; SECONDARY: (import "primary" "global" (global $glob1 (ref func))) - ;; SECONDARY: (import "primary" "global_3" (global $glob2 (ref func))) + ;; SECONDARY: (import "primary" "global_4" (global $glob2 (ref func))) - ;; SECONDARY: (import "primary" "prime" (func $prime)) + ;; SECONDARY: (import "primary" "prime" (func $prime (type $0))) - ;; SECONDARY: (elem $0 (i32.const 1) $second-in-table $second) + ;; SECONDARY: (elem $0 (table $timport$0) (i32.const 0) func $second $second-in-table) - ;; SECONDARY: (func $second + ;; SECONDARY: (elem declare func $prime) + + ;; SECONDARY: (func $second (type $0) ;; SECONDARY-NEXT: (drop ;; SECONDARY-NEXT: (ref.func $prime) ;; SECONDARY-NEXT: ) @@ -82,7 +94,7 @@ ) ) - ;; PRIMARY: (func $in-table + ;; PRIMARY: (func $in-table (type $0) ;; PRIMARY-NEXT: (nop) ;; PRIMARY-NEXT: ) (func $in-table @@ -91,7 +103,7 @@ ;; table is a list of ref.funcs. ) - ;; SECONDARY: (func $second-in-table + ;; SECONDARY: (func $second-in-table (type $0) ;; SECONDARY-NEXT: (nop) ;; SECONDARY-NEXT: ) (func $second-in-table @@ -99,8 +111,14 @@ ;; (but we will get a placeholder, as all split-out functions do). ) ) -;; PRIMARY: (func $2 -;; PRIMARY-NEXT: (call_indirect (type $0) -;; PRIMARY-NEXT: (i32.const 2) +;; PRIMARY: (func $2 (type $0) +;; PRIMARY-NEXT: (call_indirect $1 (type $0) +;; PRIMARY-NEXT: (i32.const 0) +;; PRIMARY-NEXT: ) +;; PRIMARY-NEXT: ) + +;; PRIMARY: (func $3 (type $0) +;; PRIMARY-NEXT: (call_indirect $1 (type $0) +;; PRIMARY-NEXT: (i32.const 1) ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: ) From ae4800bebd0d479813d99e31e098296c9167e34a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 11 Jul 2024 17:25:54 -0400 Subject: [PATCH 433/553] [threads] Shared polymorphism for extern conversions (#6730) `any.convert_extern` and `extern.convert_any` return references to shared heap types iff their operands are references to shared heap types. --- src/wasm/wasm-validator.cpp | 18 ++++++++++-------- src/wasm/wasm.cpp | 9 ++++++--- test/spec/shared-polymorphism.wast | 13 +++++++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 9732f54a9a1..eb2f949b24a 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2222,10 +2222,11 @@ void FunctionValidator::visitRefAs(RefAs* curr) { if (curr->type == Type::unreachable) { return; } - shouldBeSubType(curr->value->type, - Type(HeapType::ext, Nullable), - curr->value, - "any.convert_extern value should be an externref"); + shouldBeSubTypeIgnoringShared( + curr->value->type, + Type(HeapType::ext, Nullable), + curr->value, + "any.convert_extern value should be an externref"); break; } case ExternConvertAny: { @@ -2235,10 +2236,11 @@ void FunctionValidator::visitRefAs(RefAs* curr) { if (curr->type == Type::unreachable) { return; } - shouldBeSubType(curr->value->type, - Type(HeapType::any, Nullable), - curr->value, - "extern.convert_any value should be an anyref"); + shouldBeSubTypeIgnoringShared( + curr->value->type, + Type(HeapType::any, Nullable), + curr->value, + "extern.convert_any value should be an anyref"); break; } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 58699ad8bba..8a2b4755ceb 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1227,15 +1227,18 @@ void RefAs::finalize() { type = Type::unreachable; return; } + auto valHeapType = value->type.getHeapType(); switch (op) { case RefAsNonNull: - type = Type(value->type.getHeapType(), NonNullable); + type = Type(valHeapType, NonNullable); break; case AnyConvertExtern: - type = Type(HeapType::any, value->type.getNullability()); + type = Type(HeapTypes::any.getBasic(valHeapType.getShared()), + value->type.getNullability()); break; case ExternConvertAny: - type = Type(HeapType::ext, value->type.getNullability()); + type = Type(HeapTypes::ext.getBasic(valHeapType.getShared()), + value->type.getNullability()); break; default: WASM_UNREACHABLE("invalid ref.as_*"); diff --git a/test/spec/shared-polymorphism.wast b/test/spec/shared-polymorphism.wast index 547829f1170..be8b5e467af 100644 --- a/test/spec/shared-polymorphism.wast +++ b/test/spec/shared-polymorphism.wast @@ -9,4 +9,17 @@ (func (param (ref null (shared i31))) (drop (i31.get_u (local.get 0)))) (func (param (ref null (shared array))) (drop (array.len (local.get 0)))) + + (func (param (ref null (shared extern))) (result (ref null (shared any))) + (any.convert_extern (local.get 0)) + ) + (func (param (ref (shared extern))) (result (ref (shared any))) + (any.convert_extern (local.get 0)) + ) + (func (param (ref null (shared any))) (result (ref null (shared extern))) + (extern.convert_any (local.get 0)) + ) + (func (param (ref (shared any))) (result (ref (shared extern))) + (extern.convert_any (local.get 0)) + ) ) From 6d2f101b3bcb8d5a7d1ead40f1245bbbead36580 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 11 Jul 2024 15:09:08 -0700 Subject: [PATCH 434/553] Monomorphize: Use -O3 over -O1 + tweaks (#6732) Eventually we will need to do some tuning of compile time speed, but for now it is going to be simpler to do all the opts, in particular because it makes writing tests simpler. --- src/passes/Monomorphize.cpp | 34 +++++++++--------------- test/lit/passes/monomorphize-consts.wast | 13 +++++---- test/lit/passes/monomorphize-types.wast | 32 +++++++++++----------- 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index 5237f786450..c27f5d6eb9e 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -374,7 +374,7 @@ struct Monomorphize : public Pass { // Decide whether it is worth using the monomorphized function. auto worthwhile = true; if (onlyWhenHelpful) { - // Optimize both functions using minimal opts, hopefully enough to see if + // Run the optimizer on both functions, hopefully just enough to see if // there is a benefit to the context. We optimize both to avoid confusion // from the function benefiting from simply running another cycle of // optimization. @@ -400,8 +400,8 @@ struct Monomorphize : public Pass { // of the function, which uses memory, which is avoided if we just // keep optimizing from the current contents as we go. It's not // obvious which approach is best here. - doMinimalOpts(func); - doMinimalOpts(monoFunc.get()); + doOpts(func); + doOpts(monoFunc.get()); auto costBefore = CostAnalyzer(func->body).cost; auto costAfter = CostAnalyzer(monoFunc->body).cost; @@ -552,26 +552,16 @@ struct Monomorphize : public Pass { return newFunc; } - // Run minimal function-level optimizations on a function. This optimizes at - // -O1 which is very fast and runs in linear time basically, and so it should - // be reasonable to run as part of this pass: -O1 is several times faster than - // a full -O2, in particular, and so if we run this as part of -O2 we should - // not be making it much slower overall. - // TODO: Perhaps we don't need all of -O1, and can focus on specific things we - // expect to help. That would be faster, but we'd always run the risk of - // missing things, especially as new passes are added later and we don't - // think to add them here. - // Alternatively, perhaps we should have a mode that does use -O1 or - // even -O2 or above, as in theory any optimization could end up - // mattering a lot here. - void doMinimalOpts(Function* func) { + // Run some function-level optimizations on a function. Ideally we would run a + // minimal amount of optimizations here, but we do want to give the optimizer + // as much of a chance to work as possible, so for now do all of -O3 (in + // particular, we really need to run --precompute-propagate so constants are + // applied in the optimized function). + // TODO: Perhaps run -O2 or even -O1 if the function is large (or has many + // locals, etc.), to ensure linear time, but we could miss out. + void doOpts(Function* func) { PassRunner runner(getPassRunner()); - runner.options.optimizeLevel = 1; - // Local subtyping is not run in -O1, but we really do want it here since - // the entire point is that parameters now have more refined types, which - // can lead to locals reading them being refinable as well. - runner.add("local-subtyping"); - // TODO: we need local propagation and escape analysis etc. -O3? + runner.options.optimizeLevel = 3; runner.addDefaultFunctionOptimizationPasses(); runner.setIsNested(true); runner.runOnFunction(func); diff --git a/test/lit/passes/monomorphize-consts.wast b/test/lit/passes/monomorphize-consts.wast index 1dbdf15921c..ec59edfeae5 100644 --- a/test/lit/passes/monomorphize-consts.wast +++ b/test/lit/passes/monomorphize-consts.wast @@ -29,6 +29,8 @@ ;; CAREFUL: (type $3 (func (param i32) (result i32))) + ;; CAREFUL: (type $4 (func (result i32))) + ;; CAREFUL: (import "a" "b" (func $import (type $2) (param i32))) (import "a" "b" (func $import (param i32))) @@ -314,16 +316,13 @@ ;; ALWAYS-NEXT: ) ;; CAREFUL: (func $mutual-recursion-b (type $3) (param $0 i32) (result i32) ;; CAREFUL-NEXT: (i32.add - ;; CAREFUL-NEXT: (call $mutual-recursion-a - ;; CAREFUL-NEXT: (i32.const 0) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $mutual-recursion-a_10) ;; CAREFUL-NEXT: (i32.const 1337) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) (func $mutual-recursion-b (param $x i32) (result i32) (i32.add - ;; This can be optimized (in ALWAYS; to see the benefit in CAREFUL, we - ;; need additional cycles, which we do not do yet). + ;; This can be optimized (as the constant 0 allows work to happen). (call $mutual-recursion-a (i32.const 0) ) @@ -633,3 +632,7 @@ ;; CAREFUL-NEXT: (local.get $0) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $mutual-recursion-a_10 (type $4) (result i32) +;; CAREFUL-NEXT: (i32.const 42) +;; CAREFUL-NEXT: ) diff --git a/test/lit/passes/monomorphize-types.wast b/test/lit/passes/monomorphize-types.wast index 3133d88c512..f98fb08becc 100644 --- a/test/lit/passes/monomorphize-types.wast +++ b/test/lit/passes/monomorphize-types.wast @@ -447,35 +447,35 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; CAREFUL: (func $refinable (type $4) (param $0 (ref $A)) - ;; CAREFUL-NEXT: (local $1 (ref $A)) + ;; CAREFUL-NEXT: (local $1 (ref $B)) + ;; CAREFUL-NEXT: (local $2 (ref $B)) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (ref.cast (ref $B) - ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.tee $1 + ;; CAREFUL-NEXT: (ref.cast (ref $B) + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (ref.cast (ref $B) - ;; CAREFUL-NEXT: (local.tee $1 - ;; CAREFUL-NEXT: (select (result (ref $A)) - ;; CAREFUL-NEXT: (local.get $0) - ;; CAREFUL-NEXT: (struct.new_default $B) - ;; CAREFUL-NEXT: (global.get $global) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.tee $2 + ;; CAREFUL-NEXT: (select (result (ref $B)) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (global.get $global) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (ref.cast (ref $B) - ;; CAREFUL-NEXT: (local.get $1) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $2) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (ref.cast (ref $B) - ;; CAREFUL-NEXT: (local.get $0) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $1) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) (func $refinable (param $ref (ref $A)) + ;; Note that this large function will end up optimized in CAREFUL mode, as a + ;; side effect of our keeping optimizations we run for comparison purposes. + (local $x (ref $A)) ;; The refined version of this function will not have the cast, since ;; optimizations manage to remove it using the more refined type. From 363edc7fc9117824615502e02bf2fb2a05eb9c15 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 11 Jul 2024 15:09:38 -0700 Subject: [PATCH 435/553] Convert memory64 lowering test to lit. NFC (#6731) Test was converted using port_passes_tests_to_lit.py. --- test/lit/passes/memory64-lowering.wast | 283 ++++++++++++++++++ ...ry64_enable-bulk-memory_enable-threads.txt | 221 -------------- ...y64_enable-bulk-memory_enable-threads.wast | 43 --- 3 files changed, 283 insertions(+), 264 deletions(-) create mode 100644 test/lit/passes/memory64-lowering.wast delete mode 100644 test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt delete mode 100644 test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast diff --git a/test/lit/passes/memory64-lowering.wast b/test/lit/passes/memory64-lowering.wast new file mode 100644 index 00000000000..ced06940118 --- /dev/null +++ b/test/lit/passes/memory64-lowering.wast @@ -0,0 +1,283 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --memory64-lowering --enable-memory64 --enable-threads --enable-bulk-memory -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (import "env" "__memory_base" (global $__memory_base i64)) + (import "env" "__memory_base" (global $__memory_base i64)) + ;; CHECK: (import "env" "__memory_base32" (global $__memory_base32 i32)) + + ;; CHECK: (memory $0 1 1) + (memory $0 i64 1 1) + (data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00") + (data (global.get $__memory_base) "foo") + ;; CHECK: (data $0 (i32.const 0) "\00\00\00\00\00\00\00\00\00\00") + + ;; CHECK: (data $1 (global.get $__memory_base32) "foo") + + ;; CHECK: (func $load + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load align=1 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load align=2 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=100 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=100 align=1 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=100 align=2 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=100 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=100 align=1 + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $load + (drop (i32.load (i64.const 4))) + (drop (i32.load align=1 (i64.const 4))) + (drop (i32.load align=2 (i64.const 4))) + (drop (i32.load align=4 (i64.const 4))) + (drop (i32.load offset=100 (i64.const 4))) + (drop (i32.load offset=100 align=1 (i64.const 4))) + (drop (i32.load offset=100 align=2 (i64.const 4))) + (drop (i32.load offset=100 align=4 (i64.const 4))) + (drop (i32.load offset=100 align=1 (unreachable))) + ) + + ;; CHECK: (func $store + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store align=1 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store align=2 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 align=1 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 align=2 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 align=1 + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=100 align=1 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $store + (i32.store (i64.const 4) (i32.const 8)) + (i32.store align=1 (i64.const 4) (i32.const 8)) + (i32.store align=2 (i64.const 4) (i32.const 8)) + (i32.store align=4 (i64.const 4) (i32.const 8)) + (i32.store offset=100 (i64.const 4) (i32.const 8)) + (i32.store offset=100 align=1 (i64.const 4) (i32.const 8)) + (i32.store offset=100 align=2 (i64.const 4) (i32.const 8)) + (i32.store offset=100 align=4 (i64.const 4) (i32.const 8)) + (i32.store offset=100 align=1 (unreachable) (i32.const 8)) + (i32.store offset=100 align=1 (i64.const 4) (unreachable)) + ) + + ;; CHECK: (func $atomics + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.atomic.load + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.atomic.store + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.atomic.rmw8.add_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (memory.atomic.wait32 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (memory.atomic.notify + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $atomics + (drop (i32.atomic.load (i64.const 4))) + (i32.atomic.store (i64.const 4) (i32.const 8)) + (drop (i32.atomic.rmw8.add_u (i64.const 1) (i32.const 2))) + (drop (i32.atomic.rmw8.cmpxchg_u (i64.const 1) (i32.const 2) (i32.const 3))) + (drop (memory.atomic.wait32 (i64.const 1) (i32.const 2) (i64.const 3))) + (drop (memory.atomic.notify (i64.const 1) (i32.const 2))) + ) + + ;; CHECK: (func $other + ;; CHECK-NEXT: (local $0 i64) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (memory.size) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (memory.grow + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.init $0 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.fill + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $other + (local i64) + (local.set 0 (memory.size)) + (local.set 0 (memory.grow (i64.const 1))) + (memory.init 0 (i64.const 1) (i32.const 2) (i32.const 3)) + (memory.fill (i64.const 1) (i32.const 2) (i64.const 3)) + (memory.copy (i64.const 1) (i64.const 2) (i64.const 3)) + ) +) + +(module + ;; CHECK: (memory $0 1 65536) + (memory $0 i64 1 65537) +) diff --git a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt deleted file mode 100644 index 122c7e889dc..00000000000 --- a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.txt +++ /dev/null @@ -1,221 +0,0 @@ -(module - (type $0 (func)) - (import "env" "__memory_base" (global $__memory_base i64)) - (import "env" "__memory_base32" (global $__memory_base32 i32)) - (memory $0 1 1) - (data $0 (i32.const 0) "\00\00\00\00\00\00\00\00\00\00") - (data $1 (global.get $__memory_base32) "foo") - (func $func_1 - (local $0 i64) - (drop - (i32.load - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load align=1 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load align=2 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load offset=100 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load offset=100 align=1 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load offset=100 align=2 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load offset=100 - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (drop - (i32.load offset=100 align=1 - (unreachable) - ) - ) - (i32.store - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store align=1 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store align=2 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store offset=100 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store offset=100 align=1 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store offset=100 align=2 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store offset=100 - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (i32.store offset=100 align=1 - (unreachable) - (i32.const 8) - ) - (i32.store offset=100 align=1 - (i32.wrap_i64 - (i64.const 4) - ) - (unreachable) - ) - (local.set $0 - (i64.extend_i32_u - (memory.size) - ) - ) - (local.set $0 - (i64.extend_i32_u - (memory.grow - (i32.wrap_i64 - (i64.const 1) - ) - ) - ) - ) - (memory.init $0 - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - (i32.const 3) - ) - (memory.fill - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - (i32.wrap_i64 - (i64.const 3) - ) - ) - (memory.copy - (i32.wrap_i64 - (i64.const 1) - ) - (i32.wrap_i64 - (i64.const 2) - ) - (i32.wrap_i64 - (i64.const 3) - ) - ) - (drop - (i32.atomic.load - (i32.wrap_i64 - (i64.const 4) - ) - ) - ) - (i32.atomic.store - (i32.wrap_i64 - (i64.const 4) - ) - (i32.const 8) - ) - (drop - (i32.atomic.rmw8.add_u - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - ) - ) - (drop - (i32.atomic.rmw8.cmpxchg_u - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - (i32.const 3) - ) - ) - (drop - (memory.atomic.wait32 - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - (i64.const 3) - ) - ) - (drop - (memory.atomic.notify - (i32.wrap_i64 - (i64.const 1) - ) - (i32.const 2) - ) - ) - ) -) -(module - (memory $0 1 65536) -) diff --git a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast b/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast deleted file mode 100644 index 7cb89599f69..00000000000 --- a/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory_enable-threads.wast +++ /dev/null @@ -1,43 +0,0 @@ -(module - (import "env" "__memory_base" (global $__memory_base i64)) - (memory $0 i64 1 1) - (data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00") - (data (global.get $__memory_base) "foo") - (func $func_1 - (local i64) - (drop (i32.load (i64.const 4))) - (drop (i32.load align=1 (i64.const 4))) - (drop (i32.load align=2 (i64.const 4))) - (drop (i32.load align=4 (i64.const 4))) - (drop (i32.load offset=100 (i64.const 4))) - (drop (i32.load offset=100 align=1 (i64.const 4))) - (drop (i32.load offset=100 align=2 (i64.const 4))) - (drop (i32.load offset=100 align=4 (i64.const 4))) - (drop (i32.load offset=100 align=1 (unreachable))) - (i32.store (i64.const 4) (i32.const 8)) - (i32.store align=1 (i64.const 4) (i32.const 8)) - (i32.store align=2 (i64.const 4) (i32.const 8)) - (i32.store align=4 (i64.const 4) (i32.const 8)) - (i32.store offset=100 (i64.const 4) (i32.const 8)) - (i32.store offset=100 align=1 (i64.const 4) (i32.const 8)) - (i32.store offset=100 align=2 (i64.const 4) (i32.const 8)) - (i32.store offset=100 align=4 (i64.const 4) (i32.const 8)) - (i32.store offset=100 align=1 (unreachable) (i32.const 8)) - (i32.store offset=100 align=1 (i64.const 4) (unreachable)) - (local.set 0 (memory.size)) - (local.set 0 (memory.grow (i64.const 1))) - (memory.init 0 (i64.const 1) (i32.const 2) (i32.const 3)) - (memory.fill (i64.const 1) (i32.const 2) (i64.const 3)) - (memory.copy (i64.const 1) (i64.const 2) (i64.const 3)) - (drop (i32.atomic.load (i64.const 4))) - (i32.atomic.store (i64.const 4) (i32.const 8)) - (drop (i32.atomic.rmw8.add_u (i64.const 1) (i32.const 2))) - (drop (i32.atomic.rmw8.cmpxchg_u (i64.const 1) (i32.const 2) (i32.const 3))) - (drop (memory.atomic.wait32 (i64.const 1) (i32.const 2) (i64.const 3))) - (drop (memory.atomic.notify (i64.const 1) (i32.const 2))) - ) -) - -(module - (memory $0 i64 1 65537) -) From 22c28bd5a108f9bdacd1b60468e312903bcdf451 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 11 Jul 2024 16:36:13 -0700 Subject: [PATCH 436/553] Memory64Lowering: Handle -1 return value from memory.grow (#6733) This edge case make the lowering a little more tricky. --- src/passes/Memory64Lowering.cpp | 27 ++++++++++++++++++++++++-- test/lit/passes/memory64-lowering.wast | 22 +++++++++++++++++---- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/passes/Memory64Lowering.cpp b/src/passes/Memory64Lowering.cpp index c1ce3dd919d..879858b71b0 100644 --- a/src/passes/Memory64Lowering.cpp +++ b/src/passes/Memory64Lowering.cpp @@ -79,9 +79,32 @@ struct Memory64Lowering : public WalkerPass> { if (memory->is64()) { wrapAddress64(curr->delta, curr->memory); auto* size = static_cast(curr); - extendAddress64(size, curr->memory); + // MemoryGrow returns -1 in case of failure. We cannot just use + // extend_32_u in this case so we handle it as follows: + // + // (if (result i64) + // (i32.eq (i32.const -1) (local.tee $tmp (memory.grow X))) + // (then + // (i64.const -1) + // ) + // (else + // (i32.extend_32_u (local.get $tmp)) + // ) + // ) + Builder builder(module); + auto tmp = builder.addVar(getFunction(), Type::i32); + Expression* isMinusOne = + builder.makeBinary(EqInt32, + builder.makeConst(int32_t(-1)), + builder.makeLocalTee(tmp, size, Type::i32)); + auto* newSize = builder.makeLocalGet(tmp, Type::i32); + builder.makeUnary(UnaryOp::ExtendUInt32, newSize); + Expression* ifExp = + builder.makeIf(isMinusOne, + builder.makeConst(int64_t(-1)), + builder.makeUnary(UnaryOp::ExtendUInt32, newSize)); curr->type = Type::i32; - replaceCurrent(size); + replaceCurrent(ifExp); } } diff --git a/test/lit/passes/memory64-lowering.wast b/test/lit/passes/memory64-lowering.wast index ced06940118..4f9d3d050ac 100644 --- a/test/lit/passes/memory64-lowering.wast +++ b/test/lit/passes/memory64-lowering.wast @@ -225,16 +225,30 @@ ;; CHECK: (func $other ;; CHECK-NEXT: (local $0 i64) + ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.extend_i32_u ;; CHECK-NEXT: (memory.size) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (i64.extend_i32_u - ;; CHECK-NEXT: (memory.grow - ;; CHECK-NEXT: (i32.wrap_i64 - ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: (if (result i64) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (memory.grow + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) From c0286b61a0eedde936ce1adff4284859ce4c6510 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 12 Jul 2024 13:02:00 -0400 Subject: [PATCH 437/553] Do not abbreviate items in element segments (#6737) The full syntax for an expression in an element syntax looks like `(item (ref.null none))`, but we have been printing the abbreviated version, which omits the `(item ...)`. This abbreviation is only valid when the item has only a single instruction, so it is not always correct to use it. Rather than determining whether or not to use the abbreviation on a case-by-case basis, always print the full syntax. --- src/passes/Print.cpp | 3 +- test/lit/basic/multi-table.wast | 30 +++++++++---------- ...imize-instructions-call_ref-roundtrip.wast | 6 ++-- .../optimize-instructions-call_ref.wast | 2 +- test/lit/passes/table64-lowering.wast | 4 +-- test/lit/passes/unsubtyping.wast | 2 +- test/lit/wat-kitchen-sink.wast | 14 ++++----- 7 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 1d07b7f3c14..2e980077523 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -3089,8 +3089,9 @@ void PrintSExpression::visitElementSegment(ElementSegment* curr) { } } else { for (auto* entry : curr->data) { - o << ' '; + o << " (item "; visit(entry); + o << ')'; } } o << ')' << maybeNewLine; diff --git a/test/lit/basic/multi-table.wast b/test/lit/basic/multi-table.wast index 64de79df004..71dd275aa72 100644 --- a/test/lit/basic/multi-table.wast +++ b/test/lit/basic/multi-table.wast @@ -57,21 +57,21 @@ ;; CHECK-BIN: (elem $activeNonZeroOffset (table $t2) (i32.const 1) func $f $g) (elem $activeNonZeroOffset (table $t2) (offset (i32.const 1)) func $f $g) - ;; CHECK-TEXT: (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) - ;; CHECK-BIN: (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null nofunc)) + ;; CHECK-TEXT: (elem $e3-1 (table $t3) (global.get $g2) funcref (item (ref.func $f)) (item (ref.null nofunc))) + ;; CHECK-BIN: (elem $e3-1 (table $t3) (global.get $g2) funcref (item (ref.func $f)) (item (ref.null nofunc))) (elem $e3-1 (table $t3) (global.get $g2) funcref (ref.func $f) (ref.null func)) - ;; CHECK-TEXT: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) - ;; CHECK-BIN: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (ref.func $f) (ref.func $g)) + ;; CHECK-TEXT: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $g))) + ;; CHECK-BIN: (elem $e3-2 (table $t3) (i32.const 2) (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $g))) (elem $e3-2 (table $t3) (offset (i32.const 2)) (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g))) ;; CHECK-TEXT: (elem $passive-1 func $f $g) ;; CHECK-BIN: (elem $passive-1 func $f $g) (elem $passive-1 func $f $g) - ;; CHECK-TEXT: (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) - ;; CHECK-BIN: (elem $passive-2 funcref (ref.func $f) (ref.func $g) (ref.null nofunc)) + ;; CHECK-TEXT: (elem $passive-2 funcref (item (ref.func $f)) (item (ref.func $g)) (item (ref.null nofunc))) + ;; CHECK-BIN: (elem $passive-2 funcref (item (ref.func $f)) (item (ref.func $g)) (item (ref.null nofunc))) (elem $passive-2 funcref (item ref.func $f) (item (ref.func $g)) (ref.null func)) - ;; CHECK-TEXT: (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) - ;; CHECK-BIN: (elem $passive-3 (ref null $none_=>_none) (ref.func $f) (ref.func $g) (ref.null nofunc) (global.get $g1)) + ;; CHECK-TEXT: (elem $passive-3 (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $g)) (item (ref.null nofunc)) (item (global.get $g1))) + ;; CHECK-BIN: (elem $passive-3 (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $g)) (item (ref.null nofunc)) (item (global.get $g1))) (elem $passive-3 (ref null $none_=>_none) (item ref.func $f) (item (ref.func $g)) (ref.null $none_=>_none) (global.get $g1)) ;; CHECK-TEXT: (elem $empty func) ;; CHECK-BIN: (elem $empty func) @@ -80,8 +80,8 @@ ;; This elem will be emitted as usesExpressions because of the type of the ;; table. - ;; CHECK-TEXT: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) - ;; CHECK-BIN: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) + ;; CHECK-TEXT: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $h))) + ;; CHECK-BIN: (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (item (ref.func $f)) (item (ref.func $h))) (elem $especial (table $tspecial) (i32.const 0) (ref null $none_=>_none) (ref.func $f) (ref.func $h)) ;; CHECK-TEXT: (func $f (type $none_=>_none) @@ -134,19 +134,19 @@ ;; CHECK-BIN-NODEBUG: (elem $2 (table $0) (i32.const 1) func $0 $1) -;; CHECK-BIN-NODEBUG: (elem $3 (table $1) (global.get $global$1) funcref (ref.func $0) (ref.null nofunc)) +;; CHECK-BIN-NODEBUG: (elem $3 (table $1) (global.get $global$1) funcref (item (ref.func $0)) (item (ref.null nofunc))) -;; CHECK-BIN-NODEBUG: (elem $4 (table $1) (i32.const 2) (ref null $0) (ref.func $0) (ref.func $1)) +;; CHECK-BIN-NODEBUG: (elem $4 (table $1) (i32.const 2) (ref null $0) (item (ref.func $0)) (item (ref.func $1))) ;; CHECK-BIN-NODEBUG: (elem $5 func $0 $1) -;; CHECK-BIN-NODEBUG: (elem $6 funcref (ref.func $0) (ref.func $1) (ref.null nofunc)) +;; CHECK-BIN-NODEBUG: (elem $6 funcref (item (ref.func $0)) (item (ref.func $1)) (item (ref.null nofunc))) -;; CHECK-BIN-NODEBUG: (elem $7 (ref null $0) (ref.func $0) (ref.func $1) (ref.null nofunc) (global.get $global$0)) +;; CHECK-BIN-NODEBUG: (elem $7 (ref null $0) (item (ref.func $0)) (item (ref.func $1)) (item (ref.null nofunc)) (item (global.get $global$0))) ;; CHECK-BIN-NODEBUG: (elem $8 func) -;; CHECK-BIN-NODEBUG: (elem $9 (table $3) (i32.const 0) (ref null $0) (ref.func $0) (ref.func $2)) +;; CHECK-BIN-NODEBUG: (elem $9 (table $3) (i32.const 0) (ref null $0) (item (ref.func $0)) (item (ref.func $2))) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (drop diff --git a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast index 6fdcae0b20b..05f03110c40 100644 --- a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast +++ b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast @@ -33,15 +33,15 @@ ;; CHECK: (table $table-3 10 (ref null $v3)) (table $table-3 10 (ref null $v3)) - ;; CHECK: (elem $elem-1 (table $table-1) (i32.const 0) (ref null $v1) (ref.func $helper-1)) + ;; CHECK: (elem $elem-1 (table $table-1) (i32.const 0) (ref null $v1) (item (ref.func $helper-1))) (elem $elem-1 (table $table-1) (i32.const 0) (ref null $v1) (ref.func $helper-1)) - ;; CHECK: (elem $elem-2 (table $table-2) (i32.const 0) (ref null $v2) (ref.func $helper-2)) + ;; CHECK: (elem $elem-2 (table $table-2) (i32.const 0) (ref null $v2) (item (ref.func $helper-2))) (elem $elem-2 (table $table-2) (i32.const 0) (ref null $v2) (ref.func $helper-2)) - ;; CHECK: (elem $elem-3 (table $table-3) (i32.const 0) (ref null $v3) (ref.func $helper-3)) + ;; CHECK: (elem $elem-3 (table $table-3) (i32.const 0) (ref null $v3) (item (ref.func $helper-3))) (elem $elem-3 (table $table-3) (i32.const 0) (ref null $v3) (ref.func $helper-3)) diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast index 91aba5fed8e..937fbe6a766 100644 --- a/test/lit/passes/optimize-instructions-call_ref.wast +++ b/test/lit/passes/optimize-instructions-call_ref.wast @@ -23,7 +23,7 @@ ;; CHECK: (table $table-1 10 (ref null $i32_i32_=>_none)) (table $table-1 10 (ref null $i32_i32_=>_none)) - ;; CHECK: (elem $elem-1 (table $table-1) (i32.const 0) (ref null $i32_i32_=>_none) (ref.func $foo)) + ;; CHECK: (elem $elem-1 (table $table-1) (i32.const 0) (ref null $i32_i32_=>_none) (item (ref.func $foo))) (elem $elem-1 (table $table-1) (i32.const 0) (ref null $i32_i32_=>_none) (ref.func $foo)) diff --git a/test/lit/passes/table64-lowering.wast b/test/lit/passes/table64-lowering.wast index 19d51eec5c5..7e49d3e7303 100644 --- a/test/lit/passes/table64-lowering.wast +++ b/test/lit/passes/table64-lowering.wast @@ -12,11 +12,11 @@ ;; CHECK: (table $t32 10 100 funcref) - ;; CHECK: (elem $elem64 (table $t64) (i32.const 0) funcref (ref.null nofunc)) + ;; CHECK: (elem $elem64 (table $t64) (i32.const 0) funcref (item (ref.null nofunc))) (elem $elem64 (table $t64) (i64.const 0) funcref (ref.null func)) (table $t32 10 100 funcref) - ;; CHECK: (elem $elem32 (table $t32) (i32.const 0) funcref (ref.null nofunc)) + ;; CHECK: (elem $elem32 (table $t32) (i32.const 0) funcref (item (ref.null nofunc))) (elem $elem32 (table $t32) (i32.const 0) funcref (ref.null func)) ;; CHECK: (func $test_call_indirect diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index 368f935b9fc..65d4d6a4847 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -103,7 +103,7 @@ ;; An active element segment requires subtyping. So does an element segment ;; element. - ;; CHECK: (elem $e (table $t) (i32.const 0) (ref null $sub) (struct.new_default $subsub)) + ;; CHECK: (elem $e (table $t) (i32.const 0) (ref null $sub) (item (struct.new_default $subsub))) (elem $e (table $t) (offset (i32.const 0)) (ref null $sub) (struct.new $subsub)) ) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 730d9773e0e..252673198b1 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -375,13 +375,13 @@ (table $table-any anyref (elem (item i32.const 0 ref.i31) (ref.null any) (item (ref.i31 (i32.const 0))))) ;; elems - ;; CHECK: (elem $implicit-elem (table $table-any) (i32.const 0) anyref (ref.i31 + ;; CHECK: (elem $implicit-elem (table $table-any) (i32.const 0) anyref (item (ref.i31 ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) (ref.null none) (ref.i31 + ;; CHECK-NEXT: )) (item (ref.null none)) (item (ref.i31 ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: )) + ;; CHECK-NEXT: ))) - ;; CHECK: (elem $implicit-table (table $timport$0) (i32.const 0) funcref (ref.null nofunc) (ref.null nofunc) (ref.null nofunc)) + ;; CHECK: (elem $implicit-table (table $timport$0) (i32.const 0) funcref (item (ref.null nofunc)) (item (ref.null nofunc)) (item (ref.null nofunc))) (elem $implicit-table (offset i32.const 0) funcref (ref.null func) (item ref.null func) (item (ref.null func))) ;; CHECK: (elem $implicit-table-2 (table $timport$0) (i32.const 1) func) @@ -393,16 +393,16 @@ ;; CHECK: (elem $implicit-table-legacy-indices (table $timport$0) (i32.const 3) func $fimport$0 $fimport$1 $2 $f1) (elem $implicit-table-legacy-indices (i32.const 3) 0 1 2 3) - ;; CHECK: (elem $explicit-table (table $timport$0) (i32.const 0) funcref (ref.null nofunc)) + ;; CHECK: (elem $explicit-table (table $timport$0) (i32.const 0) funcref (item (ref.null nofunc))) (elem $explicit-table (table 0) (offset (i32.const 0)) funcref (item ref.null func)) ;; CHECK: (elem $explicit-table-named (table $table-any) (i32.const 1) anyref) (elem $explicit-table-named (table $table-any) (i32.const 1) anyref) - ;; CHECK: (elem $passive (ref null $s0) (struct.new_default $s0) (struct.new_default $s0)) + ;; CHECK: (elem $passive (ref null $s0) (item (struct.new_default $s0)) (item (struct.new_default $s0))) (elem $passive (ref null $s0) (item struct.new $s0) (struct.new $s0)) - ;; CHECK: (elem $passive-2 anyref (struct.new_default $s0) (struct.new_default $s0)) + ;; CHECK: (elem $passive-2 anyref (item (struct.new_default $s0)) (item (struct.new_default $s0))) (elem $passive-2 anyref (item struct.new $s0) (struct.new $s0)) ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set) From 0e0e08db6280dec4f4fcce2dff3ba07445c45b8a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 12 Jul 2024 13:37:40 -0700 Subject: [PATCH 438/553] SafeHeap: Handle overflows when adding the pointer and the size (#6409) E.g. loading 4 bytes from 2^32 - 2 should error: 2 bytes are past the maximum address. Before this PR we added 2^32 - 2 + 4 and overflowed to 2, which we saw as a low and safe address. This PR adds an extra check for an overflow in that add. Also add unreachables after calls to segfault(), which reduces the overhead of the extra check here (the unreachable apparently allows VMs to see that control flow ends, after the segfault() which is truly no-return). Fixes emscripten-core/emscripten#21557 --- src/passes/SafeHeap.cpp | 44 +- test/passes/safe-heap_disable-simd.txt | 3135 ++++++++---- .../safe-heap_enable-threads_enable-simd.txt | 4427 +++++++++++------ ...safe-heap_enable-threads_enable-simd64.txt | 4427 +++++++++++------ ...mory-unused_enable-threads_enable-simd.txt | 4427 +++++++++++------ test/passes/safe-heap_start-function.txt | 1045 ++-- 6 files changed, 11980 insertions(+), 5525 deletions(-) diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index b2f7db56756..7baeb365e39 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -288,6 +288,7 @@ struct SafeHeap : public Pass { auto func = Builder::makeFunction(name, funcSig, {indexType}); Builder builder(*module); auto* block = builder.makeBlock(); + // stash the sum of the pointer (0) and the size (1) in a local (2) block->list.push_back(builder.makeLocalSet( 2, builder.makeBinary(memory->is64() ? AddInt64 : AddInt32, @@ -296,6 +297,7 @@ struct SafeHeap : public Pass { // check for reading past valid memory: if pointer + offset + bytes block->list.push_back(makeBoundsCheck(style.type, builder, + 0, 2, style.bytes, module, @@ -346,6 +348,7 @@ struct SafeHeap : public Pass { // check for reading past valid memory: if pointer + offset + bytes block->list.push_back(makeBoundsCheck(style.valueType, builder, + 0, 3, style.bytes, module, @@ -386,9 +389,14 @@ struct SafeHeap : public Pass { builder.makeCall(alignfault, {}, Type::none)); } + // Constructs a bounds check. This receives the indexes of two locals: the + // pointer local, which contains the pointer we are checking, and the sum + // local which contains the pointer added to the number of bytes being + // accessed. Expression* makeBoundsCheck(Type type, Builder& builder, - Index local, + Index ptrLocal, + Index sumLocal, Index bytes, Module* module, Type indexType, @@ -415,19 +423,33 @@ struct SafeHeap : public Pass { } auto gtuOp = is64 ? GtUInt64 : GtUInt32; auto addOp = is64 ? AddInt64 : AddInt32; + auto* upperCheck = + builder.makeBinary(upperOp, + builder.makeLocalGet(sumLocal, indexType), + builder.makeConstPtr(upperBound, indexType)); + auto* lowerCheck = builder.makeBinary( + gtuOp, + builder.makeBinary(addOp, + builder.makeLocalGet(sumLocal, indexType), + builder.makeConstPtr(bytes, indexType)), + brkLocation); + // Check for an overflow when adding the pointer and the size, using the + // rule that for any unsigned x and y, + // x + y < x <=> x + y overflows + auto* overflowCheck = + builder.makeBinary(is64 ? LtUInt64 : LtUInt32, + builder.makeLocalGet(sumLocal, indexType), + builder.makeLocalGet(ptrLocal, indexType)); + // Add an unreachable right after the call to segfault for performance + // reasons: the call never returns, and this helps optimizations benefit + // from that. return builder.makeIf( builder.makeBinary( OrInt32, - builder.makeBinary(upperOp, - builder.makeLocalGet(local, indexType), - builder.makeConstPtr(upperBound, indexType)), - builder.makeBinary( - gtuOp, - builder.makeBinary(addOp, - builder.makeLocalGet(local, indexType), - builder.makeConstPtr(bytes, indexType)), - brkLocation)), - builder.makeCall(segfault, {}, Type::none)); + upperCheck, + builder.makeBinary(OrInt32, lowerCheck, overflowCheck)), + builder.makeSequence(builder.makeCall(segfault, {}, Type::none), + builder.makeUnreachable())); } }; diff --git a/test/passes/safe-heap_disable-simd.txt b/test/passes/safe-heap_disable-simd.txt index bb55667b1cb..e3ff8f6c2e4 100644 --- a/test/passes/safe-heap_disable-simd.txt +++ b/test/passes/safe-heap_disable-simd.txt @@ -27,18 +27,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -59,18 +66,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -91,18 +105,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -123,18 +144,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -164,18 +192,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -196,18 +231,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -237,18 +279,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -269,18 +318,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -310,18 +366,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -351,18 +414,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -383,18 +453,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -415,18 +492,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -447,18 +531,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -488,18 +579,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -520,18 +618,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -561,18 +666,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -593,18 +705,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -634,18 +753,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -675,18 +801,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -707,18 +840,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -748,18 +888,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -789,18 +936,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -821,18 +975,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -862,18 +1023,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -903,18 +1071,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -944,18 +1119,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -976,18 +1158,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1017,18 +1206,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1058,18 +1254,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -1090,18 +1293,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1131,18 +1341,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1172,18 +1389,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1213,18 +1437,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -1246,18 +1477,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -1279,18 +1517,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1321,18 +1566,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -1354,18 +1606,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1396,18 +1655,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1438,18 +1704,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -1471,18 +1744,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -1504,18 +1784,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1546,18 +1833,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -1579,18 +1873,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1621,18 +1922,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1663,18 +1971,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -1696,18 +2011,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1738,18 +2060,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1780,18 +2109,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1822,18 +2158,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -1855,18 +2198,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1897,18 +2247,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1939,18 +2296,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -1972,18 +2336,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2014,18 +2385,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2056,18 +2434,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2114,18 +2499,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -2146,18 +2538,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -2178,18 +2577,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -2210,18 +2616,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2251,18 +2664,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -2283,18 +2703,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2324,18 +2751,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -2356,18 +2790,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2397,18 +2838,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2438,18 +2886,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -2470,18 +2925,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -2502,18 +2964,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -2534,18 +3003,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2575,18 +3051,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -2607,18 +3090,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2648,18 +3138,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -2680,18 +3177,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2721,18 +3225,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2762,18 +3273,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -2794,18 +3312,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2835,18 +3360,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2876,18 +3408,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -2908,18 +3447,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2949,18 +3495,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2990,18 +3543,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3031,18 +3591,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -3063,18 +3630,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3104,18 +3678,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3145,18 +3726,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -3177,18 +3765,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3218,18 +3813,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3259,18 +3861,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3300,18 +3909,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -3333,18 +3949,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -3366,18 +3989,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3408,18 +4038,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -3441,18 +4078,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3483,18 +4127,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3525,18 +4176,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -3558,18 +4216,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -3591,18 +4256,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3633,18 +4305,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -3666,18 +4345,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3708,18 +4394,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3750,18 +4443,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -3783,18 +4483,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3825,18 +4532,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3867,18 +4581,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3909,18 +4630,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -3942,18 +4670,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3984,18 +4719,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4026,18 +4768,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -4059,18 +4808,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4101,18 +4857,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4143,18 +4906,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4209,18 +4979,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -4241,18 +5018,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -4273,18 +5057,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -4305,18 +5096,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4346,18 +5144,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -4378,18 +5183,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4419,18 +5231,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -4451,18 +5270,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4492,18 +5318,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4533,18 +5366,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -4565,18 +5405,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -4597,18 +5444,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -4629,18 +5483,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4670,18 +5531,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -4702,18 +5570,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4743,18 +5618,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -4775,18 +5657,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4816,18 +5705,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4857,18 +5753,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -4889,18 +5792,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4930,18 +5840,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4971,18 +5888,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -5003,18 +5927,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5044,18 +5975,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5085,18 +6023,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5126,18 +6071,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -5158,18 +6110,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5199,18 +6158,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5240,18 +6206,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -5272,18 +6245,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5313,18 +6293,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5354,18 +6341,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5395,18 +6389,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -5428,18 +6429,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -5461,18 +6469,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5503,18 +6518,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -5536,18 +6558,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5578,18 +6607,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5620,18 +6656,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -5653,18 +6696,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -5686,18 +6736,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5728,18 +6785,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -5761,18 +6825,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5803,18 +6874,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5845,18 +6923,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -5878,18 +6963,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5920,18 +7012,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5962,18 +7061,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6004,18 +7110,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -6037,18 +7150,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6079,18 +7199,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6121,18 +7248,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -6154,18 +7288,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6196,18 +7337,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6238,18 +7386,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if diff --git a/test/passes/safe-heap_enable-threads_enable-simd.txt b/test/passes/safe-heap_enable-threads_enable-simd.txt index aeea4f02cd0..ffc912a3c74 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd.txt @@ -198,18 +198,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -236,18 +243,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -268,18 +282,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -300,18 +321,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -332,18 +360,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -364,18 +399,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -411,18 +453,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -452,18 +501,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -484,18 +540,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -525,18 +588,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -566,18 +636,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -598,18 +675,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -639,18 +723,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -680,18 +771,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -721,18 +819,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -759,18 +864,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -791,18 +903,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -823,18 +942,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -855,18 +981,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -887,18 +1020,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -934,18 +1074,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -975,18 +1122,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -1007,18 +1161,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1048,18 +1209,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1089,18 +1257,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -1121,18 +1296,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1162,18 +1344,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1209,18 +1398,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1250,18 +1446,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -1282,18 +1485,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1323,18 +1533,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1364,18 +1581,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1405,18 +1629,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -1437,18 +1668,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1478,18 +1716,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1519,18 +1764,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1560,18 +1812,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1601,18 +1860,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -1633,18 +1899,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1674,18 +1947,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1715,18 +1995,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -1747,18 +2034,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1788,18 +2082,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1829,18 +2130,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1870,18 +2178,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -1902,18 +2217,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1943,18 +2265,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1984,18 +2313,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2025,18 +2361,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2066,18 +2409,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -2099,18 +2449,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -2132,18 +2489,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -2165,18 +2529,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2207,18 +2578,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2249,18 +2627,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -2282,18 +2667,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2324,18 +2716,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2366,18 +2765,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2408,18 +2814,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -2441,18 +2854,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -2474,18 +2894,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -2507,18 +2934,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2549,18 +2983,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2591,18 +3032,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -2624,18 +3072,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2666,18 +3121,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2708,18 +3170,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2750,18 +3219,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -2783,18 +3259,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2825,18 +3308,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2867,18 +3357,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2909,18 +3406,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2951,18 +3455,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -2984,18 +3495,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3026,18 +3544,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3068,18 +3593,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -3101,18 +3633,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3143,18 +3682,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3185,18 +3731,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3227,18 +3780,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -3260,18 +3820,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3302,18 +3869,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3344,18 +3918,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3386,18 +3967,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3454,18 +4042,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -3486,18 +4081,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -3518,18 +4120,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -3550,18 +4159,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3591,18 +4207,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -3623,18 +4246,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3664,18 +4294,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -3696,18 +4333,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3737,18 +4381,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3778,18 +4429,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -3810,18 +4468,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -3842,18 +4507,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -3874,18 +4546,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3915,18 +4594,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -3947,18 +4633,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3988,18 +4681,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -4020,18 +4720,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4061,18 +4768,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4102,18 +4816,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -4134,18 +4855,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4175,18 +4903,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4216,18 +4951,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -4248,18 +4990,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4289,18 +5038,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4330,18 +5086,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4371,18 +5134,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -4403,18 +5173,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4444,18 +5221,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4485,18 +5269,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -4517,18 +5308,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4558,18 +5356,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4599,18 +5404,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4640,18 +5452,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -4672,18 +5491,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4713,18 +5539,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4754,18 +5587,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4795,18 +5635,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4836,18 +5683,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -4869,18 +5723,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -4902,18 +5763,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4944,18 +5812,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -4977,18 +5852,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5019,18 +5901,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5061,18 +5950,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -5094,18 +5990,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -5127,18 +6030,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5169,18 +6079,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -5202,18 +6119,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5244,18 +6168,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5286,18 +6217,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -5319,18 +6257,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5361,18 +6306,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5403,18 +6355,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5445,18 +6404,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -5478,18 +6444,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5520,18 +6493,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5562,18 +6542,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -5595,18 +6582,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5637,18 +6631,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5679,18 +6680,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5721,18 +6729,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -5754,18 +6769,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5796,18 +6818,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5838,18 +6867,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5880,18 +6916,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5953,18 +6996,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -5991,18 +7041,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -6023,18 +7080,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -6055,18 +7119,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -6087,18 +7158,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -6119,18 +7197,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6166,18 +7251,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6207,18 +7299,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -6239,18 +7338,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6280,18 +7386,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6321,18 +7434,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -6353,18 +7473,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6394,18 +7521,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6435,18 +7569,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6476,18 +7617,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -6514,18 +7662,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -6546,18 +7701,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -6578,18 +7740,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -6610,18 +7779,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -6642,18 +7818,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6689,18 +7872,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6730,18 +7920,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -6762,18 +7959,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6803,18 +8007,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6844,18 +8055,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -6876,18 +8094,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6917,18 +8142,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6964,18 +8196,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7005,18 +8244,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -7037,18 +8283,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7078,18 +8331,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7119,18 +8379,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7160,18 +8427,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -7192,18 +8466,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7233,18 +8514,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7274,18 +8562,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7315,18 +8610,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7356,18 +8658,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -7388,18 +8697,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7429,18 +8745,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7470,18 +8793,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -7502,18 +8832,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7543,18 +8880,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7584,18 +8928,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7625,18 +8976,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -7657,18 +9015,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7698,18 +9063,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7739,18 +9111,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7780,18 +9159,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7821,18 +9207,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -7854,18 +9247,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -7887,18 +9287,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -7920,18 +9327,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7962,18 +9376,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8004,18 +9425,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -8037,18 +9465,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8079,18 +9514,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8121,18 +9563,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8163,18 +9612,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -8196,18 +9652,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -8229,18 +9692,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -8262,18 +9732,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8304,18 +9781,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8346,18 +9830,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -8379,18 +9870,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8421,18 +9919,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8463,18 +9968,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8505,18 +10017,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -8538,18 +10057,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8580,18 +10106,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8622,18 +10155,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8664,18 +10204,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8706,18 +10253,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -8739,18 +10293,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8781,18 +10342,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8823,18 +10391,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -8856,18 +10431,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8898,18 +10480,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8940,18 +10529,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8982,18 +10578,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -9015,18 +10618,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9057,18 +10667,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9099,18 +10716,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9141,18 +10765,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if diff --git a/test/passes/safe-heap_enable-threads_enable-simd64.txt b/test/passes/safe-heap_enable-threads_enable-simd64.txt index c76b664d53d..38482cd7d1c 100644 --- a/test/passes/safe-heap_enable-threads_enable-simd64.txt +++ b/test/passes/safe-heap_enable-threads_enable-simd64.txt @@ -198,18 +198,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -236,18 +243,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -268,18 +282,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -300,18 +321,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -332,18 +360,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -364,18 +399,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -413,18 +455,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -456,18 +505,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -488,18 +544,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -531,18 +594,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -574,18 +644,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -606,18 +683,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -649,18 +733,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -692,18 +783,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -735,18 +833,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -773,18 +878,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -805,18 +917,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -837,18 +956,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -869,18 +995,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -901,18 +1034,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -950,18 +1090,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -993,18 +1140,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -1025,18 +1179,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1068,18 +1229,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1111,18 +1279,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -1143,18 +1318,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1186,18 +1368,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1235,18 +1424,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1278,18 +1474,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -1310,18 +1513,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1353,18 +1563,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1396,18 +1613,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1439,18 +1663,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -1471,18 +1702,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1514,18 +1752,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1557,18 +1802,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1600,18 +1852,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1643,18 +1902,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -1675,18 +1941,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1718,18 +1991,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1761,18 +2041,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -1793,18 +2080,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1836,18 +2130,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1879,18 +2180,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1922,18 +2230,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -1954,18 +2269,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1997,18 +2319,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2040,18 +2369,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2083,18 +2419,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2126,18 +2469,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -2159,18 +2509,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -2192,18 +2549,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -2225,18 +2589,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2269,18 +2640,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2313,18 +2691,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -2346,18 +2731,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2390,18 +2782,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2434,18 +2833,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2478,18 +2884,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -2511,18 +2924,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -2544,18 +2964,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -2577,18 +3004,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2621,18 +3055,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2665,18 +3106,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -2698,18 +3146,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2742,18 +3197,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2786,18 +3248,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2830,18 +3299,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -2863,18 +3339,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2907,18 +3390,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2951,18 +3441,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2995,18 +3492,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3039,18 +3543,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -3072,18 +3583,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3116,18 +3634,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3160,18 +3685,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -3193,18 +3725,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3237,18 +3776,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3281,18 +3827,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3325,18 +3878,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -3358,18 +3918,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3402,18 +3969,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3446,18 +4020,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3490,18 +4071,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3560,18 +4148,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -3592,18 +4187,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -3624,18 +4226,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -3656,18 +4265,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3699,18 +4315,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -3731,18 +4354,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3774,18 +4404,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -3806,18 +4443,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3849,18 +4493,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3892,18 +4543,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -3924,18 +4582,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -3956,18 +4621,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -3988,18 +4660,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4031,18 +4710,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -4063,18 +4749,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4106,18 +4799,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -4138,18 +4838,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4181,18 +4888,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4224,18 +4938,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -4256,18 +4977,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4299,18 +5027,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4342,18 +5077,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -4374,18 +5116,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4417,18 +5166,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4460,18 +5216,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4503,18 +5266,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -4535,18 +5305,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4578,18 +5355,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4621,18 +5405,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -4653,18 +5444,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4696,18 +5494,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4739,18 +5544,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4782,18 +5594,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -4814,18 +5633,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4857,18 +5683,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4900,18 +5733,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4943,18 +5783,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4986,18 +5833,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -5019,18 +5873,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -5052,18 +5913,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5096,18 +5964,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -5129,18 +6004,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5173,18 +6055,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5217,18 +6106,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -5250,18 +6146,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -5283,18 +6186,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5327,18 +6237,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -5360,18 +6277,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5404,18 +6328,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5448,18 +6379,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -5481,18 +6419,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5525,18 +6470,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5569,18 +6521,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5613,18 +6572,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -5646,18 +6612,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5690,18 +6663,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5734,18 +6714,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -5767,18 +6754,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5811,18 +6805,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5855,18 +6856,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5899,18 +6907,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -5932,18 +6947,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5976,18 +6998,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6020,18 +7049,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6064,18 +7100,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i64.load - (call $emscripten_get_sbrk_ptr) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6139,18 +7182,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -6177,18 +7227,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -6209,18 +7266,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -6241,18 +7305,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -6273,18 +7344,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -6305,18 +7383,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6354,18 +7439,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6397,18 +7489,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -6429,18 +7528,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6472,18 +7578,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6515,18 +7628,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -6547,18 +7667,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6590,18 +7717,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6633,18 +7767,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6676,18 +7817,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -6714,18 +7862,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -6746,18 +7901,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -6778,18 +7940,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -6810,18 +7979,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -6842,18 +8018,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6891,18 +8074,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6934,18 +8124,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -6966,18 +8163,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7009,18 +8213,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7052,18 +8263,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -7084,18 +8302,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7127,18 +8352,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7176,18 +8408,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7219,18 +8458,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -7251,18 +8497,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7294,18 +8547,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7337,18 +8597,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7380,18 +8647,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -7412,18 +8686,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7455,18 +8736,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7498,18 +8786,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7541,18 +8836,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7584,18 +8886,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -7616,18 +8925,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7659,18 +8975,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7702,18 +9025,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -7734,18 +9064,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7777,18 +9114,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7820,18 +9164,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7863,18 +9214,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -7895,18 +9253,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7938,18 +9303,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7981,18 +9353,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8024,18 +9403,25 @@ (local.get $2) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $2) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $2) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8067,18 +9453,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -8100,18 +9493,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -8133,18 +9533,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -8166,18 +9573,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8210,18 +9624,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8254,18 +9675,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -8287,18 +9715,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8331,18 +9766,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8375,18 +9817,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8419,18 +9868,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -8452,18 +9908,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 1) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 1) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -8485,18 +9948,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -8518,18 +9988,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8562,18 +10039,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 2) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 2) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8606,18 +10090,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -8639,18 +10130,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8683,18 +10181,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8727,18 +10232,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8771,18 +10283,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -8804,18 +10323,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8848,18 +10374,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8892,18 +10425,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8936,18 +10476,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8980,18 +10527,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -9013,18 +10567,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9057,18 +10618,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 4) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 4) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9101,18 +10669,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -9134,18 +10709,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9178,18 +10760,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9222,18 +10811,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 8) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 8) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9266,18 +10862,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -9299,18 +10902,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9343,18 +10953,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9387,18 +11004,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9431,18 +11055,25 @@ (local.get $3) (i64.const 0) ) - (i64.gt_u - (i64.add - (local.get $3) - (i64.const 16) + (i32.or + (i64.gt_u + (i64.add + (local.get $3) + (i64.const 16) + ) + (i64.load + (call $foo) + ) ) - (i64.load - (call $foo) + (i64.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if diff --git a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt index 02904abadeb..72b68f218e5 100644 --- a/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt +++ b/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt @@ -198,18 +198,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -236,18 +243,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -268,18 +282,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -300,18 +321,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -332,18 +360,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -364,18 +399,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -411,18 +453,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -452,18 +501,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -484,18 +540,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -525,18 +588,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -566,18 +636,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -598,18 +675,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -639,18 +723,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -680,18 +771,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -721,18 +819,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -759,18 +864,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -791,18 +903,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -823,18 +942,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -855,18 +981,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -887,18 +1020,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -934,18 +1074,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -975,18 +1122,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -1007,18 +1161,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1048,18 +1209,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1089,18 +1257,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -1121,18 +1296,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1162,18 +1344,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1209,18 +1398,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1250,18 +1446,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -1282,18 +1485,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1323,18 +1533,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1364,18 +1581,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1405,18 +1629,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -1437,18 +1668,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1478,18 +1716,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1519,18 +1764,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1560,18 +1812,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1601,18 +1860,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -1633,18 +1899,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1674,18 +1947,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1715,18 +1995,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -1747,18 +2034,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1788,18 +2082,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1829,18 +2130,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1870,18 +2178,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -1902,18 +2217,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1943,18 +2265,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1984,18 +2313,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2025,18 +2361,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2066,18 +2409,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -2099,18 +2449,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -2132,18 +2489,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -2165,18 +2529,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2207,18 +2578,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2249,18 +2627,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -2282,18 +2667,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2324,18 +2716,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2366,18 +2765,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2408,18 +2814,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -2441,18 +2854,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -2474,18 +2894,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -2507,18 +2934,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2549,18 +2983,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2591,18 +3032,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -2624,18 +3072,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2666,18 +3121,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2708,18 +3170,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2750,18 +3219,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -2783,18 +3259,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2825,18 +3308,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2867,18 +3357,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2909,18 +3406,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2951,18 +3455,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -2984,18 +3495,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3026,18 +3544,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3068,18 +3593,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -3101,18 +3633,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3143,18 +3682,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3185,18 +3731,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3227,18 +3780,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -3260,18 +3820,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3302,18 +3869,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3344,18 +3918,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3386,18 +3967,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3454,18 +4042,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -3486,18 +4081,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -3518,18 +4120,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -3550,18 +4159,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3591,18 +4207,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -3623,18 +4246,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3664,18 +4294,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -3696,18 +4333,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3737,18 +4381,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3778,18 +4429,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -3810,18 +4468,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -3842,18 +4507,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -3874,18 +4546,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3915,18 +4594,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -3947,18 +4633,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -3988,18 +4681,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -4020,18 +4720,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4061,18 +4768,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4102,18 +4816,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -4134,18 +4855,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4175,18 +4903,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4216,18 +4951,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -4248,18 +4990,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4289,18 +5038,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4330,18 +5086,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4371,18 +5134,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -4403,18 +5173,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4444,18 +5221,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4485,18 +5269,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -4517,18 +5308,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4558,18 +5356,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4599,18 +5404,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4640,18 +5452,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -4672,18 +5491,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4713,18 +5539,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4754,18 +5587,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4795,18 +5635,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4836,18 +5683,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -4869,18 +5723,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -4902,18 +5763,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -4944,18 +5812,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -4977,18 +5852,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5019,18 +5901,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5061,18 +5950,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -5094,18 +5990,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -5127,18 +6030,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5169,18 +6079,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -5202,18 +6119,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5244,18 +6168,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5286,18 +6217,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -5319,18 +6257,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5361,18 +6306,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5403,18 +6355,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5445,18 +6404,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -5478,18 +6444,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5520,18 +6493,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5562,18 +6542,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -5595,18 +6582,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5637,18 +6631,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5679,18 +6680,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5721,18 +6729,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -5754,18 +6769,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5796,18 +6818,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5838,18 +6867,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5880,18 +6916,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -5953,18 +6996,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.shr_s @@ -5991,18 +7041,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -6023,18 +7080,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.load8_u @@ -6055,18 +7119,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -6087,18 +7158,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -6119,18 +7197,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6166,18 +7251,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6207,18 +7299,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -6239,18 +7338,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6280,18 +7386,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6321,18 +7434,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -6353,18 +7473,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6394,18 +7521,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6435,18 +7569,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6476,18 +7617,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.shr_s @@ -6514,18 +7662,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -6546,18 +7701,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.load8_u @@ -6578,18 +7740,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -6610,18 +7779,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -6642,18 +7818,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6689,18 +7872,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6730,18 +7920,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -6762,18 +7959,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6803,18 +8007,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6844,18 +8055,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -6876,18 +8094,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6917,18 +8142,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -6964,18 +8196,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7005,18 +8244,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -7037,18 +8283,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7078,18 +8331,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7119,18 +8379,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7160,18 +8427,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -7192,18 +8466,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7233,18 +8514,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7274,18 +8562,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7315,18 +8610,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7356,18 +8658,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -7388,18 +8697,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7429,18 +8745,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7470,18 +8793,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -7502,18 +8832,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7543,18 +8880,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7584,18 +8928,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7625,18 +8976,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.load align=1 @@ -7657,18 +9015,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7698,18 +9063,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7739,18 +9111,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7780,18 +9159,25 @@ (local.get $2) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $2) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $2) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7821,18 +9207,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.atomic.store8 @@ -7854,18 +9247,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -7887,18 +9287,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -7920,18 +9327,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -7962,18 +9376,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8004,18 +9425,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -8037,18 +9465,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8079,18 +9514,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8121,18 +9563,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8163,18 +9612,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.atomic.store8 @@ -8196,18 +9652,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 1) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -8229,18 +9692,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -8262,18 +9732,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8304,18 +9781,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 2) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8346,18 +9830,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -8379,18 +9870,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8421,18 +9919,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8463,18 +9968,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8505,18 +10017,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -8538,18 +10057,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8580,18 +10106,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8622,18 +10155,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8664,18 +10204,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8706,18 +10253,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -8739,18 +10293,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8781,18 +10342,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 4) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8823,18 +10391,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -8856,18 +10431,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8898,18 +10480,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8940,18 +10529,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 8) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -8982,18 +10578,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (v128.store align=1 @@ -9015,18 +10618,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9057,18 +10667,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9099,18 +10716,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -9141,18 +10765,25 @@ (local.get $3) (i32.const 1024) ) - (i32.gt_u - (i32.add - (local.get $3) - (i32.const 16) + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 16) + ) + (i32.load + (call $foo) + ) ) - (i32.load - (call $foo) + (i32.lt_u + (local.get $3) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if diff --git a/test/passes/safe-heap_start-function.txt b/test/passes/safe-heap_start-function.txt index 11b258945a4..a2445b18da3 100644 --- a/test/passes/safe-heap_start-function.txt +++ b/test/passes/safe-heap_start-function.txt @@ -64,18 +64,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_s @@ -96,18 +103,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load8_u @@ -128,18 +142,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_s align=1 @@ -160,18 +181,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -201,18 +229,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load16_u align=1 @@ -233,18 +268,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -274,18 +316,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.load align=1 @@ -306,18 +355,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -347,18 +403,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -388,18 +451,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_s @@ -420,18 +490,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load8_u @@ -452,18 +529,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_s align=1 @@ -484,18 +568,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -525,18 +616,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load16_u align=1 @@ -557,18 +655,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -598,18 +703,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_s align=1 @@ -630,18 +742,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -671,18 +790,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -712,18 +838,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load32_u align=1 @@ -744,18 +877,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -785,18 +925,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -826,18 +973,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.load align=1 @@ -858,18 +1012,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -899,18 +1060,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -940,18 +1108,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -981,18 +1156,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.load align=1 @@ -1013,18 +1195,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1054,18 +1243,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1095,18 +1291,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.load align=1 @@ -1127,18 +1330,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1168,18 +1378,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1209,18 +1426,25 @@ (local.get $2) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $2) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $2) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1250,18 +1474,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store8 @@ -1283,18 +1514,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store16 align=1 @@ -1316,18 +1554,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1358,18 +1603,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i32.store align=1 @@ -1391,18 +1643,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1433,18 +1692,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1475,18 +1741,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 1) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 1) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store8 @@ -1508,18 +1781,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store16 align=1 @@ -1541,18 +1821,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 2) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 2) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1583,18 +1870,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store32 align=1 @@ -1616,18 +1910,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1658,18 +1959,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1700,18 +2008,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (i64.store align=1 @@ -1733,18 +2048,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1775,18 +2097,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1817,18 +2146,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1859,18 +2195,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f32.store align=1 @@ -1892,18 +2235,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1934,18 +2284,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 4) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 4) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -1976,18 +2333,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (f64.store align=1 @@ -2009,18 +2373,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2051,18 +2422,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if @@ -2093,18 +2471,25 @@ (local.get $3) (i32.const 0) ) - (i32.gt_u - (i32.add + (i32.or + (i32.gt_u + (i32.add + (local.get $3) + (i32.const 8) + ) + (i32.load + (call $emscripten_get_sbrk_ptr) + ) + ) + (i32.lt_u (local.get $3) - (i32.const 8) - ) - (i32.load - (call $emscripten_get_sbrk_ptr) + (local.get $0) ) ) ) (then (call $segfault) + (unreachable) ) ) (if From eda6530a187add28f06d9ab84d78b21b5001a6df Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 12 Jul 2024 16:48:06 -0400 Subject: [PATCH 439/553] [threads] ref.i31_shared (#6735) Implement `ref.i31_shared` the new instruction for creating references to shared i31s. Implement binary and text parsing and emitting as well as interpretation. Copy the upstream spec test for i31 and modify it so that all the heap types are shared. Comment out some parts that we do not yet support. --- scripts/fuzz_opt.py | 1 + scripts/gen-s-parser.py | 5 +- scripts/test/binaryenjs.py | 2 +- src/gen-s-parser.inc | 23 +++- src/ir/properties.h | 3 +- src/literal.h | 6 +- src/parser/contexts.h | 11 +- src/parser/parsers.h | 11 +- src/parser/wast-parser.cpp | 7 + src/passes/Print.cpp | 6 +- src/wasm-binary.h | 1 + src/wasm-builder.h | 3 +- src/wasm-interpreter.h | 3 +- src/wasm-ir-builder.h | 2 +- src/wasm/literal.cpp | 3 +- src/wasm/wasm-binary.cpp | 18 ++- src/wasm/wasm-ir-builder.cpp | 4 +- src/wasm/wasm-stack.cpp | 4 +- src/wasm/wasm.cpp | 3 +- test/binaryen.js/expressions.js | 3 - test/lit/basic/shared-i31.wast | 37 +++++ test/spec/shared-i31.wast | 230 ++++++++++++++++++++++++++++++++ 22 files changed, 348 insertions(+), 38 deletions(-) create mode 100644 test/lit/basic/shared-i31.wast create mode 100644 test/spec/shared-i31.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 2707df4c01d..ada930127c7 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -356,6 +356,7 @@ def is_git_repo(): 'shared-polymorphism.wast', 'shared-struct.wast', 'shared-array.wast', + 'shared-i31.wast', ] diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 43a85c636ed..711096a5b18 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -572,8 +572,9 @@ ("resume", "makeResume()"), ("suspend", "makeSuspend()"), # GC - ("i31.new", "makeRefI31()"), # deprecated - ("ref.i31", "makeRefI31()"), + ("i31.new", "makeRefI31(Unshared)"), # deprecated + ("ref.i31", "makeRefI31(Unshared)"), + ("ref.i31_shared", "makeRefI31(Shared)"), ("i31.get_s", "makeI31Get(true)"), ("i31.get_u", "makeI31Get(false)"), ("ref.test", "makeRefTest()"), diff --git a/scripts/test/binaryenjs.py b/scripts/test/binaryenjs.py index d546ced1336..93fbe532f88 100644 --- a/scripts/test/binaryenjs.py +++ b/scripts/test/binaryenjs.py @@ -60,7 +60,7 @@ def test(cmd): test([shared.MOZJS, '-m', 'a.mjs']) if shared.NODEJS: if node_has_wasm or 'WebAssembly.' not in test_src: - test([shared.NODEJS, '--experimental-wasm-eh', 'a.mjs']) + test([shared.NODEJS, 'a.mjs']) else: print('Skipping ' + test_path + ' because WebAssembly might not be supported') diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 8a3dcba0be2..bbed0f8be88 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -1831,7 +1831,7 @@ switch (buf[0]) { } case 'n': if (op == "i31.new"sv) { - CHECK_ERR(makeRefI31(ctx, pos, annotations)); + CHECK_ERR(makeRefI31(ctx, pos, annotations, Unshared)); return Ok{}; } goto parse_error; @@ -4505,12 +4505,23 @@ switch (buf[0]) { goto parse_error; case 'i': { switch (buf[5]) { - case '3': - if (op == "ref.i31"sv) { - CHECK_ERR(makeRefI31(ctx, pos, annotations)); - return Ok{}; + case '3': { + switch (buf[7]) { + case '\0': + if (op == "ref.i31"sv) { + CHECK_ERR(makeRefI31(ctx, pos, annotations, Unshared)); + return Ok{}; + } + goto parse_error; + case '_': + if (op == "ref.i31_shared"sv) { + CHECK_ERR(makeRefI31(ctx, pos, annotations, Shared)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 's': if (op == "ref.is_null"sv) { CHECK_ERR(makeRefIsNull(ctx, pos, annotations)); diff --git a/src/ir/properties.h b/src/ir/properties.h index ccb2392b0c1..09486ee34ca 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -119,7 +119,8 @@ inline Literal getLiteral(const Expression* curr) { return Literal(r->func, r->type.getHeapType()); } else if (auto* i = curr->dynCast()) { if (auto* c = i->value->dynCast()) { - return Literal::makeI31(c->value.geti32()); + return Literal::makeI31(c->value.geti32(), + i->type.getHeapType().getShared()); } } else if (auto* s = curr->dynCast()) { return Literal(s->string.toString()); diff --git a/src/literal.h b/src/literal.h index 1268448fb82..45f76f247d8 100644 --- a/src/literal.h +++ b/src/literal.h @@ -243,8 +243,8 @@ class Literal { static Literal makeFunc(Name func, HeapType type) { return Literal(func, type); } - static Literal makeI31(int32_t value) { - auto lit = Literal(Type(HeapType::i31, NonNullable)); + static Literal makeI31(int32_t value, Shareability share) { + auto lit = Literal(Type(HeapTypes::i31.getBasic(share), NonNullable)); lit.i32 = value | 0x80000000; return lit; } @@ -281,7 +281,7 @@ class Literal { return i32; } int32_t geti31(bool signed_ = true) const { - assert(type.getHeapType() == HeapType::i31); + assert(type.getHeapType().getBasic(Unshared) == HeapType::i31); // Cast to unsigned for the left shift to avoid undefined behavior. return signed_ ? int32_t((uint32_t(i32) << 1)) >> 1 : (i32 & 0x7fffffff); } diff --git a/src/parser/contexts.h b/src/parser/contexts.h index f58275d7115..96a70663d15 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -695,7 +695,10 @@ struct NullInstrParserCtx { Result<> makeCallRef(Index, const std::vector&, HeapTypeT, bool) { return Ok{}; } - Result<> makeRefI31(Index, const std::vector&) { return Ok{}; } + Result<> + makeRefI31(Index, const std::vector&, Shareability share) { + return Ok{}; + } Result<> makeI31Get(Index, const std::vector&, bool) { return Ok{}; } @@ -2363,8 +2366,10 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeCallRef(type, isReturn)); } - Result<> makeRefI31(Index pos, const std::vector& annotations) { - return withLoc(pos, irBuilder.makeRefI31()); + Result<> makeRefI31(Index pos, + const std::vector& annotations, + Shareability share) { + return withLoc(pos, irBuilder.makeRefI31(share)); } Result<> makeI31Get(Index pos, diff --git a/src/parser/parsers.h b/src/parser/parsers.h index db450e3c6a3..2c3916fa38a 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -221,7 +221,8 @@ template Result<> makeCallRef(Ctx&, Index, const std::vector&, bool isReturn); template -Result<> makeRefI31(Ctx&, Index, const std::vector&); +Result<> +makeRefI31(Ctx&, Index, const std::vector&, Shareability share); template Result<> makeI31Get(Ctx&, Index, const std::vector&, bool signed_); template @@ -2127,9 +2128,11 @@ Result<> makeCallRef(Ctx& ctx, } template -Result<> -makeRefI31(Ctx& ctx, Index pos, const std::vector& annotations) { - return ctx.makeRefI31(pos, annotations); +Result<> makeRefI31(Ctx& ctx, + Index pos, + const std::vector& annotations, + Shareability share) { + return ctx.makeRefI31(pos, annotations, share); } template diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 137ef0df13a..a3a6c14ce85 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -207,6 +207,13 @@ Result result(Lexer& in) { return RefResult{HeapType::func}; } + if (in.takeSExprStart("ref.i31_shared")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.i31_shared"); + } + return RefResult{HeapTypes::i31.getBasic(Shared)}; + } + return in.err("unrecognized result"); } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 2e980077523..ede49ab3801 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2076,7 +2076,11 @@ struct PrintExpressionContents o << std::max(curr->tuple->type.size(), size_t(2)) << " "; o << curr->index; } - void visitRefI31(RefI31* curr) { printMedium(o, "ref.i31"); } + void visitRefI31(RefI31* curr) { + bool shared = + curr->type != Type::unreachable && curr->type.getHeapType().isShared(); + printMedium(o, shared ? "ref.i31_shared" : "ref.i31"); + } void visitI31Get(I31Get* curr) { printMedium(o, curr->signed_ ? "i31.get_s" : "i31.get_u"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 0b9615c7e0c..3e45b496925 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1125,6 +1125,7 @@ enum ASTNodes { RefI31 = 0x1c, I31GetS = 0x1d, I31GetU = 0x1e, + RefI31Shared = 0x1f, // stringref opcodes diff --git a/src/wasm-builder.h b/src/wasm-builder.h index a20ba46a6d8..1e768b11ccf 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -873,9 +873,10 @@ class Builder { ret->finalize(); return ret; } - RefI31* makeRefI31(Expression* value) { + RefI31* makeRefI31(Expression* value, Shareability share = Unshared) { auto* ret = wasm.allocator.alloc(); ret->value = value; + ret->type = Type(HeapTypes::i31.getBasic(share), NonNullable); ret->finalize(); return ret; } diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 93739d1c97d..9bdf0e72c1a 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1426,7 +1426,8 @@ class ExpressionRunner : public OverriddenVisitor { } const auto& value = flow.getSingleValue(); NOTE_EVAL1(value); - return Literal::makeI31(value.geti32()); + return Literal::makeI31(value.geti32(), + curr->type.getHeapType().getShared()); } Flow visitI31Get(I31Get* curr) { NOTE_ENTER("I31Get"); diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 16c3b757036..eff8c85ad8d 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -181,7 +181,7 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeTupleMake(uint32_t arity); [[nodiscard]] Result<> makeTupleExtract(uint32_t arity, uint32_t index); [[nodiscard]] Result<> makeTupleDrop(uint32_t arity); - [[nodiscard]] Result<> makeRefI31(); + [[nodiscard]] Result<> makeRefI31(Shareability share); [[nodiscard]] Result<> makeI31Get(bool signed_); [[nodiscard]] Result<> makeCallRef(HeapType type, bool isReturn); [[nodiscard]] Result<> makeRefTest(Type type); diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index f13ea504fb3..20b6b7234c5 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -57,7 +57,8 @@ Literal::Literal(Type type) : type(type) { return; } - if (type.isRef() && type.getHeapType() == HeapType::i31) { + if (type.isRef() && type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31) { assert(type.isNonNullable()); i32 = 0; return; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 78470324cf4..74d74f473f7 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7244,13 +7244,19 @@ void WasmBinaryReader::visitCallRef(CallRef* curr) { } bool WasmBinaryReader::maybeVisitRefI31(Expression*& out, uint32_t code) { - if (code != BinaryConsts::RefI31) { - return false; + Shareability share; + switch (code) { + case BinaryConsts::RefI31: + share = Unshared; + break; + case BinaryConsts::RefI31Shared: + share = Shared; + break; + default: + return false; } - auto* curr = allocator.alloc(); - curr->value = popNonVoidExpression(); - curr->finalize(); - out = curr; + auto* value = popNonVoidExpression(); + out = Builder(wasm).makeRefI31(value, share); return true; } diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 63f5df4c046..3db6238c4e1 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1605,10 +1605,10 @@ Result<> IRBuilder::makeTupleDrop(uint32_t arity) { return Ok{}; } -Result<> IRBuilder::makeRefI31() { +Result<> IRBuilder::makeRefI31(Shareability share) { RefI31 curr; CHECK_ERR(visitRefI31(&curr)); - push(builder.makeRefI31(curr.value)); + push(builder.makeRefI31(curr.value, share)); return Ok{}; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 40a50706a34..cd0a9928e1a 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2114,7 +2114,9 @@ void BinaryInstWriter::visitTupleExtract(TupleExtract* curr) { } void BinaryInstWriter::visitRefI31(RefI31* curr) { - o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefI31); + o << int8_t(BinaryConsts::GCPrefix) + << U32LEB(curr->type.getHeapType().isShared() ? BinaryConsts::RefI31Shared + : BinaryConsts::RefI31); } void BinaryInstWriter::visitI31Get(I31Get* curr) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 8a2b4755ceb..c4f02128e6c 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -964,7 +964,8 @@ void RefI31::finalize() { if (value->type == Type::unreachable) { type = Type::unreachable; } else { - type = Type(HeapType::i31, NonNullable); + assert(type.isRef() && type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31); } } diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index bd8ec67931f..c05e820a745 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -1777,9 +1777,6 @@ console.log("# RefI31"); theRefI31.value = value = module.local.get(2, binaryen.i32); assert(theRefI31.value === value); - theRefI31.type = binaryen.f64; - theRefI31.finalize(); - // assert(theRefI31.type === binaryen.?); // TODO: (ref i31) console.log(theRefI31.toText()); assert( diff --git a/test/lit/basic/shared-i31.wast b/test/lit/basic/shared-i31.wast new file mode 100644 index 00000000000..b448bcad326 --- /dev/null +++ b/test/lit/basic/shared-i31.wast @@ -0,0 +1,37 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func (param (ref null (shared i31))) (result i32))) + + ;; CHECK: (type $1 (func (param i32) (result (ref (shared i31))))) + + ;; CHECK: (func $make (type $1) (param $0 i32) (result (ref (shared i31))) + ;; CHECK-NEXT: (ref.i31_shared + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $make (param i32) (result (ref (shared i31))) + (ref.i31_shared (local.get 0)) + ) + + ;; CHECK: (func $get_s (type $0) (param $0 (ref null (shared i31))) (result i32) + ;; CHECK-NEXT: (i31.get_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get_s (param (ref null (shared i31))) (result i32) + (i31.get_s (local.get 0)) + ) + + ;; CHECK: (func $get_u (type $0) (param $0 (ref null (shared i31))) (result i32) + ;; CHECK-NEXT: (i31.get_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $get_u (param (ref null (shared i31))) (result i32) + (i31.get_u (local.get 0)) + ) +) diff --git a/test/spec/shared-i31.wast b/test/spec/shared-i31.wast new file mode 100644 index 00000000000..ef1e2a9f1ca --- /dev/null +++ b/test/spec/shared-i31.wast @@ -0,0 +1,230 @@ +(module + (func (export "new") (param $i i32) (result (ref (shared i31))) + (ref.i31_shared (local.get $i)) + ) + + (func (export "get_u") (param $i i32) (result i32) + (i31.get_u (ref.i31_shared (local.get $i))) + ) + (func (export "get_s") (param $i i32) (result i32) + (i31.get_s (ref.i31_shared (local.get $i))) + ) + + (func (export "get_u-null") (result i32) + (i31.get_u (ref.null (shared i31))) + ) + (func (export "get_s-null") (result i32) + (i31.get_u (ref.null (shared i31))) + ) + + (global $i (ref (shared i31)) (ref.i31_shared (i32.const 2))) + (global $m (mut (ref (shared i31))) (ref.i31_shared (i32.const 3))) + + (func (export "get_globals") (result i32 i32) + (i31.get_u (global.get $i)) + (i31.get_u (global.get $m)) + ) + + (func (export "set_global") (param i32) + (global.set $m (ref.i31_shared (local.get 0))) + ) +) + +(assert_return (invoke "new" (i32.const 1)) (ref.i31_shared)) + +(assert_return (invoke "get_u" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "get_u" (i32.const 100)) (i32.const 100)) +(assert_return (invoke "get_u" (i32.const -1)) (i32.const 0x7fff_ffff)) +(assert_return (invoke "get_u" (i32.const 0x3fff_ffff)) (i32.const 0x3fff_ffff)) +(assert_return (invoke "get_u" (i32.const 0x4000_0000)) (i32.const 0x4000_0000)) +(assert_return (invoke "get_u" (i32.const 0x7fff_ffff)) (i32.const 0x7fff_ffff)) +(assert_return (invoke "get_u" (i32.const 0xaaaa_aaaa)) (i32.const 0x2aaa_aaaa)) +(assert_return (invoke "get_u" (i32.const 0xcaaa_aaaa)) (i32.const 0x4aaa_aaaa)) + +(assert_return (invoke "get_s" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "get_s" (i32.const 100)) (i32.const 100)) +(assert_return (invoke "get_s" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "get_s" (i32.const 0x3fff_ffff)) (i32.const 0x3fff_ffff)) +(assert_return (invoke "get_s" (i32.const 0x4000_0000)) (i32.const -0x4000_0000)) +(assert_return (invoke "get_s" (i32.const 0x7fff_ffff)) (i32.const -1)) +(assert_return (invoke "get_s" (i32.const 0xaaaa_aaaa)) (i32.const 0x2aaa_aaaa)) +(assert_return (invoke "get_s" (i32.const 0xcaaa_aaaa)) (i32.const 0xcaaa_aaaa)) + +(assert_trap (invoke "get_u-null") "null i31 reference") +(assert_trap (invoke "get_s-null") "null i31 reference") + +(assert_return (invoke "get_globals") (i32.const 2) (i32.const 3)) + +(invoke "set_global" (i32.const 1234)) +(assert_return (invoke "get_globals") (i32.const 2) (i32.const 1234)) + +(module $tables_of_i31ref + (table $table 3 10 (ref null (shared i31))) + (elem (table $table) (i32.const 0) (ref null (shared i31)) + (item (ref.i31_shared (i32.const 999))) + (item (ref.i31_shared (i32.const 888))) + (item (ref.i31_shared (i32.const 777)))) + + (func (export "size") (result i32) + table.size $table + ) + + (func (export "get") (param i32) (result i32) + (i31.get_u (table.get $table (local.get 0))) + ) + + (func (export "grow") (param i32 i32) (result i32) + (table.grow $table (ref.i31_shared (local.get 1)) (local.get 0)) + ) + + (func (export "fill") (param i32 i32 i32) + (table.fill $table (local.get 0) (ref.i31_shared (local.get 1)) (local.get 2)) + ) + + (func (export "copy") (param i32 i32 i32) + (table.copy $table $table (local.get 0) (local.get 1) (local.get 2)) + ) + + (elem $elem (ref null (shared i31)) (item (ref.i31_shared (i32.const 123))) + (item (ref.i31_shared (i32.const 456))) + (item (ref.i31_shared (i32.const 789)))) + ;; (func (export "init") (param i32 i32 i32) + ;; (table.init $table $elem (local.get 0) (local.get 1) (local.get 2)) + ;; ) +) + +;; Initial state. +(assert_return (invoke "size") (i32.const 3)) +(assert_return (invoke "get" (i32.const 0)) (i32.const 999)) +(assert_return (invoke "get" (i32.const 1)) (i32.const 888)) +(assert_return (invoke "get" (i32.const 2)) (i32.const 777)) + +;; Grow from size 3 to size 5. +(assert_return (invoke "grow" (i32.const 2) (i32.const 333)) (i32.const 3)) +(assert_return (invoke "size") (i32.const 5)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 333)) +(assert_return (invoke "get" (i32.const 4)) (i32.const 333)) + +;; Fill table[2..4] = 111. +(invoke "fill" (i32.const 2) (i32.const 111) (i32.const 2)) +(assert_return (invoke "get" (i32.const 2)) (i32.const 111)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 111)) + +;; Copy from table[0..2] to table[3..5]. +(invoke "copy" (i32.const 3) (i32.const 0) (i32.const 2)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 999)) +(assert_return (invoke "get" (i32.const 4)) (i32.const 888)) + +;; ;; Initialize the passive element at table[1..4]. +;; (invoke "init" (i32.const 1) (i32.const 0) (i32.const 3)) +;; (assert_return (invoke "get" (i32.const 1)) (i32.const 123)) +;; (assert_return (invoke "get" (i32.const 2)) (i32.const 456)) +;; (assert_return (invoke "get" (i32.const 3)) (i32.const 789)) + +(module $env + (global (export "g") i32 (i32.const 42)) +) +(register "env") + +;; (module $i31ref_of_global_table_initializer +;; (global $g (import "env" "g") i32) +;; (table $t 3 3 (ref (shared i31)) (ref.i31_shared (global.get $g))) +;; (func (export "get") (param i32) (result i32) +;; (i31.get_u (local.get 0) (table.get $t)) +;; ) +;; ) + +;; (assert_return (invoke "get" (i32.const 0)) (i32.const 42)) +;; (assert_return (invoke "get" (i32.const 1)) (i32.const 42)) +;; (assert_return (invoke "get" (i32.const 2)) (i32.const 42)) + +(module $i31ref_of_global_global_initializer + (global $g0 (import "env" "g") i32) + (global $g1 (ref null (shared i31)) (ref.i31_shared (global.get $g0))) + (func (export "get") (result i32) + (i31.get_u (global.get $g1)) + ) +) + +(assert_return (invoke "get") (i32.const 42)) + +(module $anyref_global_of_i31ref + (global $c (ref null (shared any)) (ref.i31_shared (i32.const 1234))) + (global $m (mut (ref null (shared any))) (ref.i31_shared (i32.const 5678))) + + (func (export "get_globals") (result i32 i32) + (i31.get_u (ref.cast (ref null (shared i31)) (global.get $c))) + (i31.get_u (ref.cast (ref null (shared i31)) (global.get $m))) + ) + + (func (export "set_global") (param i32) + (global.set $m (ref.i31_shared (local.get 0))) + ) +) + +(assert_return (invoke "get_globals") (i32.const 1234) (i32.const 5678)) +(invoke "set_global" (i32.const 0)) +(assert_return (invoke "get_globals") (i32.const 1234) (i32.const 0)) + +(module $anyref_table_of_i31ref + (table $table 3 10 (ref null (shared any))) + (elem (table $table) (i32.const 0) (ref null (shared i31)) + (item (ref.i31_shared (i32.const 999))) + (item (ref.i31_shared (i32.const 888))) + (item (ref.i31_shared (i32.const 777)))) + + (func (export "size") (result i32) + table.size $table + ) + + (func (export "get") (param i32) (result i32) + (i31.get_u (ref.cast (ref null (shared i31)) (table.get $table (local.get 0)))) + ) + + (func (export "grow") (param i32 i32) (result i32) + (table.grow $table (ref.i31_shared (local.get 1)) (local.get 0)) + ) + + (func (export "fill") (param i32 i32 i32) + (table.fill $table (local.get 0) (ref.i31_shared (local.get 1)) (local.get 2)) + ) + + (func (export "copy") (param i32 i32 i32) + (table.copy $table $table (local.get 0) (local.get 1) (local.get 2)) + ) + + (elem $elem (ref null (shared i31)) (item (ref.i31_shared (i32.const 123))) + (item (ref.i31_shared (i32.const 456))) + (item (ref.i31_shared (i32.const 789)))) + ;; (func (export "init") (param i32 i32 i32) + ;; (table.init $table $elem (local.get 0) (local.get 1) (local.get 2)) + ;; ) +) + +;; Initial state. +(assert_return (invoke "size") (i32.const 3)) +(assert_return (invoke "get" (i32.const 0)) (i32.const 999)) +(assert_return (invoke "get" (i32.const 1)) (i32.const 888)) +(assert_return (invoke "get" (i32.const 2)) (i32.const 777)) + +;; Grow from size 3 to size 5. +(assert_return (invoke "grow" (i32.const 2) (i32.const 333)) (i32.const 3)) +(assert_return (invoke "size") (i32.const 5)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 333)) +(assert_return (invoke "get" (i32.const 4)) (i32.const 333)) + +;; Fill table[2..4] = 111. +(invoke "fill" (i32.const 2) (i32.const 111) (i32.const 2)) +(assert_return (invoke "get" (i32.const 2)) (i32.const 111)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 111)) + +;; Copy from table[0..2] to table[3..5]. +(invoke "copy" (i32.const 3) (i32.const 0) (i32.const 2)) +(assert_return (invoke "get" (i32.const 3)) (i32.const 999)) +(assert_return (invoke "get" (i32.const 4)) (i32.const 888)) + +;; ;; Initialize the passive element at table[1..4]. +;; (invoke "init" (i32.const 1) (i32.const 0) (i32.const 3)) +;; (assert_return (invoke "get" (i32.const 1)) (i32.const 123)) +;; (assert_return (invoke "get" (i32.const 2)) (i32.const 456)) +;; (assert_return (invoke "get" (i32.const 3)) (i32.const 789)) From 20c10df0cc5e5ffb9b8a0ca8cf4895d3416c6771 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 12 Jul 2024 17:39:43 -0400 Subject: [PATCH 440/553] Remove non-standard `i31.new` (#6736) The standard name for the instruction is `ref.i31`. Remove support for the non-standard name and update tests that were still using it. --- scripts/gen-s-parser.py | 1 - src/gen-s-parser.inc | 29 +++------- test/lit/i31-new.wast | 18 ------ .../passes/simplify-globals-single_use.wast | 22 ++++---- test/lit/passes/stack-ir-non-nullable.wast | 56 +++++++++---------- test/lit/passes/type-generalizing.wast | 10 ++-- 6 files changed, 53 insertions(+), 83 deletions(-) delete mode 100644 test/lit/i31-new.wast diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 711096a5b18..e1bfe3f3d9b 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -572,7 +572,6 @@ ("resume", "makeResume()"), ("suspend", "makeSuspend()"), # GC - ("i31.new", "makeRefI31(Unshared)"), # deprecated ("ref.i31", "makeRefI31(Unshared)"), ("ref.i31_shared", "makeRefI31(Shared)"), ("i31.get_s", "makeI31Get(true)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index bbed0f8be88..98f5b7831ea 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -1811,27 +1811,16 @@ switch (buf[0]) { case '3': { switch (buf[2]) { case '1': { - switch (buf[4]) { - case 'g': { - switch (buf[8]) { - case 's': - if (op == "i31.get_s"sv) { - CHECK_ERR(makeI31Get(ctx, pos, annotations, true)); - return Ok{}; - } - goto parse_error; - case 'u': - if (op == "i31.get_u"sv) { - CHECK_ERR(makeI31Get(ctx, pos, annotations, false)); - return Ok{}; - } - goto parse_error; - default: goto parse_error; + switch (buf[8]) { + case 's': + if (op == "i31.get_s"sv) { + CHECK_ERR(makeI31Get(ctx, pos, annotations, true)); + return Ok{}; } - } - case 'n': - if (op == "i31.new"sv) { - CHECK_ERR(makeRefI31(ctx, pos, annotations, Unshared)); + goto parse_error; + case 'u': + if (op == "i31.get_u"sv) { + CHECK_ERR(makeI31Get(ctx, pos, annotations, false)); return Ok{}; } goto parse_error; diff --git a/test/lit/i31-new.wast b/test/lit/i31-new.wast deleted file mode 100644 index 9d47b3ec9be..00000000000 --- a/test/lit/i31-new.wast +++ /dev/null @@ -1,18 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; Check that we still parse the legacy i31.new instruction. - -;; RUN: wasm-opt %s -all -S -o - | filecheck %s - -(module - ;; CHECK: (func $test (type $0) (result i31ref) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $test (result i31ref) - (i31.new - (i32.const 0) - ) - ) -) diff --git a/test/lit/passes/simplify-globals-single_use.wast b/test/lit/passes/simplify-globals-single_use.wast index daba2588d0b..768ac6f8683 100644 --- a/test/lit/passes/simplify-globals-single_use.wast +++ b/test/lit/passes/simplify-globals-single_use.wast @@ -17,7 +17,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -59,7 +59,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -85,7 +85,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -131,7 +131,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -160,7 +160,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -188,7 +188,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use1 anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) )) @@ -199,7 +199,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use2 anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 1337) ) )) @@ -217,7 +217,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) (global $single-use3 anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 99999) ) )) @@ -250,7 +250,7 @@ ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: )) (global $single-use1 anyref (struct.new $A - (i31.new + (ref.i31 (i32.const 42) ) (ref.null any) @@ -264,7 +264,7 @@ ;; CHECK-NEXT: )) (global $single-use2 anyref (struct.new $A (ref.null any) - (i31.new + (ref.i31 (i32.const 1337) ) )) @@ -297,7 +297,7 @@ ;; CHECK: (global $single-use1 anyref (ref.i31 ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: )) - (global $single-use1 anyref (i31.new + (global $single-use1 anyref (ref.i31 (i32.const 42) )) diff --git a/test/lit/passes/stack-ir-non-nullable.wast b/test/lit/passes/stack-ir-non-nullable.wast index c3309d65a74..508fe574f6c 100644 --- a/test/lit/passes/stack-ir-non-nullable.wast +++ b/test/lit/passes/stack-ir-non-nullable.wast @@ -37,20 +37,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -86,20 +86,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -135,20 +135,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -191,20 +191,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -245,20 +245,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -296,20 +296,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -345,20 +345,20 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) (then (local.set $temp - (i31.new + (ref.i31 (i32.const 1) ) ) ) (else (local.set $temp - (i31.new + (ref.i31 (i32.const 2) ) ) @@ -410,7 +410,7 @@ (tuple.extract 2 1 (local.get $temp) ) - (i31.new + (ref.i31 (i32.const 1) ) ) @@ -418,7 +418,7 @@ (local.set $temp (tuple.make 2 (i32.const 2) - (i31.new + (ref.i31 (i32.const 3) ) ) @@ -428,7 +428,7 @@ (local.set $temp (tuple.make 2 (i32.const 4) - (i31.new + (ref.i31 (i32.const 5) ) ) @@ -482,7 +482,7 @@ (tuple.extract 2 1 (local.get $temp) ) - (i31.new + (ref.i31 (i32.const 1) ) ) @@ -490,7 +490,7 @@ (local.set $temp (tuple.make 2 (i32.const 2) - (i31.new + (ref.i31 (i32.const 3) ) ) @@ -500,7 +500,7 @@ (local.set $temp (tuple.make 2 (i32.const 4) - (i31.new + (ref.i31 (i32.const 5) ) ) @@ -1015,7 +1015,7 @@ (if (ref.eq (local.get $temp) - (i31.new + (ref.i31 (i32.const 0) ) ) diff --git a/test/lit/passes/type-generalizing.wast b/test/lit/passes/type-generalizing.wast index 344509794c2..e9c92ff864f 100644 --- a/test/lit/passes/type-generalizing.wast +++ b/test/lit/passes/type-generalizing.wast @@ -270,7 +270,7 @@ (local $var i31ref) ;; Require that (ref i31) <: typeof($var). (local.set $var - (i31.new + (ref.i31 (i32.const 0) ) ) @@ -405,7 +405,7 @@ (drop (local.tee $dest (local.tee $var - (i31.new + (ref.i31 (i32.const 0) ) ) @@ -439,7 +439,7 @@ (local $nonnullable (ref i31)) ;; Initialize the non-nullable local for validation purposes. (local.set $nonnullable - (i31.new + (ref.i31 (i32.const 0) ) ) @@ -819,7 +819,7 @@ (func $extern-convert-any-nullable (result externref) (local $var (ref i31)) (local.set $var - (i31.new + (ref.i31 (i32.const 0) ) ) @@ -843,7 +843,7 @@ (func $extern-convert-any-non-nullable (result (ref extern)) (local $var (ref i31)) (local.set $var - (i31.new + (ref.i31 (i32.const 0) ) ) From d2a48afe09dd5b22079c748a97ebaebaf69a19a7 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 12 Jul 2024 16:15:53 -0700 Subject: [PATCH 441/553] Monomorphize dropped functions (#6734) We now consider a drop to be part of the call context: If we see (drop (call $foo) ) (func $foo (result i32) (i32.const 42) ) Then we'd monomorphize to this: (call $foo_1) ;; call the specialized function instead (func $foo_1 ;; the specialized function returns nothing (drop ;; the drop was moved into here (i32.const 42) ) ) With the drop now in the called function, we may be able to optimize out unused work. Refactor a bit of code out of DAE that we can reuse here, into a new return-utils.h. --- src/ir/CMakeLists.txt | 1 + src/ir/return-utils.cpp | 99 ++ src/ir/return-utils.h | 39 + src/passes/DeadArgumentElimination.cpp | 19 +- src/passes/Monomorphize.cpp | 105 ++- test/lit/passes/monomorphize-drop.wast | 1191 ++++++++++++++++++++++++ 6 files changed, 1418 insertions(+), 36 deletions(-) create mode 100644 src/ir/return-utils.cpp create mode 100644 src/ir/return-utils.h create mode 100644 test/lit/passes/monomorphize-drop.wast diff --git a/src/ir/CMakeLists.txt b/src/ir/CMakeLists.txt index 996daa56416..45b08702de8 100644 --- a/src/ir/CMakeLists.txt +++ b/src/ir/CMakeLists.txt @@ -17,6 +17,7 @@ set(ir_SOURCES LocalGraph.cpp LocalStructuralDominance.cpp ReFinalize.cpp + return-utils.cpp stack-utils.cpp table-utils.cpp type-updating.cpp diff --git a/src/ir/return-utils.cpp b/src/ir/return-utils.cpp new file mode 100644 index 00000000000..20b3a194b13 --- /dev/null +++ b/src/ir/return-utils.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2024 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 "ir/return-utils.h" +#include "ir/module-utils.h" +#include "wasm-builder.h" +#include "wasm-traversal.h" +#include "wasm.h" + +namespace wasm::ReturnUtils { + +namespace { + +struct ReturnValueRemover : public PostWalker { + void visitReturn(Return* curr) { + auto* value = curr->value; + assert(value); + curr->value = nullptr; + Builder builder(*getModule()); + replaceCurrent(builder.makeSequence(builder.makeDrop(value), curr)); + } + + void visitCall(Call* curr) { handleReturnCall(curr); } + void visitCallIndirect(CallIndirect* curr) { handleReturnCall(curr); } + void visitCallRef(CallRef* curr) { handleReturnCall(curr); } + + template void handleReturnCall(T* curr) { + if (curr->isReturn) { + Fatal() << "Cannot remove return_calls in ReturnValueRemover"; + } + } + + void visitFunction(Function* curr) { + if (curr->body->type.isConcrete()) { + curr->body = Builder(*getModule()).makeDrop(curr->body); + } + } +}; + +} // anonymous namespace + +void removeReturns(Function* func, Module& wasm) { + ReturnValueRemover().walkFunctionInModule(func, &wasm); +} + +std::unordered_map findReturnCallers(Module& wasm) { + ModuleUtils::ParallelFunctionAnalysis analysis( + wasm, [&](Function* func, bool& hasReturnCall) { + if (func->imported()) { + return; + } + + struct Finder : PostWalker { + bool hasReturnCall = false; + + void visitCall(Call* curr) { + if (curr->isReturn) { + hasReturnCall = true; + } + } + void visitCallIndirect(CallIndirect* curr) { + if (curr->isReturn) { + hasReturnCall = true; + } + } + void visitCallRef(CallRef* curr) { + if (curr->isReturn) { + hasReturnCall = true; + } + } + } finder; + + finder.walk(func->body); + hasReturnCall = finder.hasReturnCall; + }); + + // Convert to an unordered map for fast lookups. TODO: Avoid a copy here. + std::unordered_map ret; + ret.reserve(analysis.map.size()); + for (auto& [k, v] : analysis.map) { + ret[k] = v; + } + return ret; +} + +} // namespace wasm::ReturnUtils diff --git a/src/ir/return-utils.h b/src/ir/return-utils.h new file mode 100644 index 00000000000..a5214ba017c --- /dev/null +++ b/src/ir/return-utils.h @@ -0,0 +1,39 @@ +/* + * Copyright 2024 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. + */ + +#ifndef wasm_ir_return_h +#define wasm_ir_return_h + +#include "wasm.h" + +namespace wasm::ReturnUtils { + +// Removes values from both explicit returns and implicit ones (values that flow +// from the body). This is useful after changing a function's type to no longer +// return anything. +// +// This does *not* handle return calls, and will error on them. Removing a +// return call may change the semantics of the program, so we do not do it +// automatically here. +void removeReturns(Function* func, Module& wasm); + +// Return a map of every function to whether it does a return call. +using ReturnCallersMap = std::unordered_map; +ReturnCallersMap findReturnCallers(Module& wasm); + +} // namespace wasm::ReturnUtils + +#endif // wasm_ir_return_h diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index 4a341571e4c..83cd7e86d07 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -42,6 +42,7 @@ #include "ir/find_all.h" #include "ir/lubs.h" #include "ir/module-utils.h" +#include "ir/return-utils.h" #include "ir/type-updating.h" #include "ir/utils.h" #include "param-utils.h" @@ -358,23 +359,7 @@ struct DAE : public Pass { } } // Remove any return values. - struct ReturnUpdater : public PostWalker { - Module* module; - ReturnUpdater(Function* func, Module* module) : module(module) { - walk(func->body); - } - void visitReturn(Return* curr) { - auto* value = curr->value; - assert(value); - curr->value = nullptr; - Builder builder(*module); - replaceCurrent(builder.makeSequence(builder.makeDrop(value), curr)); - } - } returnUpdater(func, module); - // Remove any value flowing out. - if (func->body->type.isConcrete()) { - func->body = Builder(*module).makeDrop(func->body); - } + ReturnUtils::removeReturns(func, *module); } // Given a function and all the calls to it, see if we can refine the type of diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index c27f5d6eb9e..8c08db55bde 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -92,6 +92,7 @@ #include "ir/manipulation.h" #include "ir/module-utils.h" #include "ir/names.h" +#include "ir/return-utils.h" #include "ir/type-updating.h" #include "ir/utils.h" #include "pass.h" @@ -103,6 +104,36 @@ namespace wasm { namespace { +// Core information about a call: the call itself, and if it is dropped, the +// drop. +struct CallInfo { + Call* call; + // Store a reference to the drop's pointer so that we can replace it, as when + // we optimize a dropped call we need to replace (drop (call)) with (call). + // Or, if the call is not dropped, this is nullptr. + Expression** drop; +}; + +// Finds the calls and whether each one of them is dropped. +struct CallFinder : public PostWalker { + std::vector infos; + + void visitCall(Call* curr) { + // Add the call as not having a drop, and update the drop later if we are. + infos.push_back(CallInfo{curr, nullptr}); + } + + void visitDrop(Drop* curr) { + if (curr->value->is()) { + // The call we just added to |infos| is dropped. + assert(!infos.empty()); + auto& back = infos.back(); + assert(back.call == curr->value); + back.drop = getCurrentPointer(); + } + } +}; + // Relevant information about a callsite for purposes of monomorphization. struct CallContext { // The operands of the call, processed to leave the parts that make sense to @@ -181,12 +212,12 @@ struct CallContext { // remaining values by updating |newOperands| (for example, if all the values // sent are constants, then |newOperands| will end up empty, as we have // nothing left to send). - void buildFromCall(Call* call, + void buildFromCall(CallInfo& info, std::vector& newOperands, Module& wasm) { Builder builder(wasm); - for (auto* operand : call->operands) { + for (auto* operand : info.call->operands) { // Process the operand. This is a copy operation, as we are trying to move // (copy) code from the callsite into the called function. When we find we // can copy then we do so, and when we cannot that value remains as a @@ -212,8 +243,7 @@ struct CallContext { })); } - // TODO: handle drop - dropped = false; + dropped = !!info.drop; } // Checks whether an expression can be moved into the context. @@ -299,6 +329,11 @@ struct Monomorphize : public Pass { void run(Module* module) override { // TODO: parallelize, see comments below + // Find all the return-calling functions. We cannot remove their returns + // (because turning a return call into a normal call may break the program + // by using more stack). + auto returnCallersMap = ReturnUtils::findReturnCallers(*module); + // Note the list of all functions. We'll be adding more, and do not want to // operate on those. std::vector funcNames; @@ -309,26 +344,38 @@ struct Monomorphize : public Pass { // to call the monomorphized targets. for (auto name : funcNames) { auto* func = module->getFunction(name); - for (auto* call : FindAll(func->body).list) { - if (call->type == Type::unreachable) { + + CallFinder callFinder; + callFinder.walk(func->body); + for (auto& info : callFinder.infos) { + if (info.call->type == Type::unreachable) { // Ignore unreachable code. // TODO: return_call? continue; } - if (call->target == name) { + if (info.call->target == name) { // Avoid recursion, which adds some complexity (as we'd be modifying // ourselves if we apply optimizations). continue; } - processCall(call, *module); + // If the target function does a return call, then as noted earlier we + // cannot remove its returns, so do not consider the drop as part of the + // context in such cases (as if we reverse-inlined the drop into the + // target then we'd be removing the returns). + if (returnCallersMap[module->getFunction(info.call->target)]) { + info.drop = nullptr; + } + + processCall(info, *module); } } } // Try to optimize a call. - void processCall(Call* call, Module& wasm) { + void processCall(CallInfo& info, Module& wasm) { + auto* call = info.call; auto target = call->target; auto* func = wasm.getFunction(target); if (func->imported()) { @@ -342,7 +389,7 @@ struct Monomorphize : public Pass { // if we use that context. CallContext context; std::vector newOperands; - context.buildFromCall(call, newOperands, wasm); + context.buildFromCall(info, newOperands, wasm); // See if we've already evaluated this function + call context. If so, then // we've memoized the result. @@ -350,11 +397,8 @@ struct Monomorphize : public Pass { if (iter != funcContextMap.end()) { auto newTarget = iter->second; if (newTarget != target) { - // When we computed this before we found a benefit to optimizing, and - // created a new monomorphized function to call. Use it by simply - // applying the new operands we computed, and adjusting the call target. - call->operands.set(newOperands); - call->target = newTarget; + // We saw benefit to optimizing this case. Apply that. + updateCall(info, newTarget, newOperands, wasm); } return; } @@ -419,8 +463,7 @@ struct Monomorphize : public Pass { if (worthwhile) { // We are using the monomorphized function, so update the call and add it // to the module. - call->operands.set(newOperands); - call->target = monoFunc->name; + updateCall(info, monoFunc->name, newOperands, wasm); wasm.addFunction(std::move(monoFunc)); } @@ -453,8 +496,9 @@ struct Monomorphize : public Pass { newParams.push_back(operand->type); } } - // TODO: support changes to results. - auto newResults = func->getResults(); + // If we were dropped then we are pulling the drop into the monomorphized + // function, which means we return nothing. + auto newResults = context.dropped ? Type::none : func->getResults(); newFunc->type = Signature(Type(newParams), newResults); // We must update local indexes: the new function has a potentially @@ -549,9 +593,32 @@ struct Monomorphize : public Pass { newFunc->body = builder.makeBlock(pre); } + if (context.dropped) { + ReturnUtils::removeReturns(newFunc.get(), wasm); + } + return newFunc; } + // Given a call and a new target it should be calling, apply that new target, + // including updating the operands and handling dropping. + void updateCall(const CallInfo& info, + Name newTarget, + const std::vector& newOperands, + Module& wasm) { + info.call->target = newTarget; + info.call->operands.set(newOperands); + + if (info.drop) { + // Replace (drop (call)) with (call), that is, replace the drop with the + // (updated) call which now has type none. Note we should have handled + // unreachability before getting here. + assert(info.call->type != Type::unreachable); + info.call->type = Type::none; + *info.drop = info.call; + } + } + // Run some function-level optimizations on a function. Ideally we would run a // minimal amount of optimizations here, but we do want to give the optimizer // as much of a chance to work as possible, so for now do all of -O3 (in diff --git a/test/lit/passes/monomorphize-drop.wast b/test/lit/passes/monomorphize-drop.wast new file mode 100644 index 00000000000..63923f76841 --- /dev/null +++ b/test/lit/passes/monomorphize-drop.wast @@ -0,0 +1,1191 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; As in monomorphize-types.wast, test in both "always" mode, which always +;; monomorphizes, and in "careful" mode which does it only when it appears to +;; actually help. + +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL + +(module + ;; Test that dropped functions are monomorphized, and the drop is reverse- + ;; inlined into the called function, enabling more optimizations. + + ;; ALWAYS: (type $0 (func (result i32))) + + ;; ALWAYS: (type $1 (func (param i32))) + + ;; ALWAYS: (type $2 (func (param i32 i32) (result i32))) + + ;; ALWAYS: (type $3 (func (param i32) (result i32))) + + ;; ALWAYS: (type $4 (func)) + + ;; ALWAYS: (type $5 (func (param i32 i32))) + + ;; ALWAYS: (func $work (type $2) (param $x i32) (param $y i32) (result i32) + ;; ALWAYS-NEXT: (i32.mul + ;; ALWAYS-NEXT: (i32.xor + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.div_s + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func (result i32))) + + ;; CAREFUL: (type $1 (func (param i32))) + + ;; CAREFUL: (type $2 (func (param i32 i32) (result i32))) + + ;; CAREFUL: (type $3 (func (param i32) (result i32))) + + ;; CAREFUL: (type $4 (func)) + + ;; CAREFUL: (type $5 (func (param i32 i32))) + + ;; CAREFUL: (func $work (type $2) (param $0 i32) (param $1 i32) (result i32) + ;; CAREFUL-NEXT: (i32.mul + ;; CAREFUL-NEXT: (i32.div_s + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.xor + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $work (param $x i32) (param $y i32) (result i32) + ;; Do some nontrivial work that we return. If this is dropped then we don't + ;; need that work. + (i32.mul + (i32.xor + (local.get $x) + (local.get $y) + ) + (i32.div_s + (local.get $x) + (local.get $y) + ) + ) + ) + + ;; ALWAYS: (func $calls (type $1) (param $x i32) + ;; ALWAYS-NEXT: (call $work_5) + ;; ALWAYS-NEXT: (call $work_5) + ;; ALWAYS-NEXT: (call $work_6 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $work_7 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $calls (type $1) (param $x i32) + ;; CAREFUL-NEXT: (call $work_5) + ;; CAREFUL-NEXT: (call $work_5) + ;; CAREFUL-NEXT: (call $work_6 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $work_7 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $calls (param $x i32) + ;; Both of these can call the same monomorphized function. In CAREFUL mode + ;; that function's body can also be optimized into a nop. + (drop + (call $work + (i32.const 3) + (i32.const 4) + ) + ) + (drop + (call $work + (i32.const 3) + (i32.const 4) + ) + ) + ;; Another call, now with an unknown parameter. This calls a different + ;; monomorphized function, but once again the body can be optimized into a + ;; nop in CAREFUL. + (drop + (call $work + (i32.const 3) + (local.get $x) + ) + ) + ;; Two unknown parameters. Yet another monomorphized function, but the same + ;; outcome. + (drop + (call $work + (local.get $x) + (local.get $x) + ) + ) + ) + + ;; ALWAYS: (func $call-undropped-trivial (type $3) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (call $work + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-undropped-trivial (type $3) (param $x i32) (result i32) + ;; CAREFUL-NEXT: (call $work + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-undropped-trivial (param $x i32) (result i32) + ;; A call of the same target that is dropped in the previous function, but + ;; now without a drop. We know nothing nontrivial here, so we do nothing. + (call $work + (local.get $x) + (local.get $x) + ) + ) + + ;; ALWAYS: (func $call-undropped (type $0) (result i32) + ;; ALWAYS-NEXT: (call $work_8) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-undropped (type $0) (result i32) + ;; CAREFUL-NEXT: (call $work_8) + ;; CAREFUL-NEXT: ) + (func $call-undropped (result i32) + ;; As above but now with constant params. We can monomorphize here - there + ;; is no issue in optimizing here without a drop and with a drop elsewhere - + ;; but we do call a different function of course, that returns an i32. + (call $work + (i32.const 3) + (i32.const 4) + ) + ) + + ;; ALWAYS: (func $call-no-params-return (type $0) (result i32) + ;; ALWAYS-NEXT: (return_call $work + ;; ALWAYS-NEXT: (i32.const 10) + ;; ALWAYS-NEXT: (i32.const 20) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-no-params-return (type $0) (result i32) + ;; CAREFUL-NEXT: (return_call $work + ;; CAREFUL-NEXT: (i32.const 10) + ;; CAREFUL-NEXT: (i32.const 20) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-no-params-return (result i32) + ;; Return calls can be monomorphized too, but we have that as a TODO atm. + (return_call $work + (i32.const 10) + (i32.const 20) + ) + ) +) + +;; ALWAYS: (func $work_5 (type $4) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (i32.const 4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.mul +;; ALWAYS-NEXT: (i32.xor +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.div_s +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $work_6 (type $1) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.mul +;; ALWAYS-NEXT: (i32.xor +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.div_s +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $work_7 (type $5) (param $0 i32) (param $1 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.mul +;; ALWAYS-NEXT: (i32.xor +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.div_s +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $work_8 (type $0) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (i32.const 4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.mul +;; ALWAYS-NEXT: (i32.xor +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.div_s +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $work_5 (type $4) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $work_6 (type $1) (param $0 i32) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (i32.div_s +;; CAREFUL-NEXT: (i32.const 3) +;; CAREFUL-NEXT: (local.get $0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $work_7 (type $5) (param $0 i32) (param $1 i32) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (i32.div_s +;; CAREFUL-NEXT: (local.get $0) +;; CAREFUL-NEXT: (local.get $1) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $work_8 (type $0) (result i32) +;; CAREFUL-NEXT: (i32.const 0) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param i32 i32) (result i32))) + + ;; ALWAYS: (type $2 (func (result i32))) + + ;; ALWAYS: (import "a" "b" (func $import (type $1) (param i32 i32) (result i32))) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32 i32) (result i32))) + + ;; CAREFUL: (type $2 (func (result i32))) + + ;; CAREFUL: (import "a" "b" (func $import (type $1) (param i32 i32) (result i32))) + (import "a" "b" (func $import (param i32 i32) (result i32))) + + ;; ALWAYS: (func $no-params (type $2) (result i32) + ;; ALWAYS-NEXT: (i32.const 42) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $no-params (type $2) (result i32) + ;; CAREFUL-NEXT: (i32.const 42) + ;; CAREFUL-NEXT: ) + (func $no-params (result i32) + ;; A function that will be dropped, and has no params. + (i32.const 42) + ) + + ;; ALWAYS: (func $call-no-params (type $2) (result i32) + ;; ALWAYS-NEXT: (call $no-params_6) + ;; ALWAYS-NEXT: (call $no-params) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-no-params (type $2) (result i32) + ;; CAREFUL-NEXT: (call $no-params_6) + ;; CAREFUL-NEXT: (call $no-params) + ;; CAREFUL-NEXT: ) + (func $call-no-params (result i32) + ;; We can optimize the drop into the target. + (drop + (call $no-params) + ) + ;; Without a drop, the call context is trivial and we do nothing. + (call $no-params) + ) + + ;; ALWAYS: (func $call-import (type $0) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $import + ;; ALWAYS-NEXT: (i32.const 3) + ;; ALWAYS-NEXT: (i32.const 4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-import (type $0) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $import + ;; CAREFUL-NEXT: (i32.const 3) + ;; CAREFUL-NEXT: (i32.const 4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-import + ;; Calling an import allows no optimizations. + (drop + (call $import + (i32.const 3) + (i32.const 4) + ) + ) + ) + + ;; ALWAYS: (func $import-work (type $1) (param $x i32) (param $y i32) (result i32) + ;; ALWAYS-NEXT: (call $import + ;; ALWAYS-NEXT: (i32.xor + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.div_s + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $y) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $import-work (type $1) (param $0 i32) (param $1 i32) (result i32) + ;; CAREFUL-NEXT: (call $import + ;; CAREFUL-NEXT: (i32.xor + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.div_s + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $import-work (param $x i32) (param $y i32) (result i32) + ;; Do some work and also call an import. + (call $import + (i32.xor + (local.get $x) + (local.get $y) + ) + (i32.div_s + (local.get $x) + (local.get $y) + ) + ) + ) + + ;; ALWAYS: (func $call-import-work (type $0) + ;; ALWAYS-NEXT: (call $import-work_7) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-import-work (type $0) + ;; CAREFUL-NEXT: (call $import-work_7) + ;; CAREFUL-NEXT: ) + (func $call-import-work + ;; This is monomorphized with the drop. + (drop + (call $import-work + (i32.const 3) + (i32.const 4) + ) + ) + ) +) + +;; ALWAYS: (func $no-params_6 (type $0) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (i32.const 42) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $import-work_7 (type $0) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local $y i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $y +;; ALWAYS-NEXT: (i32.const 4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (call $import +;; ALWAYS-NEXT: (i32.xor +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.div_s +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (local.get $y) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $no-params_6 (type $0) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $import-work_7 (type $0) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (call $import +;; CAREFUL-NEXT: (i32.const 7) +;; CAREFUL-NEXT: (i32.const 0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $0 (func (param i32))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (type $2 (func (result i32))) + + ;; ALWAYS: (type $3 (func (param i32) (result i32))) + + ;; ALWAYS: (import "a" "c" (func $import (type $2) (result i32))) + ;; CAREFUL: (type $0 (func (param i32))) + + ;; CAREFUL: (type $1 (func)) + + ;; CAREFUL: (type $2 (func (result i32))) + + ;; CAREFUL: (type $3 (func (param i32) (result i32))) + + ;; CAREFUL: (import "a" "c" (func $import (type $2) (result i32))) + (import "a" "c" (func $import (result i32))) + + ;; ALWAYS: (func $return-normal (type $3) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (return + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $return-normal (type $3) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (return + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + (func $return-normal (param $x i32) (result i32) + ;; This function has a return, which needs to be handled in the + ;; monomorphized function, as we'll no longer return a value. + (if + (local.get $x) + (then + (drop + (call $import) + ) + (return + (i32.const 0) + ) + ) + ) + ;; Also return a value by flowing it out. + (i32.const 1) + ) + + ;; ALWAYS: (func $call-return-normal (type $0) (param $x i32) + ;; ALWAYS-NEXT: (call $return-normal_3) + ;; ALWAYS-NEXT: (call $return-normal_4) + ;; ALWAYS-NEXT: (call $return-normal_5 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-return-normal (type $0) (param $x i32) + ;; CAREFUL-NEXT: (call $return-normal_3) + ;; CAREFUL-NEXT: (call $return-normal_4) + ;; CAREFUL-NEXT: (call $return-normal_5 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-return-normal (param $x i32) + ;; Call the above function with 0, 1, and an unknown value, to test the two + ;; code paths there + the case of the input being unknown. We monomorphize + ;; them all (differently). + (drop + (call $return-normal + (i32.const 0) + ) + ) + (drop + (call $return-normal + (i32.const 1) + ) + ) + (drop + (call $return-normal + (local.get $x) + ) + ) + ) +) + +;; ALWAYS: (func $return-normal_3 (type $1) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (return) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $return-normal_4 (type $1) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (return) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $return-normal_5 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (return) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $return-normal_3 (type $1) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $return-normal_4 (type $1) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (block +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (call $import) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: (return) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $return-normal_5 (type $0) (param $0 i32) +;; CAREFUL-NEXT: (if +;; CAREFUL-NEXT: (local.get $0) +;; CAREFUL-NEXT: (then +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (call $import) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $0 (func (result i32))) + + ;; ALWAYS: (type $1 (func (param i32) (result i32))) + + ;; ALWAYS: (type $2 (func (param i32))) + + ;; ALWAYS: (import "a" "c" (func $import (type $0) (result i32))) + ;; CAREFUL: (type $0 (func (result i32))) + + ;; CAREFUL: (type $1 (func (param i32) (result i32))) + + ;; CAREFUL: (type $2 (func (param i32))) + + ;; CAREFUL: (import "a" "c" (func $import (type $0) (result i32))) + (import "a" "c" (func $import (result i32))) + + ;; ALWAYS: (func $return-call (type $1) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $return-call (type $1) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + (func $return-call (param $x i32) (result i32) + ;; As above, but now with a return_call. We do not monomorphize the drop + ;; part, as if we included the drop we'd turn the call into a non-return + ;; call, which can break things. + (if + (local.get $x) + (then + (return_call $import) + ) + ) + (i32.const 1) + ) + + ;; ALWAYS: (func $call-return-call (type $2) (param $x i32) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call_3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call_4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-return-call (type $2) (param $x i32) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call_3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call_4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-return-call (param $x i32) + ;; As above, but due to the return call we won't monomorphize the drop. As + ;; a result we monomorphize the first two, leaving drops here, and do + ;; nothing for the last (as the call context is trivial). + (drop + (call $return-call + (i32.const 0) + ) + ) + (drop + (call $return-call + (i32.const 1) + ) + ) + (drop + (call $return-call + (local.get $x) + ) + ) + ) +) + +;; ALWAYS: (func $return-call_3 (type $0) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $return-call_4 (type $0) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $return-call_3 (type $0) (result i32) +;; CAREFUL-NEXT: (i32.const 1) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $return-call_4 (type $0) (result i32) +;; CAREFUL-NEXT: (return_call $import) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $i (func (result i32))) + ;; CAREFUL: (type $i (func (result i32))) + (type $i (func (result i32))) + + ;; ALWAYS: (type $1 (func (param i32) (result i32))) + + ;; ALWAYS: (type $2 (func (param i32))) + + ;; ALWAYS: (import "a" "c" (func $import (type $i) (result i32))) + ;; CAREFUL: (type $1 (func (param i32) (result i32))) + + ;; CAREFUL: (type $2 (func (param i32))) + + ;; CAREFUL: (import "a" "c" (func $import (type $i) (result i32))) + (import "a" "c" (func $import (result i32))) + + ;; ALWAYS: (table $table 10 10 funcref) + ;; CAREFUL: (table $table 10 10 funcref) + (table $table 10 10 funcref) + + ;; ALWAYS: (func $return-call-indirect (type $1) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call_indirect $table (type $i) + ;; ALWAYS-NEXT: (call $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $return-call-indirect (type $1) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call_indirect $table (type $i) + ;; CAREFUL-NEXT: (call $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + (func $return-call-indirect (param $x i32) (result i32) + ;; As above, but now with a return_call_indirect. The outcome below is + ;; similar. + (if + (local.get $x) + (then + (return_call_indirect (type $i) + (call $import) + ) + ) + ) + (i32.const 1) + ) + + ;; ALWAYS: (func $call-return-call-indirect (type $2) (param $x i32) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-indirect_3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-indirect_4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-indirect + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-return-call-indirect (type $2) (param $x i32) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-indirect_3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-indirect_4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-indirect + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $call-return-call-indirect (param $x i32) + (drop + (call $return-call-indirect + (i32.const 0) + ) + ) + (drop + (call $return-call-indirect + (i32.const 1) + ) + ) + (drop + (call $return-call-indirect + (local.get $x) + ) + ) + ) +) + +;; ALWAYS: (func $return-call-indirect_3 (type $i) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call_indirect $table (type $i) +;; ALWAYS-NEXT: (call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $return-call-indirect_4 (type $i) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call_indirect $table (type $i) +;; ALWAYS-NEXT: (call $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $return-call-indirect_3 (type $i) (result i32) +;; CAREFUL-NEXT: (i32.const 1) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $return-call-indirect_4 (type $i) (result i32) +;; CAREFUL-NEXT: (return_call_indirect $table (type $i) +;; CAREFUL-NEXT: (call $import) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $i (func (result i32))) + ;; CAREFUL: (type $i (func (result i32))) + (type $i (func (result i32))) + + ;; ALWAYS: (type $1 (func (param i32) (result i32))) + + ;; ALWAYS: (import "a" "c" (func $import (type $i) (result i32))) + ;; CAREFUL: (type $1 (func (param i32) (result i32))) + + ;; CAREFUL: (import "a" "c" (func $import (type $i) (result i32))) + (import "a" "c" (func $import (result i32))) + + ;; ALWAYS: (table $table 10 10 funcref) + ;; CAREFUL: (table $table 10 10 funcref) + (table $table 10 10 funcref) + + ;; ALWAYS: (elem declare func $import) + + ;; ALWAYS: (func $return-call-ref (type $1) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call_ref $i + ;; ALWAYS-NEXT: (ref.func $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (elem declare func $import) + + ;; CAREFUL: (func $return-call-ref (type $1) (param $0 i32) (result i32) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + (func $return-call-ref (param $x i32) (result i32) + ;; As above, but now with a return_call_ref. The outcome below is similar. + (if + (local.get $x) + (then + (return_call_ref $i + (ref.func $import) + ) + ) + ) + (i32.const 1) + ) + + ;; ALWAYS: (func $call-return-call-ref (type $1) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-ref_3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-ref_4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (drop + ;; ALWAYS-NEXT: (call $return-call-ref + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call_indirect $table (type $i) + ;; ALWAYS-NEXT: (i32.const 7) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (if + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (return_call_ref $i + ;; ALWAYS-NEXT: (ref.func $import) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (unreachable) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $call-return-call-ref (type $1) (param $x i32) (result i32) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-ref_3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-ref_4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (drop + ;; CAREFUL-NEXT: (call $return-call-ref + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call_indirect $table (type $i) + ;; CAREFUL-NEXT: (i32.const 7) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (if + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (return_call_ref $i + ;; CAREFUL-NEXT: (ref.func $import) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (unreachable) + ;; CAREFUL-NEXT: ) + (func $call-return-call-ref (param $x i32) (result i32) + ;; As before, a set of three calls (with similar outcomes as before: the + ;; first two are monomorphized without the drop; the last is unchanged). + (drop + (call $return-call-ref + (i32.const 0) + ) + ) + (drop + (call $return-call-ref + (i32.const 1) + ) + ) + (drop + (call $return-call-ref + (local.get $x) + ) + ) + + ;; Also add some return calls here, to show that it is fine for the caller + ;; to have them: we can still monomorphize some of the previous calls + ;; (without their drops). + (if + (local.get $x) + (then + (return_call $import) + ) + ) + (if + (local.get $x) + (then + (return_call_indirect (type $i) + (i32.const 7) + ) + ) + ) + (if + (local.get $x) + (then + (return_call_ref $i + (ref.func $import) + ) + ) + ) + (unreachable) + ) +) + +;; ALWAYS: (func $return-call-ref_3 (type $i) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call_ref $i +;; ALWAYS-NEXT: (ref.func $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $return-call-ref_4 (type $i) (result i32) +;; ALWAYS-NEXT: (local $x i32) +;; ALWAYS-NEXT: (local.set $x +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (if +;; ALWAYS-NEXT: (local.get $x) +;; ALWAYS-NEXT: (then +;; ALWAYS-NEXT: (return_call_ref $i +;; ALWAYS-NEXT: (ref.func $import) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $return-call-ref_3 (type $i) (result i32) +;; CAREFUL-NEXT: (i32.const 1) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $return-call-ref_4 (type $i) (result i32) +;; CAREFUL-NEXT: (return_call $import) +;; CAREFUL-NEXT: ) From 65ee5b95743e4ee984643923c2d88a8b320cd51d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Sat, 13 Jul 2024 19:51:45 -0400 Subject: [PATCH 442/553] [threads] Fix struct op validation for shared null (#6742) --- src/wasm/wasm-validator.cpp | 2 +- test/spec/shared-struct.wast | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index eb2f949b24a..143baee416e 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2879,7 +2879,7 @@ void FunctionValidator::visitStructSet(StructSet* curr) { return; } auto type = curr->ref->type.getHeapType(); - if (type == HeapType::none) { + if (type.isBasic() && type.getBasic(Unshared) == HeapType::none) { return; } if (!shouldBeTrue( diff --git a/test/spec/shared-struct.wast b/test/spec/shared-struct.wast index 28139bb2809..f321d880061 100644 --- a/test/spec/shared-struct.wast +++ b/test/spec/shared-struct.wast @@ -90,3 +90,11 @@ (func (param (ref null $i8)) (struct.set $i8 0 (local.get 0) (i32.const 0))) ) + +;; Bottom types +(module + (type $i8 (shared (struct (mut i8)))) + (func (drop (struct.get_s $i8 0 (ref.null (shared none))))) + (func (drop (struct.get_u $i8 0 (ref.null (shared none))))) + (func (struct.set $i8 0 (ref.null (shared none)) (i32.const 0))) +) From aec516f1259c3fec92982db92dc0e4e67ab2251a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Sat, 13 Jul 2024 19:51:59 -0400 Subject: [PATCH 443/553] [threads] Test that array ops work with shared nulls (#6743) --- test/spec/shared-array.wast | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/test/spec/shared-array.wast b/test/spec/shared-array.wast index 7aa3877316a..8c748fd20f0 100644 --- a/test/spec/shared-array.wast +++ b/test/spec/shared-array.wast @@ -73,9 +73,10 @@ (type $i8 (shared (array (mut i8)))) (type $i32 (shared (array (mut i32)))) (type $unshared (array (mut i8))) + (type $funcs (shared (array (mut (ref null (shared any)))))) (data) - (elem) + (elem (ref null (shared any))) (func (array.new $i8 (i32.const 0) (i32.const 0)) (drop)) @@ -110,6 +111,29 @@ (func (param (ref null $i8)) (array.init_data $i8 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) + (func (param (ref null $funcs)) + (array.init_elem $funcs 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) +) + +;; Bottom types +(module + (type $i8 (shared (array (mut i8)))) + (type $i32 (shared (array (mut i32)))) + (type $funcs (shared (array (mut (ref null (shared func)))))) + + (data) + (elem (ref null (shared any))) + + (func (array.get_s $i8 (ref.null (shared none)) (i32.const 0)) (drop)) + (func (array.get_u $i8 (ref.null (shared none)) (i32.const 0)) (drop)) + (func (array.get $i32 (ref.null (shared none)) (i32.const 0)) (drop)) + (func (array.set $i8 (ref.null (shared none)) (i32.const 0) (i32.const 0))) (func (param (ref null $i8)) - (array.init_data $i8 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) + (array.copy $i8 $i8 (ref.null (shared none)) (i32.const 0) (local.get 0) (i32.const 0) (i32.const 0))) + (func (param (ref null $i8)) + (array.copy $i8 $i8 (local.get 0) (i32.const 0) (ref.null (shared none)) (i32.const 0) (i32.const 0))) + (func (array.copy $i8 $i8 (ref.null (shared none)) (i32.const 0) (ref.null (shared none)) (i32.const 0) (i32.const 0))) + (func (array.fill $i8 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) + (func (array.init_data $i8 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) + (func (array.init_elem $funcs 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) ) From fd8b2bd43d73cf1976426e60c22c5261fa343510 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Tue, 16 Jul 2024 01:04:37 +0200 Subject: [PATCH 444/553] Allow different arguments for multiple instances of a pass (#6687) Each pass instance can now store an argument for it, which can be different. This may be a breaking change for the corner case of running a pass multiple times and setting the pass's argument multiple times as well (before, the last pass argument affected them all; now, it affects the last instance only). This only affects arguments with the name of a pass; others remain global, as before (and multiple passes can read them, in fact). See the CHANGELOG for details. Fixes #6646 --- CHANGELOG.md | 6 +++ src/binaryen-c.cpp | 10 ++++- src/pass.h | 25 ++++++++++-- src/passes/Asyncify.cpp | 39 ++++++++---------- src/passes/Directize.cpp | 2 +- src/passes/ExtractFunction.cpp | 9 ++--- src/passes/FuncCastEmulation.cpp | 3 +- src/passes/JSPI.cpp | 11 +++--- src/passes/LegalizeJSInterface.cpp | 5 +-- src/passes/LogExecution.cpp | 3 +- src/passes/NoInline.cpp | 4 +- src/passes/PostEmscripten.cpp | 6 +-- src/passes/PrintFunctionMap.cpp | 2 +- src/passes/SeparateDataSegments.cpp | 14 +++---- src/passes/SetGlobals.cpp | 6 +-- src/passes/StackCheck.cpp | 3 +- src/passes/TraceCalls.cpp | 8 ++-- src/passes/pass.cpp | 38 ++++++++++++++++++ src/tools/optimization-options.h | 44 ++++++++++++++++++--- src/tools/tool-options.h | 14 ++++++- src/tools/wasm-split/wasm-split.cpp | 3 +- test/lit/help/wasm-as.test | 7 +++- test/lit/help/wasm-ctor-eval.test | 7 +++- test/lit/help/wasm-dis.test | 7 +++- test/lit/help/wasm-emscripten-finalize.test | 7 +++- test/lit/help/wasm-merge.test | 7 +++- test/lit/help/wasm-metadce.test | 9 ++++- test/lit/help/wasm-opt.test | 9 ++++- test/lit/help/wasm-reduce.test | 7 +++- test/lit/help/wasm-split.test | 7 +++- test/lit/help/wasm2js.test | 9 ++++- 31 files changed, 242 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56199c9831a..5f7a3758141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,12 @@ v118 - The build-time option to use legacy WasmGC opcodes is removed. - The strings in `string.const` instructions must now be valid WTF-8. - The `TraverseCalls` flag for `ExpressionRunner` is removed. + - Passes can now receive individual pass arguments, that is --foo=A --foo=B for + a pass foo will run the pass twice (which was possible before) and will now + run it first with argument A and second with B. --pass-arg=foo@BAR will now + apply to the most recent --foo pass on the commandline, if foo is a pass + (while global pass arguments - that are not the name of a pass - remain, as + before, global for all passes). v117 ---- diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index be80206f568..298a5023368 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -5453,7 +5453,10 @@ void BinaryenModuleRunPasses(BinaryenModuleRef module, PassRunner passRunner((Module*)module); passRunner.options = globalPassOptions; for (BinaryenIndex i = 0; i < numPasses; i++) { - passRunner.add(passes[i]); + passRunner.add(passes[i], + globalPassOptions.arguments.count(passes[i]) > 0 + ? globalPassOptions.arguments[passes[i]] + : std::optional()); } passRunner.run(); } @@ -5704,7 +5707,10 @@ void BinaryenFunctionRunPasses(BinaryenFunctionRef func, PassRunner passRunner((Module*)module); passRunner.options = globalPassOptions; for (BinaryenIndex i = 0; i < numPasses; i++) { - passRunner.add(passes[i]); + passRunner.add(passes[i], + globalPassOptions.arguments.count(passes[i]) > 0 + ? globalPassOptions.arguments[passes[i]] + : std::optional()); } passRunner.runOnFunction((Function*)func); } diff --git a/src/pass.h b/src/pass.h index ab060309b4b..9352319ad65 100644 --- a/src/pass.h +++ b/src/pass.h @@ -39,12 +39,14 @@ struct PassRegistry { using Creator = std::function; void registerPass(const char* name, const char* description, Creator create); + // Register a pass that's used for internal testing. These passes do not show // up in --help. void registerTestPass(const char* name, const char* description, Creator create); std::unique_ptr createPass(std::string name); std::vector getRegisteredNames(); + bool containsPass(const std::string& name); std::string getPassDescription(std::string name); bool isPassHidden(std::string name); @@ -103,6 +105,8 @@ class EffectAnalyzer; using FuncEffectsMap = std::unordered_map; struct PassOptions { + friend Pass; + // Run passes in debug mode, doing extra validation and timing checks. bool debug = false; // Whether to run the validator to check for errors. @@ -269,6 +273,7 @@ struct PassOptions { return PassOptions(); // defaults are to not optimize } +private: bool hasArgument(std::string key) { return arguments.count(key) > 0; } std::string getArgument(std::string key, std::string errorTextIfMissing) { @@ -322,9 +327,8 @@ struct PassRunner { } // Add a pass using its name. - void add(std::string passName) { - doAdd(PassRegistry::get()->createPass(passName)); - } + void add(std::string passName, + std::optional passArg = std::nullopt); // Add a pass given an instance. void add(std::unique_ptr pass) { doAdd(std::move(pass)); } @@ -486,6 +490,8 @@ class Pass { // to imports must override this to return true. virtual bool addsEffects() { return false; } + void setPassArg(const std::string& value) { passArg = value; } + std::string name; PassRunner* getPassRunner() { return runner; } @@ -497,6 +503,19 @@ class Pass { PassOptions& getPassOptions() { return runner->options; } protected: + bool hasArgument(const std::string& key); + std::string getArgument(const std::string& key, + const std::string& errorTextIfMissing); + std::string getArgumentOrDefault(const std::string& key, + const std::string& defaultValue); + + // The main argument of the pass, which can be specified individually for + // every pass . getArgument() and friends will refer to this value if queried + // for a key that matches the pass name. All other arguments are taken from + // the runner / passOptions and therefore are global for all instances of a + // pass. + std::optional passArg; + Pass() = default; Pass(const Pass&) = default; Pass(Pass&&) = default; diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 1ba764387e8..7ac9cf48921 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -1608,54 +1608,49 @@ struct Asyncify : public Pass { bool addsEffects() override { return true; } void run(Module* module) override { - auto& options = getPassOptions(); - bool optimize = options.optimizeLevel > 0; + bool optimize = getPassOptions().optimizeLevel > 0; // Find which things can change the state. auto stateChangingImports = String::trim(read_possible_response_file( - options.getArgumentOrDefault("asyncify-imports", ""))); - auto ignoreImports = - options.getArgumentOrDefault("asyncify-ignore-imports", ""); + getArgumentOrDefault("asyncify-imports", ""))); + auto ignoreImports = getArgumentOrDefault("asyncify-ignore-imports", ""); bool allImportsCanChangeState = stateChangingImports == "" && ignoreImports == ""; String::Split listedImports(stateChangingImports, String::Split::NewLineOr(",")); // canIndirectChangeState is the default. asyncify-ignore-indirect sets it // to false. - auto canIndirectChangeState = - !options.hasArgument("asyncify-ignore-indirect"); + auto canIndirectChangeState = !hasArgument("asyncify-ignore-indirect"); std::string removeListInput = - options.getArgumentOrDefault("asyncify-removelist", ""); + getArgumentOrDefault("asyncify-removelist", ""); if (removeListInput.empty()) { // Support old name for now to avoid immediate breakage TODO remove - removeListInput = options.getArgumentOrDefault("asyncify-blacklist", ""); + removeListInput = getArgumentOrDefault("asyncify-blacklist", ""); } String::Split removeList( String::trim(read_possible_response_file(removeListInput)), String::Split::NewLineOr(",")); - String::Split addList( - String::trim(read_possible_response_file( - options.getArgumentOrDefault("asyncify-addlist", ""))), - String::Split::NewLineOr(",")); - std::string onlyListInput = - options.getArgumentOrDefault("asyncify-onlylist", ""); + String::Split addList(String::trim(read_possible_response_file( + getArgumentOrDefault("asyncify-addlist", ""))), + String::Split::NewLineOr(",")); + std::string onlyListInput = getArgumentOrDefault("asyncify-onlylist", ""); if (onlyListInput.empty()) { // Support old name for now to avoid immediate breakage TODO remove - onlyListInput = options.getArgumentOrDefault("asyncify-whitelist", ""); + onlyListInput = getArgumentOrDefault("asyncify-whitelist", ""); } String::Split onlyList( String::trim(read_possible_response_file(onlyListInput)), String::Split::NewLineOr(",")); - auto asserts = options.hasArgument("asyncify-asserts"); - auto verbose = options.hasArgument("asyncify-verbose"); - auto relocatable = options.hasArgument("asyncify-relocatable"); - auto secondaryMemory = options.hasArgument("asyncify-in-secondary-memory"); - auto propagateAddList = options.hasArgument("asyncify-propagate-addlist"); + auto asserts = hasArgument("asyncify-asserts"); + auto verbose = hasArgument("asyncify-verbose"); + auto relocatable = hasArgument("asyncify-relocatable"); + auto secondaryMemory = hasArgument("asyncify-in-secondary-memory"); + auto propagateAddList = hasArgument("asyncify-propagate-addlist"); // Ensure there is a memory, as we need it. if (secondaryMemory) { auto secondaryMemorySizeString = - options.getArgumentOrDefault("asyncify-secondary-memory-size", "1"); + getArgumentOrDefault("asyncify-secondary-memory-size", "1"); Address secondaryMemorySize = std::stoi(secondaryMemorySizeString); asyncifyMemory = createSecondaryMemory(module, secondaryMemorySize); } else { diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp index 66b42d3867f..6cb4e46d8c2 100644 --- a/src/passes/Directize.cpp +++ b/src/passes/Directize.cpp @@ -203,7 +203,7 @@ struct Directize : public Pass { // TODO: consider a per-table option here auto initialContentsImmutable = - getPassOptions().hasArgument("directize-initial-contents-immutable"); + hasArgument("directize-initial-contents-immutable"); // Set up the initial info. TableInfoMap tables; diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp index 440468ede19..df53afbf2ba 100644 --- a/src/passes/ExtractFunction.cpp +++ b/src/passes/ExtractFunction.cpp @@ -62,7 +62,7 @@ struct ExtractFunction : public Pass { bool addsEffects() override { return true; } void run(Module* module) override { - Name name = getPassOptions().getArgument( + Name name = getArgument( "extract-function", "ExtractFunction usage: wasm-opt --extract-function=FUNCTION_NAME"); extract(getPassRunner(), module, name); @@ -74,10 +74,9 @@ struct ExtractFunctionIndex : public Pass { bool addsEffects() override { return true; } void run(Module* module) override { - std::string index = - getPassOptions().getArgument("extract-function-index", - "ExtractFunctionIndex usage: wasm-opt " - "--extract-function-index=FUNCTION_INDEX"); + std::string index = getArgument("extract-function-index", + "ExtractFunctionIndex usage: wasm-opt " + "--extract-function-index=FUNCTION_INDEX"); for (char c : index) { if (!std::isdigit(c)) { Fatal() << "Expected numeric function index"; diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 23eb98a8c0d..972cf719cb7 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -157,8 +157,7 @@ struct FuncCastEmulation : public Pass { bool addsEffects() override { return true; } void run(Module* module) override { - Index numParams = std::stoul( - getPassOptions().getArgumentOrDefault("max-func-params", "16")); + Index numParams = std::stoul(getArgumentOrDefault("max-func-params", "16")); // we just need the one ABI function type for all indirect calls HeapType ABIType( Signature(Type(std::vector(numParams, Type::i64)), Type::i64)); diff --git a/src/passes/JSPI.cpp b/src/passes/JSPI.cpp index 1adf0de4ca2..d5fed1faf63 100644 --- a/src/passes/JSPI.cpp +++ b/src/passes/JSPI.cpp @@ -83,18 +83,17 @@ struct JSPI : public Pass { void run(Module* module) override { Builder builder(*module); - auto& options = getPassOptions(); // Find which imports can suspend. - auto stateChangingImports = String::trim(read_possible_response_file( - options.getArgumentOrDefault("jspi-imports", ""))); + auto stateChangingImports = String::trim( + read_possible_response_file(getArgumentOrDefault("jspi-imports", ""))); String::Split listedImports(stateChangingImports, ","); // Find which exports should create a promise. - auto stateChangingExports = String::trim(read_possible_response_file( - options.getArgumentOrDefault("jspi-exports", ""))); + auto stateChangingExports = String::trim( + read_possible_response_file(getArgumentOrDefault("jspi-exports", ""))); String::Split listedExports(stateChangingExports, ","); - bool wasmSplit = options.hasArgument("jspi-split-module"); + bool wasmSplit = hasArgument("jspi-split-module"); if (wasmSplit) { // Make an import for the load secondary module function so a JSPI wrapper // version will be created. diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index a0b526a811e..bfc7e192b15 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -64,9 +64,8 @@ struct LegalizeJSInterface : public Pass { setTempRet0 = nullptr; getTempRet0 = nullptr; auto exportOriginals = - getPassOptions().hasArgument("legalize-js-interface-export-originals"); - exportedHelpers = - getPassOptions().hasArgument("legalize-js-interface-exported-helpers"); + hasArgument("legalize-js-interface-export-originals"); + exportedHelpers = hasArgument("legalize-js-interface-exported-helpers"); // for each illegal export, we must export a legalized stub instead std::vector> newExports; for (auto& ex : module->exports) { diff --git a/src/passes/LogExecution.cpp b/src/passes/LogExecution.cpp index f1d48012f85..aa7948963bc 100644 --- a/src/passes/LogExecution.cpp +++ b/src/passes/LogExecution.cpp @@ -46,8 +46,7 @@ struct LogExecution : public WalkerPass> { bool addsEffects() override { return true; } void run(Module* module) override { - auto& options = getPassOptions(); - loggerModule = options.getArgumentOrDefault("log-execution", ""); + loggerModule = getArgumentOrDefault("log-execution", ""); super::run(module); } diff --git a/src/passes/NoInline.cpp b/src/passes/NoInline.cpp index 59e4f7e2ca8..34f693e296b 100644 --- a/src/passes/NoInline.cpp +++ b/src/passes/NoInline.cpp @@ -48,8 +48,8 @@ struct NoInline : public Pass { NoInline(NoInlineMode mode) : mode(mode) {} void run(Module* module) override { - std::string pattern = getPassOptions().getArgument( - name, "Usage usage: wasm-opt --" + name + "=WILDCARD"); + std::string pattern = + getArgument(name, "Usage usage: wasm-opt --" + name + "=WILDCARD"); for (auto& func : module->functions) { if (!String::wildcardMatch(pattern, func->name.toString())) { diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp index 7ade801cceb..0e2c268dec0 100644 --- a/src/passes/PostEmscripten.cpp +++ b/src/passes/PostEmscripten.cpp @@ -214,8 +214,7 @@ struct PostEmscripten : public Pass { std::vector
segmentOffsets; // segment index => address offset calcSegmentOffsets(module, segmentOffsets); - auto& options = getPassOptions(); - auto sideModule = options.hasArgument("post-emscripten-side-module"); + auto sideModule = hasArgument("post-emscripten-side-module"); if (!sideModule) { removeData(module, segmentOffsets, "__start_em_asm", "__stop_em_asm"); removeData(module, segmentOffsets, "__start_em_js", "__stop_em_js"); @@ -235,8 +234,7 @@ struct PostEmscripten : public Pass { } void removeEmJsExports(Module& module) { - auto& options = getPassOptions(); - auto sideModule = options.hasArgument("post-emscripten-side-module"); + auto sideModule = hasArgument("post-emscripten-side-module"); EmJsWalker walker(sideModule); walker.walkModule(&module); for (const Export& exp : walker.toRemove) { diff --git a/src/passes/PrintFunctionMap.cpp b/src/passes/PrintFunctionMap.cpp index 08f5a359bb7..4fe266ec084 100644 --- a/src/passes/PrintFunctionMap.cpp +++ b/src/passes/PrintFunctionMap.cpp @@ -37,7 +37,7 @@ struct PrintFunctionMap : public Pass { void run(Module* module) override { // If an argument is provided, write to that file; otherwise write to // stdout. - auto outFile = getPassOptions().getArgumentOrDefault("symbolmap", ""); + auto outFile = getArgumentOrDefault("symbolmap", ""); Output output(outFile, Flags::Text); auto& o = output.getStream(); Index i = 0; diff --git a/src/passes/SeparateDataSegments.cpp b/src/passes/SeparateDataSegments.cpp index 3e48d14bc0e..bd684dbe82c 100644 --- a/src/passes/SeparateDataSegments.cpp +++ b/src/passes/SeparateDataSegments.cpp @@ -33,14 +33,14 @@ struct SeparateDataSegments : public Pass { void run(Module* module) override { std::string outfileName = - getPassOptions().getArgument("separate-data-segments", - "SeparateDataSegments usage: wasm-opt " - "--separate-data-segments@FILENAME"); + getArgument("separate-data-segments", + "SeparateDataSegments usage: wasm-opt " + "--separate-data-segments@FILENAME"); Output outfile(outfileName, Flags::Binary); - std::string baseStr = getPassOptions().getArgument( - "separate-data-segments-global-base", - "SeparateDataSegments usage: wasm-opt " - "--pass-arg=separate-data-segments-global-base@NUMBER"); + std::string baseStr = + getArgument("separate-data-segments-global-base", + "SeparateDataSegments usage: wasm-opt " + "--pass-arg=separate-data-segments-global-base@NUMBER"); Address base = std::stoi(baseStr); size_t lastEnd = 0; for (auto& seg : module->dataSegments) { diff --git a/src/passes/SetGlobals.cpp b/src/passes/SetGlobals.cpp index 5e24184fa55..4c0718e849c 100644 --- a/src/passes/SetGlobals.cpp +++ b/src/passes/SetGlobals.cpp @@ -29,9 +29,9 @@ struct SetGlobals : public Pass { bool requiresNonNullableLocalFixups() override { return false; } void run(Module* module) override { - Name input = getPassRunner()->options.getArgument( - "set-globals", - "SetGlobals usage: wasm-opt --pass-arg=set-globals@x=y,z=w"); + Name input = + getArgument("set-globals", + "SetGlobals usage: wasm-opt --pass-arg=set-globals@x=y,z=w"); // The input is a set of X=Y pairs separated by commas. String::Split pairs(input.toString(), ","); diff --git a/src/passes/StackCheck.cpp b/src/passes/StackCheck.cpp index 229a97f26bd..ce5d346b944 100644 --- a/src/passes/StackCheck.cpp +++ b/src/passes/StackCheck.cpp @@ -141,8 +141,7 @@ struct StackCheck : public Pass { auto stackLimitName = Names::getValidGlobalName(*module, "__stack_limit"); Name handler; - auto handlerName = - getPassOptions().getArgumentOrDefault("stack-check-handler", ""); + auto handlerName = getArgumentOrDefault("stack-check-handler", ""); if (handlerName != "") { handler = handlerName; importStackOverflowHandler( diff --git a/src/passes/TraceCalls.cpp b/src/passes/TraceCalls.cpp index 01278c2e9e6..44bc16e95e6 100644 --- a/src/passes/TraceCalls.cpp +++ b/src/passes/TraceCalls.cpp @@ -124,10 +124,10 @@ struct TraceCalls : public Pass { bool addsEffects() override { return true; } void run(Module* module) override { - auto functionsDefinitions = getPassOptions().getArgument( - "trace-calls", - "TraceCalls usage: wasm-opt " - "--trace-calls=FUNCTION_TO_TRACE[:TRACER_NAME][,...]"); + auto functionsDefinitions = + getArgument("trace-calls", + "TraceCalls usage: wasm-opt " + "--trace-calls=FUNCTION_TO_TRACE[:TRACER_NAME][,...]"); auto tracedFunctions = parseArgument(functionsDefinitions); diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index b226d6ec9ad..ec6077941d4 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -73,6 +73,10 @@ std::vector PassRegistry::getRegisteredNames() { return ret; } +bool PassRegistry::containsPass(const std::string& name) { + return passInfos.count(name) > 0; +} + std::string PassRegistry::getPassDescription(std::string name) { assert(passInfos.find(name) != passInfos.end()); return passInfos[name].description; @@ -715,6 +719,15 @@ void PassRunner::addDefaultGlobalOptimizationPrePasses() { // which can lead to more opportunities for global effects to matter. } +void PassRunner::add(std::string passName, std::optional passArg) { + auto pass = PassRegistry::get()->createPass(passName); + if (passArg) { + pass->setPassArg(*passArg); + } + + doAdd(std::move(pass)); +} + void PassRunner::addDefaultGlobalOptimizationPostPasses() { if (options.optimizeLevel >= 2 || options.shrinkLevel >= 1) { addIfNoDWARFIssues("dae-optimizing"); @@ -1025,4 +1038,29 @@ bool PassRunner::shouldPreserveDWARF() { return true; } +bool Pass::hasArgument(const std::string& key) { + // An argument with the name of the pass is stored on the instance. Other + // arguments are in the global storage. + return key == name ? passArg.has_value() : getPassOptions().hasArgument(key); +} + +std::string Pass::getArgument(const std::string& key, + const std::string& errorTextIfMissing) { + if (!hasArgument(key)) { + Fatal() << errorTextIfMissing; + } + + return (key == name) ? *passArg + : getPassOptions().getArgument(key, errorTextIfMissing); +} + +std::string Pass::getArgumentOrDefault(const std::string& key, + const std::string& defaultValue) { + if (key == name) { + return passArg.value_or(defaultValue); + } + + return getPassOptions().getArgumentOrDefault(key, defaultValue); +} + } // namespace wasm diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h index af468769d69..f04b7321120 100644 --- a/src/tools/optimization-options.h +++ b/src/tools/optimization-options.h @@ -51,6 +51,9 @@ struct OptimizationOptions : public ToolOptions { // The name of the pass to run. std::string name; + // The main argument of the pass, if applicable. + std::optional argument; + // The optimize and shrink levels to run the pass with, if specified. If not // specified then the defaults are used. std::optional optimizeLevel; @@ -330,18 +333,47 @@ struct OptimizationOptions : public ToolOptions { // --foo --pass-arg=foo@ARG Options::Arguments::Optional, [this, p](Options*, const std::string& arg) { + PassInfo info(p); if (!arg.empty()) { - if (passOptions.arguments.count(p)) { - Fatal() << "Cannot pass multiple pass arguments to " << p; - } - passOptions.arguments[p] = arg; + info.argument = arg; } - passes.push_back(p); + + passes.push_back(info); }, PassRegistry::get()->isPassHidden(p)); } } + // Pass arguments with the same name as the pass are stored per-instance on + // PassInfo, while all other arguments are stored globally on + // passOptions.arguments (which is what the overriden method on ToolOptions + // does). + void addPassArg(const std::string& key, const std::string& value) override { + // Scan the current pass list for the last defined instance of a pass named + // like the argument under consideration. + for (auto i = passes.rbegin(); i != passes.rend(); i++) { + if (i->name != key) { + continue; + } + + if (i->argument.has_value()) { + Fatal() << i->name << " already set to " << *(i->argument); + } + + // Found? Store the argument value there and return. + i->argument = value; + return; + } + + // Not found? Store it globally if there is no pass with the same name. + if (!PassRegistry::get()->containsPass(key)) { + return ToolOptions::addPassArg(key, value); + } + + // Not found, but we have a pass with the same name? Bail out. + Fatal() << "can't set " << key << ": pass not enabled"; + } + bool runningDefaultOptimizationPasses() { for (auto& pass : passes) { if (pass.name == DEFAULT_OPT_PASSES) { @@ -393,7 +425,7 @@ struct OptimizationOptions : public ToolOptions { passRunner.options.shrinkLevel = passOptions.shrinkLevel; } else { // This is a normal pass. Add it to the queue for execution. - passRunner.add(pass.name); + passRunner.add(pass.name, pass.argument); // Normal passes do not set their own optimize/shrinkLevels. assert(!pass.optimizeLevel); diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h index 10a03acc785..c9d891a00bb 100644 --- a/src/tools/tool-options.h +++ b/src/tools/tool-options.h @@ -126,7 +126,10 @@ struct ToolOptions : public Options { .add("--pass-arg", "-pa", "An argument passed along to optimization passes being run. Must be " - "in the form KEY@VALUE", + "in the form KEY@VALUE. If KEY is the name of a pass then it " + "applies to the closest instance of that pass before us. If KEY is " + "not the name of a pass then it is a global option that applies to " + "all pass instances that read it.", ToolOptionsCategory, Options::Arguments::N, [this](Options*, const std::string& argument) { @@ -139,7 +142,8 @@ struct ToolOptions : public Options { key = argument.substr(0, colon); value = argument.substr(colon + 1); } - passOptions.arguments[key] = value; + + addPassArg(key, value); }) .add( "--closed-world", @@ -213,6 +217,12 @@ struct ToolOptions : public Options { module.features.disable(disabledFeatures); } + virtual void addPassArg(const std::string& key, const std::string& value) { + passOptions.arguments[key] = value; + } + + virtual ~ToolOptions() = default; + private: FeatureSet enabledFeatures = FeatureSet::Default; FeatureSet disabledFeatures = FeatureSet::None; diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index abb1646c173..eed26f1e15e 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -192,9 +192,8 @@ void getFunctionsToKeepAndSplit(Module& wasm, void writeSymbolMap(Module& wasm, std::string filename) { PassOptions options; - options.arguments["symbolmap"] = filename; PassRunner runner(&wasm, options); - runner.add("symbolmap"); + runner.add("symbolmap", filename); runner.run(); } diff --git a/test/lit/help/wasm-as.test b/test/lit/help/wasm-as.test index 114064576a2..3a863dbd6b4 100644 --- a/test/lit/help/wasm-as.test +++ b/test/lit/help/wasm-as.test @@ -121,7 +121,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-ctor-eval.test b/test/lit/help/wasm-ctor-eval.test index 93b5654ed60..2d57e3e8cc3 100644 --- a/test/lit/help/wasm-ctor-eval.test +++ b/test/lit/help/wasm-ctor-eval.test @@ -128,7 +128,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-dis.test b/test/lit/help/wasm-dis.test index 06dda9e96af..63c7f8bd0b1 100644 --- a/test/lit/help/wasm-dis.test +++ b/test/lit/help/wasm-dis.test @@ -114,7 +114,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-emscripten-finalize.test b/test/lit/help/wasm-emscripten-finalize.test index 1b31e1e44cf..c92960dfbeb 100644 --- a/test/lit/help/wasm-emscripten-finalize.test +++ b/test/lit/help/wasm-emscripten-finalize.test @@ -156,7 +156,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-merge.test b/test/lit/help/wasm-merge.test index 293bdbff041..fe3f1cdb29e 100644 --- a/test/lit/help/wasm-merge.test +++ b/test/lit/help/wasm-merge.test @@ -144,7 +144,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index 5b621caf5e1..66013f81aa8 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -733,7 +733,14 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to ;; CHECK-NEXT: optimization passes being run. -;; CHECK-NEXT: Must be in the form KEY@VALUE +;; CHECK-NEXT: Must be in the form KEY@VALUE. +;; CHECK-NEXT: If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest +;; CHECK-NEXT: instance of that pass before us. +;; CHECK-NEXT: If KEY is not the name of a pass +;; CHECK-NEXT: then it is a global option that +;; CHECK-NEXT: applies to all pass instances +;; CHECK-NEXT: that read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the ;; CHECK-NEXT: module does not inspect or diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 9f7caf98bee..c89baaf4a73 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -742,7 +742,14 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to ;; CHECK-NEXT: optimization passes being run. -;; CHECK-NEXT: Must be in the form KEY@VALUE +;; CHECK-NEXT: Must be in the form KEY@VALUE. +;; CHECK-NEXT: If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest +;; CHECK-NEXT: instance of that pass before us. +;; CHECK-NEXT: If KEY is not the name of a pass +;; CHECK-NEXT: then it is a global option that +;; CHECK-NEXT: applies to all pass instances +;; CHECK-NEXT: that read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the ;; CHECK-NEXT: module does not inspect or diff --git a/test/lit/help/wasm-reduce.test b/test/lit/help/wasm-reduce.test index 39795285537..cacf260fab5 100644 --- a/test/lit/help/wasm-reduce.test +++ b/test/lit/help/wasm-reduce.test @@ -150,7 +150,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test index c118d302dca..bc09796d77e 100644 --- a/test/lit/help/wasm-split.test +++ b/test/lit/help/wasm-split.test @@ -231,7 +231,12 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to optimization ;; CHECK-NEXT: passes being run. Must be in the form -;; CHECK-NEXT: KEY@VALUE +;; CHECK-NEXT: KEY@VALUE. If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest instance +;; CHECK-NEXT: of that pass before us. If KEY is not the +;; CHECK-NEXT: name of a pass then it is a global option +;; CHECK-NEXT: that applies to all pass instances that +;; CHECK-NEXT: read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the module does ;; CHECK-NEXT: not inspect or interact with GC and diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index ca731d27741..45bef7d7383 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -696,7 +696,14 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --pass-arg,-pa An argument passed along to ;; CHECK-NEXT: optimization passes being run. -;; CHECK-NEXT: Must be in the form KEY@VALUE +;; CHECK-NEXT: Must be in the form KEY@VALUE. +;; CHECK-NEXT: If KEY is the name of a pass +;; CHECK-NEXT: then it applies to the closest +;; CHECK-NEXT: instance of that pass before us. +;; CHECK-NEXT: If KEY is not the name of a pass +;; CHECK-NEXT: then it is a global option that +;; CHECK-NEXT: applies to all pass instances +;; CHECK-NEXT: that read it. ;; CHECK-NEXT: ;; CHECK-NEXT: --closed-world,-cw Assume code outside of the ;; CHECK-NEXT: module does not inspect or From 503fc4bb767d4f1861feba71b127799b89d9d663 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 15 Jul 2024 16:25:05 -0700 Subject: [PATCH 445/553] [NFC] Fix changelog order after #6687 (#6748) We made a release since it was written, which this is not included in. --- CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f7a3758141..4d37e89e367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,13 @@ full changeset diff at the end of each section. Current Trunk ------------- + - Passes can now receive individual pass arguments, that is --foo=A --foo=B for + a pass foo will run the pass twice (which was possible before) and will now + run it first with argument A and second with B. --pass-arg=foo@BAR will now + apply to the most recent --foo pass on the commandline, if foo is a pass + (while global pass arguments - that are not the name of a pass - remain, as + before, global for all passes). (#6687) + v118 ---- @@ -41,12 +48,6 @@ v118 - The build-time option to use legacy WasmGC opcodes is removed. - The strings in `string.const` instructions must now be valid WTF-8. - The `TraverseCalls` flag for `ExpressionRunner` is removed. - - Passes can now receive individual pass arguments, that is --foo=A --foo=B for - a pass foo will run the pass twice (which was possible before) and will now - run it first with argument A and second with B. --pass-arg=foo@BAR will now - apply to the most recent --foo pass on the commandline, if foo is a pass - (while global pass arguments - that are not the name of a pass - remain, as - before, global for all passes). v117 ---- From 5bdc0f40934a8b6b9887f345a5779dc8faa7660a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 15 Jul 2024 21:50:06 -0400 Subject: [PATCH 446/553] Simplify fuzzer generation of function references (#6745) When creating a reference to `func`, fix the probability of choosing to continue on to choose some function other than the last one rather than making it depend on the number of functions. Then, do not eagerly pick from the rest of the candidate functions. Instead, fall through to the more general logic that will already pick a random candidate function. Also move the logic for coming up with a concrete signature down to where it is needed. These simplifications will make it easier to update the code to handle shared types. --- src/tools/fuzzing/fuzzing.cpp | 28 ++++----- ...e-to-fuzz_all-features_metrics_noprint.txt | 58 ++++++++++--------- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 555de5db148..8e699fe1366 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2468,26 +2468,15 @@ Literal TranslateToFuzzReader::makeLiteral(Type type) { Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { auto heapType = type.getHeapType(); - if (heapType == HeapType::func) { - // First set to target to the last created function, and try to select - // among other existing function if possible. - Function* target = funcContext ? funcContext->func : nullptr; - // If there is no last function, and we have others, pick between them. Also - // pick between them with some random probability even if there is a last - // function. - if (!wasm.functions.empty() && (!target || !oneIn(wasm.functions.size()))) { - target = pick(wasm.functions).get(); - } - if (target) { + if (heapType.isBasic()) { + assert(heapType.getBasic(Unshared) == HeapType::func); + // With high probability, use the last created function if possible. + // Otherwise, continue on to select some other function. + if (funcContext && !oneIn(4)) { + auto* target = funcContext->func; return builder.makeRefFunc(target->name, target->type); } } - if (heapType == HeapType::func) { - // From here on we need a specific signature type, as we want to create a - // RefFunc or even a Function out of it. Pick an arbitrary one if we only - // had generic 'func' here. - heapType = Signature(Type::none, Type::none); - } // Look for a proper function starting from a random location, and loop from // there, wrapping around to 0. if (!wasm.functions.empty()) { @@ -2519,6 +2508,11 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { // here (we might end up recursing). Note that a trap in the function lets us // execute more code then the ref.as_non_null path just before us, which traps // even if we never call the function. + if (heapType.isBasic()) { + // We need a specific signature type to create a function. Pick an arbitrary + // signature if we only had generic 'func' here. + heapType = Signature(Type::none, Type::none); + } auto* body = heapType.getSignature().results == Type::none ? (Expression*)builder.makeNop() : (Expression*)builder.makeUnreachable(); diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index 57650cb2475..aba60b9da76 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -8,52 +8,54 @@ total [table-data] : 3 [tables] : 1 [tags] : 1 - [total] : 750 - [vars] : 30 + [total] : 846 + [vars] : 38 ArrayCopy : 1 - ArrayGet : 2 + ArrayGet : 3 ArrayLen : 5 ArrayNew : 24 ArrayNewFixed : 1 ArraySet : 1 AtomicCmpxchg : 1 AtomicFence : 1 + AtomicNotify : 1 AtomicRMW : 1 - Binary : 84 - Block : 58 - Break : 12 + Binary : 91 + Block : 75 + Break : 17 Call : 13 - Const : 175 - Drop : 2 - GlobalGet : 45 - GlobalSet : 20 + Const : 177 + Drop : 3 + GlobalGet : 50 + GlobalSet : 26 I31Get : 2 - If : 21 - Load : 20 - LocalGet : 70 - LocalSet : 46 - Loop : 7 + If : 26 + Load : 23 + LocalGet : 79 + LocalSet : 56 + Loop : 10 MemoryCopy : 1 - Nop : 11 - Pop : 3 - RefAs : 7 + Nop : 13 + Pop : 4 + RefAs : 16 RefEq : 1 RefFunc : 5 - RefI31 : 7 - RefIsNull : 3 - RefNull : 19 + RefI31 : 5 + RefIsNull : 2 + RefNull : 23 RefTest : 3 Return : 2 SIMDTernary : 1 - Select : 3 - Store : 1 - StringConst : 8 + Select : 4 + Store : 2 + StringConst : 6 StringEncode : 1 StringMeasure : 1 StringWTF16Get : 1 StructGet : 1 - StructNew : 21 - Try : 3 + StructNew : 14 + StructSet : 1 + Try : 4 TupleMake : 6 - Unary : 19 - Unreachable : 10 + Unary : 29 + Unreachable : 13 From 0964a6adabc6428f8b188ed7d8949c801adedf33 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 15 Jul 2024 22:01:06 -0400 Subject: [PATCH 447/553] [threads] Fix encoding of shared types (#6746) --- src/wasm-binary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 3e45b496925..8a6f825fffa 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -382,7 +382,7 @@ enum EncodedType { Array = -0x22, // 0x5e Sub = -0x30, // 0x50 SubFinal = -0x31, // 0x4f - Shared = -0x24, // 0x65 + Shared = -0x1b, // 0x65 // isorecursive recursion groups Rec = -0x32, // 0x4e // block_type From afef6d353c4283798b82e6cd4a6969fdfdc7cf7c Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 13:50:50 -0400 Subject: [PATCH 448/553] Remove extra space printed in empty structs (#6750) When we switched to the new type printing machinery, we inserted this extra space to minimize the diff in the test output compared with the previous type printer. Improve the quality of the printed output by removing it. --- src/wasm/wasm-type.cpp | 4 - test/example/typeinfo.txt | 4 +- test/lit/basic/shared-types.wast | 4 +- test/lit/cast-and-recast-tuple.wast | 4 +- test/lit/cast-and-recast.wast | 6 +- .../ctor-eval/ctor_after_serialization.wat | 4 +- test/lit/empty-elem.wast | 2 +- test/lit/fuzz-types.test | 4 +- test/lit/global-only.wast | 2 +- test/lit/isorecursive-good.wast | 2 +- test/lit/isorecursive-output-ordering.wast | 30 +-- test/lit/isorecursive-singleton-group.wast | 2 +- test/lit/isorecursive-whole-group.wast | 4 +- test/lit/passes/abstract-type-refining.wast | 50 ++--- test/lit/passes/dae-gc-refine-params.wast | 2 +- test/lit/passes/dae-gc-refine-return.wast | 2 +- test/lit/passes/dae-gc.wast | 2 +- test/lit/passes/global-refining.wast | 4 +- test/lit/passes/gto-removals.wast | 16 +- test/lit/passes/gufa-cast-all.wast | 4 +- test/lit/passes/gufa-refs.wast | 38 ++-- test/lit/passes/gufa-tnh-closed.wast | 30 +-- test/lit/passes/gufa-tnh.wast | 4 +- test/lit/passes/gufa-vs-cfp.wast | 2 +- test/lit/passes/heap2local.wast | 2 +- test/lit/passes/inlining_splitting.wast | 2 +- ...inlining_vacuum_optimize-instructions.wast | 2 +- test/lit/passes/j2cl.wast | 2 +- test/lit/passes/monomorphize-types.wast | 44 ++-- test/lit/passes/name-types.wast | 2 +- .../no-inline-monomorphize-inlining.wast | 8 +- test/lit/passes/optimize-casts-noeh.wast | 2 +- test/lit/passes/optimize-casts-tnh.wast | 2 +- test/lit/passes/optimize-casts.wast | 4 +- .../passes/optimize-instructions-gc-iit.wast | 8 +- test/lit/passes/precompute-gc.wast | 2 +- test/lit/passes/remove-unused-brs-gc.wast | 6 +- test/lit/passes/remove-unused-types.wast | 4 +- test/lit/passes/signature-refining.wast | 48 ++--- test/lit/passes/simplify-globals-gc.wast | 2 +- test/lit/passes/ssa.wast | 2 +- test/lit/passes/type-finalizing.wast | 12 +- test/lit/passes/type-merging-shared.wast | 6 +- test/lit/passes/type-merging-tnh.wast | 10 +- test/lit/passes/type-merging.wast | 18 +- test/lit/passes/type-refining.wast | 18 +- test/lit/passes/type-ssa.wast | 8 +- test/lit/passes/type-ssa_and_merging.wast | 6 +- test/lit/passes/unsubtyping-casts.wast | 50 ++--- test/lit/passes/unsubtyping.wast | 190 +++++++++--------- test/lit/passes/vacuum-gc.wast | 2 +- test/lit/select-gc.wat | 2 +- test/lit/subtype-chain.wast | 2 +- .../validation/closed-world-interface.wast | 2 +- test/lit/validation/shared-struct.wast | 2 +- test/lit/wat-kitchen-sink.wast | 4 +- test/passes/roundtrip_typenames_features.txt | 2 +- 57 files changed, 349 insertions(+), 353 deletions(-) diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 6328180f81d..adb2c7fa82c 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -2109,10 +2109,6 @@ TypePrinter::print(const Struct& struct_, print(struct_.fields[i]); os << ')'; } - // TODO: Remove this extra space kept to minimize test diffs. - if (struct_.fields.size() == 0) { - os << ' '; - } return os << ")"; } diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt index 5fff87f238c..cb545340779 100644 --- a/test/example/typeinfo.txt +++ b/test/example/typeinfo.txt @@ -12,7 +12,7 @@ i31 i31ref (ref i31) (func) -(type $struct.0 (struct )) +(type $struct.0 (struct)) (type $array.0 (array i32)) ;; Signature @@ -24,7 +24,7 @@ i31ref (ref null $func.0) ;; Struct -(type $struct.0 (struct )) +(type $struct.0 (struct)) (ref $struct.0) (ref null $struct.0) (type $struct.0 (struct (field i32) (field i64) (field (mut f32)) (field (mut f64)))) diff --git a/test/lit/basic/shared-types.wast b/test/lit/basic/shared-types.wast index 0bba2f05487..f74d0023fd4 100644 --- a/test/lit/basic/shared-types.wast +++ b/test/lit/basic/shared-types.wast @@ -8,9 +8,9 @@ ;; CHECK: (type $0 (func)) ;; CHECK: (rec - ;; CHECK-NEXT: (type $final (shared (struct ))) + ;; CHECK-NEXT: (type $final (shared (struct))) (type $final (shared (struct))) - ;; CHECK: (type $top (sub (shared (struct )))) + ;; CHECK: (type $top (sub (shared (struct)))) (type $top (sub (shared (struct)))) ;; CHECK: (type $mid (sub $top (shared (struct (field i32))))) (type $mid (sub $top (shared (struct i32)))) diff --git a/test/lit/cast-and-recast-tuple.wast b/test/lit/cast-and-recast-tuple.wast index 7f0886fce74..3febcbff7ef 100644 --- a/test/lit/cast-and-recast-tuple.wast +++ b/test/lit/cast-and-recast-tuple.wast @@ -10,9 +10,9 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ) diff --git a/test/lit/cast-and-recast.wast b/test/lit/cast-and-recast.wast index c25ccc69a98..a2fe4371146 100644 --- a/test/lit/cast-and-recast.wast +++ b/test/lit/cast-and-recast.wast @@ -10,11 +10,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; CHECK: (type $C (sub $B (struct ))) + ;; CHECK: (type $C (sub $B (struct))) (type $C (sub $B (struct))) ) diff --git a/test/lit/ctor-eval/ctor_after_serialization.wat b/test/lit/ctor-eval/ctor_after_serialization.wat index df37f7e8bb6..e3acfefe6c9 100644 --- a/test/lit/ctor-eval/ctor_after_serialization.wat +++ b/test/lit/ctor-eval/ctor_after_serialization.wat @@ -7,7 +7,7 @@ ;; contains the serialization of the struct.new instruction). (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) (export "new" (func $new)) @@ -43,7 +43,7 @@ ;; As above, but now there is an existing global with the name that we want to ;; use. We should not collide. - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) ;; CHECK: (type $1 (func (result (ref any)))) diff --git a/test/lit/empty-elem.wast b/test/lit/empty-elem.wast index 0eff01d3c97..0dec887d64f 100644 --- a/test/lit/empty-elem.wast +++ b/test/lit/empty-elem.wast @@ -6,7 +6,7 @@ ;; type, resulting in invalid modules. (module - ;; CHECK: (type $struct (sub (struct ))) + ;; CHECK: (type $struct (sub (struct))) (type $struct (sub (struct))) ;; CHECK: (type $array (sub (array (mut (ref null $struct))))) diff --git a/test/lit/fuzz-types.test b/test/lit/fuzz-types.test index 10d8fe3bc93..9c338f35e95 100644 --- a/test/lit/fuzz-types.test +++ b/test/lit/fuzz-types.test @@ -6,7 +6,7 @@ ;; CHECK-NEXT: (type $0 (sub (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) ;; CHECK-NEXT: (type $1 (sub (func (param (ref $1)) (result f64 (ref $0) f32 (ref null (shared eq)))))) ;; CHECK-NEXT: (type $2 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))))))) -;; CHECK-NEXT: (type $3 (sub (shared (struct )))) +;; CHECK-NEXT: (type $3 (sub (shared (struct)))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec ;; CHECK-NEXT: (type $4 (sub (array i32))) @@ -36,7 +36,7 @@ ;; CHECK-NEXT: (type $0 (sub (struct (field (mut i16)) (field (mut (ref $2))) (field (mut (ref null $2)))))) ;; CHECK-NEXT: (type $1 (sub (func (param (ref $1)) (result f64 (ref $0) f32 (ref null (shared eq)))))) ;; CHECK-NEXT: (type $2 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (mut (ref null $2))))))) -;; CHECK-NEXT: (type $3 (sub (shared (struct )))) +;; CHECK-NEXT: (type $3 (sub (shared (struct))) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (rec ;; CHECK-NEXT: (type $4 (sub (array i32))) diff --git a/test/lit/global-only.wast b/test/lit/global-only.wast index ac3e1ee8f4d..ca87ff36f11 100644 --- a/test/lit/global-only.wast +++ b/test/lit/global-only.wast @@ -6,7 +6,7 @@ ;; RUN: wasm-opt -all %s -S -o - | filecheck %s (module $parse - ;; CHECK: (type $t (struct )) + ;; CHECK: (type $t (struct)) (type $t (struct)) ;; CHECK: (global $g (ref null $t) (ref.null none)) (global $g (ref null $t) (ref.null $t)) diff --git a/test/lit/isorecursive-good.wast b/test/lit/isorecursive-good.wast index 43caeb7d1f2..373f64ac600 100644 --- a/test/lit/isorecursive-good.wast +++ b/test/lit/isorecursive-good.wast @@ -34,7 +34,7 @@ (type $final-func (sub final $sub-func (func (param (ref $super-array)) (result (ref $final-array))))) ) - ;; CHECK: (type $final-root (struct )) + ;; CHECK: (type $final-root (struct)) (type $final-root (sub final (struct))) ;; CHECK: (func $make-super-struct (type $6) (result (ref $super-struct)) diff --git a/test/lit/isorecursive-output-ordering.wast b/test/lit/isorecursive-output-ordering.wast index 54d99130172..b8d0a1c8ea4 100644 --- a/test/lit/isorecursive-output-ordering.wast +++ b/test/lit/isorecursive-output-ordering.wast @@ -9,22 +9,22 @@ (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $unused-6 (sub (struct ))) + ;; CHECK-NEXT: (type $unused-6 (sub (struct))) - ;; CHECK: (type $used-a-bit (sub (struct ))) + ;; CHECK: (type $used-a-bit (sub (struct))) ;; CHECK: (rec - ;; CHECK-NEXT: (type $unused-1 (sub (struct ))) + ;; CHECK-NEXT: (type $unused-1 (sub (struct))) (type $unused-1 (sub (struct))) - ;; CHECK: (type $unused-2 (sub (struct ))) + ;; CHECK: (type $unused-2 (sub (struct))) (type $unused-2 (sub (struct))) - ;; CHECK: (type $unused-3 (sub (struct ))) + ;; CHECK: (type $unused-3 (sub (struct))) (type $unused-3 (sub (struct))) - ;; CHECK: (type $unused-4 (sub (struct ))) + ;; CHECK: (type $unused-4 (sub (struct))) (type $unused-4 (sub (struct))) - ;; CHECK: (type $used-a-lot (sub (struct ))) + ;; CHECK: (type $used-a-lot (sub (struct))) (type $used-a-lot (sub (struct))) - ;; CHECK: (type $unused-5 (sub (struct ))) + ;; CHECK: (type $unused-5 (sub (struct))) (type $unused-5 (sub (struct))) ) @@ -47,20 +47,20 @@ (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $leaf (sub (struct ))) + ;; CHECK-NEXT: (type $leaf (sub (struct))) (type $leaf (sub (struct))) - ;; CHECK: (type $unused (sub (struct ))) + ;; CHECK: (type $unused (sub (struct))) (type $unused (sub (struct))) ) (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $shrub (sub $leaf (struct ))) + ;; CHECK-NEXT: (type $shrub (sub $leaf (struct))) - ;; CHECK: (type $used-a-ton (sub (struct ))) + ;; CHECK: (type $used-a-ton (sub (struct))) ;; CHECK: (rec - ;; CHECK-NEXT: (type $twig (sub (struct ))) + ;; CHECK-NEXT: (type $twig (sub (struct))) (type $twig (sub (struct))) ;; CHECK: (type $used-a-bit (sub (struct (field (ref $leaf))))) (type $used-a-bit (sub (struct (ref $leaf)))) @@ -73,9 +73,9 @@ (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $root (sub (struct ))) + ;; CHECK-NEXT: (type $root (sub (struct))) (type $root (sub (struct))) - ;; CHECK: (type $used-a-lot (sub $twig (struct ))) + ;; CHECK: (type $used-a-lot (sub $twig (struct))) (type $used-a-lot (sub $twig (struct))) ) diff --git a/test/lit/isorecursive-singleton-group.wast b/test/lit/isorecursive-singleton-group.wast index 80fa346c7ef..d68ef394d5c 100644 --- a/test/lit/isorecursive-singleton-group.wast +++ b/test/lit/isorecursive-singleton-group.wast @@ -10,7 +10,7 @@ (rec - ;; CHECK: (type $singleton (sub (struct ))) + ;; CHECK: (type $singleton (sub (struct))) (type $singleton (sub (struct))) ) diff --git a/test/lit/isorecursive-whole-group.wast b/test/lit/isorecursive-whole-group.wast index 3978a610c72..6bc6c443796 100644 --- a/test/lit/isorecursive-whole-group.wast +++ b/test/lit/isorecursive-whole-group.wast @@ -9,9 +9,9 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $used (sub (struct ))) + ;; CHECK-NEXT: (type $used (sub (struct))) (type $used (sub (struct))) - ;; CHECK: (type $unused (sub (struct ))) + ;; CHECK: (type $unused (sub (struct))) (type $unused (sub (struct))) ) diff --git a/test/lit/passes/abstract-type-refining.wast b/test/lit/passes/abstract-type-refining.wast index 0b2025e7beb..c0a2f12b3cf 100644 --- a/test/lit/passes/abstract-type-refining.wast +++ b/test/lit/passes/abstract-type-refining.wast @@ -14,25 +14,25 @@ ;; NO_TNH: (rec ;; NO_TNH-NEXT: (type $0 (func)) - ;; NO_TNH: (type $A (sub (struct ))) + ;; NO_TNH: (type $A (sub (struct))) (type $A (sub (struct))) ;; YESTNH: (rec ;; YESTNH-NEXT: (type $0 (func)) - ;; YESTNH: (type $B (sub (struct ))) - ;; NO_TNH: (type $B (sub $A (struct ))) + ;; YESTNH: (type $B (sub (struct))) + ;; NO_TNH: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; YESTNH: (type $C (sub $B (struct ))) - ;; NO_TNH: (type $C (sub $B (struct ))) + ;; YESTNH: (type $C (sub $B (struct))) + ;; NO_TNH: (type $C (sub $B (struct))) (type $C (sub $B (struct))) - ;; NO_TNH: (type $D (sub $C (struct ))) + ;; NO_TNH: (type $D (sub $C (struct))) (type $D (sub $C (struct))) - ;; YESTNH: (type $E (sub $C (struct ))) - ;; NO_TNH: (type $E (sub $D (struct ))) + ;; YESTNH: (type $E (sub $C (struct))) + ;; NO_TNH: (type $E (sub $D (struct))) (type $E (sub $D (struct))) ;; YESTNH: (type $4 (func (param anyref))) @@ -264,21 +264,21 @@ (module (rec ;; YESTNH: (rec - ;; YESTNH-NEXT: (type $A (sub (struct ))) + ;; YESTNH-NEXT: (type $A (sub (struct))) ;; NO_TNH: (rec - ;; NO_TNH-NEXT: (type $A (sub (struct ))) + ;; NO_TNH-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; YESTNH: (type $B1 (sub $A (struct ))) + ;; YESTNH: (type $B1 (sub $A (struct))) ;; YESTNH: (type $2 (func (param anyref))) - ;; YESTNH: (type $B (sub $A (struct ))) - ;; NO_TNH: (type $B1 (sub $A (struct ))) + ;; YESTNH: (type $B (sub $A (struct))) + ;; NO_TNH: (type $B1 (sub $A (struct))) ;; NO_TNH: (type $2 (func (param anyref))) - ;; NO_TNH: (type $B (sub $A (struct ))) + ;; NO_TNH: (type $B (sub $A (struct))) (type $B (sub $A (struct))) (type $B1 (sub $A (struct))) ;; this is a new type @@ -362,14 +362,14 @@ (module (rec ;; NO_TNH: (rec - ;; NO_TNH-NEXT: (type $A (sub (struct ))) + ;; NO_TNH-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) (type $B (sub $A (struct))) ;; YESTNH: (rec - ;; YESTNH-NEXT: (type $B1 (sub (struct ))) - ;; NO_TNH: (type $B1 (sub $A (struct ))) + ;; YESTNH-NEXT: (type $B1 (sub (struct))) + ;; NO_TNH: (type $B1 (sub $A (struct))) (type $B1 (sub $A (struct))) ;; this is a new type ) @@ -449,15 +449,15 @@ ;; A chain, $A :> $B :> $C, where we can optimize $A all the way to $C. (module ;; NO_TNH: (rec - ;; NO_TNH-NEXT: (type $A (sub (struct ))) + ;; NO_TNH-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; NO_TNH: (type $B (sub $A (struct ))) + ;; NO_TNH: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; YESTNH: (rec - ;; YESTNH-NEXT: (type $C (sub (struct ))) - ;; NO_TNH: (type $C (sub $B (struct ))) + ;; YESTNH-NEXT: (type $C (sub (struct))) + ;; NO_TNH: (type $C (sub $B (struct))) (type $C (sub $B (struct))) ;; YESTNH: (type $1 (func (param anyref))) @@ -824,17 +824,17 @@ ;; NO_TNH: (rec ;; NO_TNH-NEXT: (type $0 (func (param anyref))) - ;; NO_TNH: (type $A (sub (struct ))) + ;; NO_TNH: (type $A (sub (struct))) (type $A (sub (struct))) - ;; NO_TNH: (type $B (sub $A (struct ))) + ;; NO_TNH: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; YESTNH: (rec ;; YESTNH-NEXT: (type $0 (func (param anyref))) - ;; YESTNH: (type $C1 (sub (struct ))) - ;; NO_TNH: (type $C1 (sub $B (struct ))) + ;; YESTNH: (type $C1 (sub (struct))) + ;; NO_TNH: (type $C1 (sub $B (struct))) (type $C1 (sub $B (struct))) (type $C2 (sub $B (struct))) diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast index 78b732a3fd7..77766e18fcd 100644 --- a/test/lit/passes/dae-gc-refine-params.wast +++ b/test/lit/passes/dae-gc-refine-params.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s (module - ;; CHECK: (type $"{}" (sub (struct ))) + ;; CHECK: (type $"{}" (sub (struct))) (type $"{}" (sub (struct))) ;; CHECK: (type $"{i32}" (sub $"{}" (struct (field i32)))) diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast index 8e54a538ee2..1088cda25b1 100644 --- a/test/lit/passes/dae-gc-refine-return.wast +++ b/test/lit/passes/dae-gc-refine-return.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s (module - ;; CHECK: (type $"{}" (sub (struct ))) + ;; CHECK: (type $"{}" (sub (struct))) (type $"{}" (sub (struct))) ;; CHECK: (type $"return_{}" (func (result (ref $"{}")))) diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast index a5625b85227..9878230207f 100644 --- a/test/lit/passes/dae-gc.wast +++ b/test/lit/passes/dae-gc.wast @@ -2,7 +2,7 @@ ;; RUN: foreach %s %t wasm-opt -all --dae -S -o - | filecheck %s (module - ;; CHECK: (type $"{}" (struct )) + ;; CHECK: (type $"{}" (struct)) (type $"{}" (struct)) ;; CHECK: (func $foo (type $0) diff --git a/test/lit/passes/global-refining.wast b/test/lit/passes/global-refining.wast index 81459affec3..f1f6048f765 100644 --- a/test/lit/passes/global-refining.wast +++ b/test/lit/passes/global-refining.wast @@ -110,10 +110,10 @@ ;; CHECK: (type $0 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) ;; CLOSD: (type $0 (func)) - ;; CLOSD: (type $struct (struct )) + ;; CLOSD: (type $struct (struct)) (type $struct (struct)) (type $array (array i8)) diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index ad406bbda8d..1d662f0ac7e 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -6,7 +6,7 @@ ;; removed. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct (field (mut funcref))))) ;; CHECK: (type $1 (func (param (ref $struct)))) @@ -22,7 +22,7 @@ ;; A write does not keep a field from being removed. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct (field (mut funcref))))) ;; CHECK: (type $1 (func (param (ref $struct)))) @@ -53,7 +53,7 @@ ;; A new does not keep a field from being removed. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct (field (mut funcref))))) ;; CHECK: (type $1 (func (param (ref $struct)))) @@ -77,7 +77,7 @@ ;; A new_default does not keep a field from being removed. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct (field (mut funcref))))) ;; CHECK: (type $1 (func (param (ref $struct)))) @@ -770,10 +770,10 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $parent (sub (struct ))) + ;; CHECK-NEXT: (type $parent (sub (struct))) (type $parent (sub (struct (field i32)))) - ;; CHECK: (type $child2 (sub $parent (struct ))) + ;; CHECK: (type $child2 (sub $parent (struct))) ;; CHECK: (type $child1 (sub $parent (struct (field i32)))) (type $child1 (sub $parent (struct (field i32)))) @@ -802,7 +802,7 @@ ;; CHECK: (type $2 (func)) - ;; CHECK: (type $"{mut:i8}" (sub (struct ))) + ;; CHECK: (type $"{mut:i8}" (sub (struct))) (type $"{mut:i8}" (sub (struct (field (mut i8))))) ;; CHECK: (type $4 (func (param (ref null $"{mut:i8}")))) @@ -928,7 +928,7 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct (field anyref) (field i32) (field f32) (field f64)))) ;; CHECK: (type $1 (func (result (ref $struct)))) diff --git a/test/lit/passes/gufa-cast-all.wast b/test/lit/passes/gufa-cast-all.wast index 21103089dbb..c5b92ee89da 100644 --- a/test/lit/passes/gufa-cast-all.wast +++ b/test/lit/passes/gufa-cast-all.wast @@ -6,10 +6,10 @@ ;; CHECK: (type $none_=>_none (func)) (type $none_=>_none (func)) - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $3 (func (result i32))) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index f2feea228c2..d70de6a7a62 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -2,7 +2,7 @@ ;; RUN: foreach %s %t wasm-opt -all --gufa -S -o - | filecheck %s (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) @@ -361,7 +361,7 @@ ) (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -459,7 +459,7 @@ (module ;; CHECK: (type $0 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (global $A-null anyref (ref.null none)) @@ -569,7 +569,7 @@ (module ;; CHECK: (type $0 (func (param (ref any)) (result (ref any)))) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $2 (func (param i32) (result i32))) @@ -679,7 +679,7 @@ ;; As above, but using indirect calls. (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) @@ -811,7 +811,7 @@ ;; As above, but using call_ref. (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) @@ -923,7 +923,7 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct))) ;; CHECK: (type $parent (sub (struct (field (mut (ref null $struct)))))) @@ -931,7 +931,7 @@ ;; CHECK: (type $child (sub $parent (struct (field (mut (ref null $struct))) (field (mut (ref null $struct)))))) (type $child (sub $parent (struct (field (mut (ref null $struct))) (field (mut (ref null $struct)))))) - ;; CHECK: (type $unrelated (struct )) + ;; CHECK: (type $unrelated (struct)) (type $unrelated (struct)) ) @@ -1201,7 +1201,7 @@ ;; Exact types: Writes to the parent class do not confuse us. (module - ;; CHECK: (type $struct (sub (struct ))) + ;; CHECK: (type $struct (sub (struct))) (type $struct (sub (struct))) ;; CHECK: (type $parent (sub (struct (field (mut (ref null $struct)))))) (type $parent (sub (struct (field (mut (ref null $struct)))))) @@ -1557,7 +1557,7 @@ ;; CHECK: (type $4 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (func $func (type $4) @@ -1687,7 +1687,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) (type $storage (struct (field (mut (ref null any))))) @@ -1831,7 +1831,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) (type $storage (struct (field (mut (ref null any))))) @@ -1898,7 +1898,7 @@ ;; CHECK: (type $1 (func (param anyref))) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (tag $nothing (param anyref)) @@ -2132,7 +2132,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (tag $tag (param anyref anyref)) @@ -2207,7 +2207,7 @@ ) (module - ;; CHECK: (type $"{}" (sub (struct ))) + ;; CHECK: (type $"{}" (sub (struct))) (type $"{}" (sub (struct))) ;; CHECK: (type $1 (func (result (ref $"{}")))) @@ -2461,7 +2461,7 @@ ;; CHECK: (type $4 (func (param i32))) - ;; CHECK: (type $other (sub (struct ))) + ;; CHECK: (type $other (sub (struct))) (type $other (sub (struct))) ;; CHECK: (type $6 (func (result i32))) @@ -5922,10 +5922,10 @@ ) (module - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $2 (func (result (ref $A)))) @@ -6008,7 +6008,7 @@ ) (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) ;; CHECK: (type $1 (func)) diff --git a/test/lit/passes/gufa-tnh-closed.wast b/test/lit/passes/gufa-tnh-closed.wast index b55ae5ea600..4f593aea34b 100644 --- a/test/lit/passes/gufa-tnh-closed.wast +++ b/test/lit/passes/gufa-tnh-closed.wast @@ -296,13 +296,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y1 (sub $X (struct ))) + ;; CHECK: (type $Y1 (sub $X (struct))) (type $Y1 (sub $X (struct))) - ;; CHECK: (type $Y2 (sub $X (struct ))) + ;; CHECK: (type $Y2 (sub $X (struct))) (type $Y2 (sub $X (struct))) ;; CHECK: (type $A (func (param anyref))) @@ -421,13 +421,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y1 (sub $X (struct ))) + ;; CHECK: (type $Y1 (sub $X (struct))) (type $Y1 (sub $X (struct))) - ;; CHECK: (type $Y2 (sub $X (struct ))) + ;; CHECK: (type $Y2 (sub $X (struct))) (type $Y2 (sub $X (struct))) ;; CHECK: (type $A (func (param anyref anyref))) @@ -659,13 +659,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y1 (sub $X (struct ))) + ;; CHECK: (type $Y1 (sub $X (struct))) (type $Y1 (sub $X (struct))) - ;; CHECK: (type $Y2 (sub $X (struct ))) + ;; CHECK: (type $Y2 (sub $X (struct))) (type $Y2 (sub $X (struct))) ;; CHECK: (type $A (func (param anyref anyref anyref anyref anyref anyref))) @@ -885,13 +885,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y1 (sub $X (struct ))) + ;; CHECK: (type $Y1 (sub $X (struct))) (type $Y1 (sub $X (struct))) - ;; CHECK: (type $Y2 (sub $X (struct ))) + ;; CHECK: (type $Y2 (sub $X (struct))) (type $Y2 (sub $X (struct))) ;; CHECK: (type $A (func (param (ref null $X) (ref null $X) (ref null $X)))) @@ -1041,13 +1041,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y1 (sub $X (struct ))) + ;; CHECK: (type $Y1 (sub $X (struct))) (type $Y1 (sub $X (struct))) - ;; CHECK: (type $Y2 (sub $X (struct ))) + ;; CHECK: (type $Y2 (sub $X (struct))) (type $Y2 (sub $X (struct))) ;; CHECK: (type $A (func (param anyref))) diff --git a/test/lit/passes/gufa-tnh.wast b/test/lit/passes/gufa-tnh.wast index cb363c567ea..d276421f888 100644 --- a/test/lit/passes/gufa-tnh.wast +++ b/test/lit/passes/gufa-tnh.wast @@ -1980,10 +1980,10 @@ (module ;; CHECK: (type $0 (func)) - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $3 (func (param (ref null $A)))) diff --git a/test/lit/passes/gufa-vs-cfp.wast b/test/lit/passes/gufa-vs-cfp.wast index cb3aeaa227b..45f111cb226 100644 --- a/test/lit/passes/gufa-vs-cfp.wast +++ b/test/lit/passes/gufa-vs-cfp.wast @@ -2348,7 +2348,7 @@ ) (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) (type $B (struct (ref $A))) diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index f00cb60e2da..2ce3e12dd88 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2994,7 +2994,7 @@ ;; CHECK: (type $7 (struct (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)))) - ;; CHECK: (type $8 (struct )) + ;; CHECK: (type $8 (struct)) ;; CHECK: (type $9 (struct (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)))) diff --git a/test/lit/passes/inlining_splitting.wast b/test/lit/passes/inlining_splitting.wast index b34f74cf4f5..4d944d454f1 100644 --- a/test/lit/passes/inlining_splitting.wast +++ b/test/lit/passes/inlining_splitting.wast @@ -11,7 +11,7 @@ ;; CHECK: (type $3 (func (param anyref))) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $5 (func (param i64 i32 f64))) diff --git a/test/lit/passes/inlining_vacuum_optimize-instructions.wast b/test/lit/passes/inlining_vacuum_optimize-instructions.wast index db681ef69b6..165036f4d5e 100644 --- a/test/lit/passes/inlining_vacuum_optimize-instructions.wast +++ b/test/lit/passes/inlining_vacuum_optimize-instructions.wast @@ -11,7 +11,7 @@ ;; which is temporarily inconsistent. We must be careful to avoid confusion ;; there. (module - ;; CHECK: (type $B (sub (struct ))) + ;; CHECK: (type $B (sub (struct))) (type $B (sub (struct ))) ;; CHECK: (type $A (sub (struct (field (ref null $B))))) (type $A (sub (struct (field (ref null $B))))) diff --git a/test/lit/passes/j2cl.wast b/test/lit/passes/j2cl.wast index b8081d8b22c..4fe661e5c96 100644 --- a/test/lit/passes/j2cl.wast +++ b/test/lit/passes/j2cl.wast @@ -71,7 +71,7 @@ ;; Fields initialized to a non-default value shouldn't be hoisted. (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) ;; CHECK: (type $1 (func)) diff --git a/test/lit/passes/monomorphize-types.wast b/test/lit/passes/monomorphize-types.wast index f98fb08becc..49ae8353abf 100644 --- a/test/lit/passes/monomorphize-types.wast +++ b/test/lit/passes/monomorphize-types.wast @@ -7,11 +7,11 @@ ;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL (module - ;; ALWAYS: (type $A (sub (struct ))) - ;; CAREFUL: (type $A (sub (struct ))) + ;; ALWAYS: (type $A (sub (struct))) + ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) - ;; ALWAYS: (type $B (sub $A (struct ))) - ;; CAREFUL: (type $B (sub $A (struct ))) + ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; ALWAYS: (type $2 (func (param (ref $A)))) @@ -128,13 +128,13 @@ ;; As above, but now the refinable function uses the local in a way that ;; requires a fixup. - ;; ALWAYS: (type $A (sub (struct ))) + ;; ALWAYS: (type $A (sub (struct))) ;; CAREFUL: (type $0 (func)) - ;; CAREFUL: (type $A (sub (struct ))) + ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) - ;; ALWAYS: (type $B (sub $A (struct ))) - ;; CAREFUL: (type $B (sub $A (struct ))) + ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) @@ -208,21 +208,21 @@ (module ;; Multiple refinings of the same function, and of different functions. - ;; ALWAYS: (type $A (sub (struct ))) + ;; ALWAYS: (type $A (sub (struct))) ;; CAREFUL: (type $0 (func)) - ;; CAREFUL: (type $A (sub (struct ))) + ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) - ;; ALWAYS: (type $B (sub $A (struct ))) - ;; CAREFUL: (type $B (sub $A (struct ))) + ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; ALWAYS: (type $2 (func)) - ;; ALWAYS: (type $C (sub $B (struct ))) + ;; ALWAYS: (type $C (sub $B (struct))) ;; CAREFUL: (type $3 (func (param (ref $A)))) - ;; CAREFUL: (type $C (sub $B (struct ))) + ;; CAREFUL: (type $C (sub $B (struct))) (type $C (sub $B (struct))) ;; ALWAYS: (type $4 (func (param (ref $A)))) @@ -343,12 +343,12 @@ ;; A case where even CAREFUL mode will monomorphize, as it helps the target ;; function get optimized better. - ;; ALWAYS: (type $A (sub (struct ))) - ;; CAREFUL: (type $A (sub (struct ))) + ;; ALWAYS: (type $A (sub (struct))) + ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) - ;; ALWAYS: (type $B (sub $A (struct ))) - ;; CAREFUL: (type $B (sub $A (struct ))) + ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; ALWAYS: (type $2 (func (param (ref $B)))) @@ -578,15 +578,15 @@ (module ;; Test that we avoid recursive calls. - ;; ALWAYS: (type $A (sub (struct ))) - ;; CAREFUL: (type $A (sub (struct ))) + ;; ALWAYS: (type $A (sub (struct))) + ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) ;; ALWAYS: (type $1 (func (param (ref $A)))) - ;; ALWAYS: (type $B (sub $A (struct ))) + ;; ALWAYS: (type $B (sub $A (struct))) ;; CAREFUL: (type $1 (func (param (ref $A)))) - ;; CAREFUL: (type $B (sub $A (struct ))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) diff --git a/test/lit/passes/name-types.wast b/test/lit/passes/name-types.wast index b08d36ca2fb..bb31ffc8230 100644 --- a/test/lit/passes/name-types.wast +++ b/test/lit/passes/name-types.wast @@ -6,7 +6,7 @@ (type $obnoxious-super-long-type-name_____________________________1 (struct)) ;; A reasonable name that will be kept. - ;; CHECK: (type $type_1 (struct )) + ;; CHECK: (type $type_1 (struct)) ;; CHECK: (type $reasonable-name (struct (field i32))) (type $reasonable-name (struct (field i32))) diff --git a/test/lit/passes/no-inline-monomorphize-inlining.wast b/test/lit/passes/no-inline-monomorphize-inlining.wast index 716d0beda50..b5dc2ed39a9 100644 --- a/test/lit/passes/no-inline-monomorphize-inlining.wast +++ b/test/lit/passes/no-inline-monomorphize-inlining.wast @@ -11,12 +11,12 @@ ;; RUN: foreach %s %t wasm-opt --monomorphize-always --inlining --optimize-level=3 -all -S -o - | filecheck %s --check-prefix YESINLINE (module - ;; NO_INLINE: (type $A (sub (struct ))) - ;; YESINLINE: (type $A (sub (struct ))) + ;; NO_INLINE: (type $A (sub (struct))) + ;; YESINLINE: (type $A (sub (struct))) (type $A (sub (struct))) - ;; NO_INLINE: (type $B (sub $A (struct ))) - ;; YESINLINE: (type $B (sub $A (struct ))) + ;; NO_INLINE: (type $B (sub $A (struct))) + ;; YESINLINE: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; NO_INLINE: (type $2 (func)) diff --git a/test/lit/passes/optimize-casts-noeh.wast b/test/lit/passes/optimize-casts-noeh.wast index 351c2fd4ba5..3cee5f3d441 100644 --- a/test/lit/passes/optimize-casts-noeh.wast +++ b/test/lit/passes/optimize-casts-noeh.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s --optimize-casts --enable-reference-types --enable-gc --enable-tail-call -S -o - | filecheck %s (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) ;; CHECK: (func $yes-past-call (type $1) (param $x (ref struct)) diff --git a/test/lit/passes/optimize-casts-tnh.wast b/test/lit/passes/optimize-casts-tnh.wast index a039947057b..ed8951e8f14 100644 --- a/test/lit/passes/optimize-casts-tnh.wast +++ b/test/lit/passes/optimize-casts-tnh.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s --optimize-casts -all -tnh -S -o - | filecheck %s (module - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) ;; CHECK: (global $a (mut i32) (i32.const 0)) diff --git a/test/lit/passes/optimize-casts.wast b/test/lit/passes/optimize-casts.wast index a10540f5de0..acf8fc7b425 100644 --- a/test/lit/passes/optimize-casts.wast +++ b/test/lit/passes/optimize-casts.wast @@ -2,10 +2,10 @@ ;; RUN: wasm-opt %s --optimize-casts -all -S -o - | filecheck %s (module - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $void (func)) diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast index df225a8c787..4b9c46179a7 100644 --- a/test/lit/passes/optimize-instructions-gc-iit.wast +++ b/test/lit/passes/optimize-instructions-gc-iit.wast @@ -200,9 +200,9 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) ;; TNH: (rec - ;; TNH-NEXT: (type $A (sub (struct ))) + ;; TNH-NEXT: (type $A (sub (struct))) (type $A (sub (struct ))) ;; CHECK: (type $B (sub $A (struct (field (ref null $A))))) ;; TNH: (type $B (sub $A (struct (field (ref null $A))))) @@ -210,8 +210,8 @@ ;; CHECK: (type $C (sub $B (struct (field (ref null $D))))) ;; TNH: (type $C (sub $B (struct (field (ref null $D))))) (type $C (sub $B (struct (field (ref null $D))))) - ;; CHECK: (type $D (sub $A (struct ))) - ;; TNH: (type $D (sub $A (struct ))) + ;; CHECK: (type $D (sub $A (struct))) + ;; TNH: (type $D (sub $A (struct))) (type $D (sub $A (struct ))) ) diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 2b16cb43f95..fc4cc7c2ee9 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -4,7 +4,7 @@ ;; RUN: | filecheck %s (module - ;; CHECK: (type $empty (struct )) + ;; CHECK: (type $empty (struct)) (type $empty (struct)) ;; CHECK: (type $struct (struct (field (mut i32)))) diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast index 9dc871e326b..115002e8903 100644 --- a/test/lit/passes/remove-unused-brs-gc.wast +++ b/test/lit/passes/remove-unused-brs-gc.wast @@ -5,11 +5,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) (type $struct (sub (struct))) - ;; CHECK: (type $struct2 (struct )) + ;; CHECK: (type $struct2 (struct)) (type $struct2 (struct)) - ;; CHECK: (type $substruct (sub $struct (struct ))) + ;; CHECK: (type $substruct (sub $struct (struct))) (type $substruct (sub $struct (struct))) ) diff --git a/test/lit/passes/remove-unused-types.wast b/test/lit/passes/remove-unused-types.wast index afcafe8cd82..859290b6ea0 100644 --- a/test/lit/passes/remove-unused-types.wast +++ b/test/lit/passes/remove-unused-types.wast @@ -7,13 +7,13 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $mutually-used-2 (struct (field (ref null $mutually-used-1)))) - ;; CHECK: (type $indirectly-used (struct )) + ;; CHECK: (type $indirectly-used (struct)) ;; CHECK: (type $mutually-used-1 (struct (field (ref null $mutually-used-2)))) ;; CHECK: (type $directly-used (struct (field (ref null $indirectly-used)))) - ;; CHECK: (type $used (struct )) + ;; CHECK: (type $used (struct)) (type $used (struct)) (type $unused (struct)) ) diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index 215c4e9c438..fdddbe4ed8f 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -8,7 +8,7 @@ ;; on the function (which are derived from the heap type). ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -38,7 +38,7 @@ ;; As above, but the call is via call_ref. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -74,7 +74,7 @@ ;; is a nullable eqref. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -121,11 +121,11 @@ (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (sub (struct ))) + ;; CHECK-NEXT: (type $struct (sub (struct))) - ;; CHECK: (type $struct-sub2 (sub $struct (struct ))) + ;; CHECK: (type $struct-sub2 (sub $struct (struct))) - ;; CHECK: (type $struct-sub1 (sub $struct (struct ))) + ;; CHECK: (type $struct-sub1 (sub $struct (struct))) ;; CHECK: (type $3 (func)) @@ -174,7 +174,7 @@ ;; updated, though, as they share a heap type. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -277,7 +277,7 @@ ;; param to be $struct. ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -366,7 +366,7 @@ ;; Test multiple fields in multiple types. (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -447,7 +447,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) (table 1 1 anyref) @@ -477,7 +477,7 @@ ;; allows us to refine (but the new type must be nullable). ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) ;; CHECK: (type $1 (func)) @@ -519,7 +519,7 @@ ;; CHECK: (type $sig-cannot-refine (sub (func (result (ref func))))) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; This signature has a single function using it, which returns a more @@ -625,7 +625,7 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $struct (struct )) + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct)) ;; This signature has multiple functions using it, and some of them have nulls @@ -684,7 +684,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) (type $sig (sub (func (param anyref)))) @@ -728,7 +728,7 @@ ) (module - ;; CHECK: (type $"{}" (struct )) + ;; CHECK: (type $"{}" (struct)) (type $"{}" (struct)) ;; CHECK: (type $1 (func (param (ref $"{}") i32))) @@ -780,7 +780,7 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (import "a" "b" (func $import (type $0) (param structref))) @@ -913,13 +913,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; CHECK: (type $C (sub $B (struct ))) + ;; CHECK: (type $C (sub $B (struct))) (type $C (sub $B (struct))) ;; CHECK: (type $return_A_2 (func (result (ref $C)))) @@ -1013,13 +1013,13 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B1 (sub $A (struct ))) + ;; CHECK: (type $B1 (sub $A (struct))) (type $B1 (sub $A (struct))) - ;; CHECK: (type $B2 (sub $A (struct ))) + ;; CHECK: (type $B2 (sub $A (struct))) (type $B2 (sub $A (struct))) ) @@ -1070,10 +1070,10 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $0 (func (param (ref $B)))) - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ) diff --git a/test/lit/passes/simplify-globals-gc.wast b/test/lit/passes/simplify-globals-gc.wast index 97063a1a1b1..a24f769d258 100644 --- a/test/lit/passes/simplify-globals-gc.wast +++ b/test/lit/passes/simplify-globals-gc.wast @@ -32,7 +32,7 @@ ) (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct )) ;; CHECK: (type $1 (func (result anyref))) diff --git a/test/lit/passes/ssa.wast b/test/lit/passes/ssa.wast index c5b92db81c2..68b85360719 100644 --- a/test/lit/passes/ssa.wast +++ b/test/lit/passes/ssa.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s -all --ssa -S -o - | filecheck %s (module - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct )) ;; CHECK: (func $foo (type $1) diff --git a/test/lit/passes/type-finalizing.wast b/test/lit/passes/type-finalizing.wast index d8265fe049d..6897c6abf82 100644 --- a/test/lit/passes/type-finalizing.wast +++ b/test/lit/passes/type-finalizing.wast @@ -58,17 +58,17 @@ (module (rec ;; UNFINAL: (rec - ;; UNFINAL-NEXT: (type $parent (sub (struct ))) + ;; UNFINAL-NEXT: (type $parent (sub (struct))) ;; DOFINAL: (rec - ;; DOFINAL-NEXT: (type $parent (sub (struct ))) + ;; DOFINAL-NEXT: (type $parent (sub (struct))) (type $parent (sub (struct))) - ;; UNFINAL: (type $child-open (sub $parent (struct ))) - ;; DOFINAL: (type $child-open (sub final $parent (struct ))) + ;; UNFINAL: (type $child-open (sub $parent (struct))) + ;; DOFINAL: (type $child-open (sub final $parent (struct))) (type $child-open (sub $parent (struct))) - ;; UNFINAL: (type $child-final (sub $parent (struct ))) - ;; DOFINAL: (type $child-final (sub final $parent (struct ))) + ;; UNFINAL: (type $child-final (sub $parent (struct))) + ;; DOFINAL: (type $child-final (sub final $parent (struct))) (type $child-final (sub final $parent (struct))) ) diff --git a/test/lit/passes/type-merging-shared.wast b/test/lit/passes/type-merging-shared.wast index e0281507942..fb7fa89b7a5 100644 --- a/test/lit/passes/type-merging-shared.wast +++ b/test/lit/passes/type-merging-shared.wast @@ -10,9 +10,9 @@ ;; CHECK: (type $B (array i8)) - ;; CHECK: (type $A' (shared (struct ))) + ;; CHECK: (type $A' (shared (struct))) - ;; CHECK: (type $A (struct )) + ;; CHECK: (type $A (struct)) (type $A (struct)) (type $A' (shared (struct))) (type $B (array i8)) @@ -47,7 +47,7 @@ ;; CHECK: (type $B (shared (array i8))) - ;; CHECK: (type $A (shared (struct ))) + ;; CHECK: (type $A (shared (struct))) (type $A (shared (struct))) (type $A' (shared (struct))) (type $B (shared (array i8))) diff --git a/test/lit/passes/type-merging-tnh.wast b/test/lit/passes/type-merging-tnh.wast index ee0603fa68b..ebb2f98b79f 100644 --- a/test/lit/passes/type-merging-tnh.wast +++ b/test/lit/passes/type-merging-tnh.wast @@ -4,7 +4,7 @@ ;; ref.cast does not inhibit merging if traps never happen. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) (type $B (sub $A (struct))) @@ -25,9 +25,9 @@ ;; Check that a ref.test still inhibits merging with -tnh. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $2 (func (param (ref $A)) (result i32))) @@ -47,9 +47,9 @@ ;; Check that a br_on_cast still inhibits merging with -tnh. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $2 (func (param (ref $A)) (result (ref $B)))) diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index b9fcd9c0135..fcf3f4332a6 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -157,7 +157,7 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) (type $Y (sub $X (struct))) ;; CHECK: (type $A (sub (struct (field (ref null $X))))) @@ -580,7 +580,7 @@ ;; CHECK: (type $D' (sub $C (struct (field (ref $A)) (field i32) (field i32)))) - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) (type $A' (sub $A (struct))) @@ -625,7 +625,7 @@ ;; Check that we refinalize properly. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) (type $B (sub $A (struct))) @@ -844,12 +844,12 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $X (struct (field (ref $A)))) (type $X (struct (ref $B))) - ;; CHECK: (type $A' (struct )) + ;; CHECK: (type $A' (struct)) (type $A' (struct)) ) ;; CHECK: (type $3 (func)) @@ -1022,9 +1022,9 @@ ;; Check that a ref.test inhibits merging (ref.cast is already checked above). (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $2 (func (param (ref $A)) (result i32))) @@ -1044,9 +1044,9 @@ ;; Check that a br_on_cast inhibits merging. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct ))) + ;; CHECK-NEXT: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $B (sub $A (struct ))) + ;; CHECK: (type $B (sub $A (struct))) (type $B (sub $A (struct))) ;; CHECK: (type $2 (func (param (ref $A)) (result (ref $B)))) diff --git a/test/lit/passes/type-refining.wast b/test/lit/passes/type-refining.wast index ebff9b2cd52..002b1c07830 100644 --- a/test/lit/passes/type-refining.wast +++ b/test/lit/passes/type-refining.wast @@ -459,10 +459,10 @@ ;; CHECK: (type $B (sub $A (struct (field (ref $Y))))) - ;; CHECK: (type $X (sub (struct ))) + ;; CHECK: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) (type $A (sub (struct (field (ref $X))))) @@ -509,10 +509,10 @@ (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) ;; CHECK: (type $A (sub (struct (field (ref $X))))) @@ -542,14 +542,14 @@ ) (module - ;; CHECK: (type $X (sub (struct ))) + ;; CHECK: (type $X (sub (struct))) (type $X (sub (struct))) ;; CHECK: (type $1 (func)) ;; CHECK: (type $A (sub (struct (field (ref $X))))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) (type $A (sub (struct (field (ref $X))))) @@ -819,7 +819,7 @@ ;; -> Leaf2-Outer[Leaf2-Inner] ;; CHECK: (rec - ;; CHECK-NEXT: (type $Root-Inner (sub (struct ))) + ;; CHECK-NEXT: (type $Root-Inner (sub (struct))) (type $Root-Inner (sub (struct))) ;; CHECK: (type $Leaf1-Inner (sub $Root-Inner (struct (field i32)))) @@ -831,7 +831,7 @@ ;; CHECK: (type $Leaf2-Outer (sub $Root-Outer (struct (field (ref $Leaf2-Inner))))) - ;; CHECK: (type $Leaf2-Inner (sub $Root-Inner (struct ))) + ;; CHECK: (type $Leaf2-Inner (sub $Root-Inner (struct))) (type $Leaf2-Inner (sub $Root-Inner (struct ))) (type $Root-Outer (sub (struct (field (ref $Root-Inner))))) @@ -1147,7 +1147,7 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $A (struct (field (ref $B)))) (type $A (struct (field (ref struct)))) - ;; CHECK: (type $B (struct )) + ;; CHECK: (type $B (struct)) (type $B (struct)) ) diff --git a/test/lit/passes/type-ssa.wast b/test/lit/passes/type-ssa.wast index 277e2a2ff1b..4cc5f6494bf 100644 --- a/test/lit/passes/type-ssa.wast +++ b/test/lit/passes/type-ssa.wast @@ -366,10 +366,10 @@ ;; turn into a simple Literal). (We do optimize $empty and generate $empty$1, ;; but that is not important here.) (module - ;; CHECK: (type $empty (sub (struct ))) + ;; CHECK: (type $empty (sub (struct))) (type $empty (sub (struct))) - ;; CHECK: (type $empty_1 (sub $empty (struct ))) + ;; CHECK: (type $empty_1 (sub $empty (struct))) ;; CHECK: (type $2 (func (param anyref))) @@ -452,10 +452,10 @@ ) (module - ;; CHECK: (type $A (sub (struct ))) + ;; CHECK: (type $A (sub (struct))) (type $A (sub (struct))) - ;; CHECK: (type $A_1 (sub $A (struct ))) + ;; CHECK: (type $A_1 (sub $A (struct))) ;; CHECK: (type $2 (func (result (ref $A)))) diff --git a/test/lit/passes/type-ssa_and_merging.wast b/test/lit/passes/type-ssa_and_merging.wast index 8928820bfcd..8e84cf5c489 100644 --- a/test/lit/passes/type-ssa_and_merging.wast +++ b/test/lit/passes/type-ssa_and_merging.wast @@ -16,15 +16,15 @@ ;; YES: (rec ;; YES-NEXT: (type $1 (func (param (ref $A)))) - ;; YES: (type $A (sub (struct ))) + ;; YES: (type $A (sub (struct))) (type $A (sub (struct (field (mut i32))))) ;; NOP: (type $2 (func (result i32))) ;; NOP: (import "a" "b" (func $import (type $2) (result i32))) - ;; YES: (type $A_2 (sub $A (struct ))) + ;; YES: (type $A_2 (sub $A (struct))) - ;; YES: (type $A_1 (sub $A (struct ))) + ;; YES: (type $A_1 (sub $A (struct))) ;; YES: (import "a" "b" (func $import (type $0) (result i32))) (import "a" "b" (func $import (result i32))) diff --git a/test/lit/passes/unsubtyping-casts.wast b/test/lit/passes/unsubtyping-casts.wast index 8f0f66ef2e1..95394bdd05d 100644 --- a/test/lit/passes/unsubtyping-casts.wast +++ b/test/lit/passes/unsubtyping-casts.wast @@ -3,7 +3,7 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) (type $mid (sub $top (struct))) (type $bot (sub $mid (struct))) @@ -31,11 +31,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub $mid (struct ))) + ;; CHECK: (type $bot (sub $mid (struct))) (type $bot (sub $mid (struct))) ;; CHECK: (type $3 (func)) @@ -69,11 +69,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub $mid (struct ))) + ;; CHECK: (type $bot (sub $mid (struct))) (type $bot (sub $mid (struct))) ;; CHECK: (type $3 (func)) @@ -106,11 +106,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub $mid (struct ))) + ;; CHECK: (type $bot (sub $mid (struct))) (type $bot (sub $mid (struct))) ;; CHECK: (type $3 (func)) @@ -153,11 +153,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub $mid (struct ))) + ;; CHECK: (type $bot (sub $mid (struct))) (type $bot (sub $mid (struct))) ;; CHECK: (type $3 (func)) @@ -272,11 +272,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub (struct ))) + ;; CHECK: (type $mid (sub (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub $mid (struct ))) + ;; CHECK: (type $bot (sub $mid (struct))) (type $bot (sub $mid (struct))) ;; CHECK: (type $3 (func)) @@ -312,11 +312,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub (struct ))) + ;; CHECK: (type $bot (sub (struct))) (type $bot (sub $mid (struct))) ) @@ -381,11 +381,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $top (sub (struct ))) + ;; CHECK-NEXT: (type $top (sub (struct))) (type $top (sub (struct))) - ;; CHECK: (type $mid (sub $top (struct ))) + ;; CHECK: (type $mid (sub $top (struct))) (type $mid (sub $top (struct))) - ;; CHECK: (type $bot (sub (struct ))) + ;; CHECK: (type $bot (sub (struct))) (type $bot (sub $mid (struct))) ) @@ -478,11 +478,11 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $topC (sub (struct ))) + ;; CHECK-NEXT: (type $topC (sub (struct))) (type $topC (sub (struct))) - ;; CHECK: (type $midC (sub $topC (struct ))) + ;; CHECK: (type $midC (sub $topC (struct))) (type $midC (sub $topC (struct))) - ;; CHECK: (type $botC (sub $midC (struct ))) + ;; CHECK: (type $botC (sub $midC (struct))) (type $botC (sub $midC (struct))) ;; CHECK: (type $topB (sub (struct (field (ref null $topC))))) diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index 65d4d6a4847..5181b9a1cdd 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -61,9 +61,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; A function body requires subtyping @@ -79,9 +79,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; A global initializer requires subtyping @@ -91,11 +91,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) - ;; CHECK: (type $subsub (sub $sub (struct ))) + ;; CHECK: (type $subsub (sub $sub (struct))) (type $subsub (sub $sub (struct))) ;; CHECK: (table $t 1 1 (ref null $super)) @@ -109,9 +109,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) ;; CHECK: (type $A (sub (struct (field (ref null $X))))) @@ -126,9 +126,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) ;; CHECK: (type $A (sub (array (ref null $X)))) @@ -146,14 +146,14 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) - ;; CHECK: (type $X' (sub (struct ))) + ;; CHECK: (type $X' (sub (struct))) (type $X' (sub (struct))) - ;; CHECK: (type $Y' (sub $X' (struct ))) + ;; CHECK: (type $Y' (sub $X' (struct))) (type $Y' (sub $X' (struct))) ;; CHECK: (type $A (sub (func (param (ref $Y')) (result (ref $X))))) @@ -176,9 +176,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -216,9 +216,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $opt (sub (struct (field i32)))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $opt (sub $super (struct i32))) @@ -264,9 +264,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -302,9 +302,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -328,9 +328,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -370,9 +370,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -412,9 +412,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func (param (ref $super)))) @@ -434,9 +434,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func (result (ref $sub)))) @@ -461,9 +461,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func (param (ref $super)))) @@ -488,9 +488,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func (result (ref $sub)))) @@ -541,9 +541,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -565,9 +565,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -593,9 +593,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -618,11 +618,11 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) ;; CHECK: (type $sub2 (sub $super (struct (field i32)))) - ;; CHECK: (type $sub1 (sub $super (struct ))) + ;; CHECK: (type $sub1 (sub $super (struct))) (type $sub1 (sub $super (struct))) (type $sub2 (sub $super (struct i32))) @@ -651,9 +651,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func (result (ref $super)))) @@ -673,9 +673,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $sub (sub (struct ))) + ;; CHECK-NEXT: (type $sub (sub (struct))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) (type $sub (sub $super (struct))) @@ -697,14 +697,14 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $super2 (sub (struct ))) + ;; CHECK-NEXT: (type $super2 (sub (struct))) - ;; CHECK: (type $sub2 (sub $super2 (struct ))) + ;; CHECK: (type $sub2 (sub $super2 (struct))) - ;; CHECK: (type $super1 (sub (struct ))) + ;; CHECK: (type $super1 (sub (struct))) (type $super1 (sub (struct))) (type $super2 (sub (struct))) - ;; CHECK: (type $sub1 (sub $super1 (struct ))) + ;; CHECK: (type $sub1 (sub $super1 (struct))) (type $sub1 (sub $super1 (struct))) (type $sub2 (sub $super2 (struct))) ) @@ -732,9 +732,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -759,9 +759,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -790,9 +790,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $0 (func)) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (table $super 1 1 (ref null $super)) @@ -820,9 +820,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -856,9 +856,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -892,9 +892,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -921,9 +921,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $f (func (param (ref $super)))) @@ -976,9 +976,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $f (func (result (ref $sub)))) @@ -1010,9 +1010,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -1042,9 +1042,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -1072,9 +1072,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $2 (func)) @@ -1104,9 +1104,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $struct (sub (struct (field (ref null $super))))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $struct (sub (struct (ref null $super)))) @@ -1151,9 +1151,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $struct (sub (struct (field (mut (ref null $super)))))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $struct (sub (struct (mut (ref null $super))))) @@ -1207,9 +1207,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $array (sub (array (ref null $super)))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $array (sub (array (ref null $super)))) @@ -1270,9 +1270,9 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $array (sub (array (ref null $super)))) @@ -1317,9 +1317,9 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $array (sub (array (ref null $super)))) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $array (sub (array (ref null $super)))) @@ -1355,9 +1355,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $array (sub (array (mut (ref null $super))))) @@ -1420,9 +1420,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $sub-array (sub (array (mut (ref null $sub))))) @@ -1508,9 +1508,9 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) ;; CHECK: (type $array (sub (array (mut (ref null $super))))) @@ -1587,9 +1587,9 @@ ;; CHECK: (type $1 (func)) - ;; CHECK: (type $super (sub (struct ))) + ;; CHECK: (type $super (sub (struct))) (type $super (sub (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $super (struct))) (type $array (sub (array (mut (ref null $super))))) @@ -1662,10 +1662,10 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $super (sub (struct ))) + ;; CHECK-NEXT: (type $super (sub (struct))) (type $super (sub (struct))) (type $mid (sub $super (struct))) - ;; CHECK: (type $sub (sub $super (struct ))) + ;; CHECK: (type $sub (sub $super (struct))) (type $sub (sub $mid (struct))) ;; $sub <: $super, but it no longer needs to be related to $mid. @@ -1710,9 +1710,9 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $X (sub (struct ))) + ;; CHECK-NEXT: (type $X (sub (struct))) (type $X (sub (struct))) - ;; CHECK: (type $Y (sub $X (struct ))) + ;; CHECK: (type $Y (sub $X (struct))) (type $Y (sub $X (struct))) ;; CHECK: (type $super (sub (struct (field (ref null $mid))))) diff --git a/test/lit/passes/vacuum-gc.wast b/test/lit/passes/vacuum-gc.wast index 778ee8cd542..a59b2da1ed7 100644 --- a/test/lit/passes/vacuum-gc.wast +++ b/test/lit/passes/vacuum-gc.wast @@ -2,7 +2,7 @@ ;; RUN: wasm-opt %s --vacuum -all -S -o - | filecheck %s (module - ;; CHECK: (type $"{}" (struct )) + ;; CHECK: (type $"{}" (struct)) ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (type $2) (param i32 i32 funcref) (result anyref))) (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param i32 i32 funcref) (result (ref null any)))) diff --git a/test/lit/select-gc.wat b/test/lit/select-gc.wat index ddc3b9bdcb4..bd1394950f6 100644 --- a/test/lit/select-gc.wat +++ b/test/lit/select-gc.wat @@ -6,7 +6,7 @@ ;; only used in that one place in the whole module. (module - ;; CHECK: (type $struct (struct )) + ;; CHECK: (type $struct (struct)) (type $struct (struct)) ;; CHECK: (func $foo (type $0) (result anyref) diff --git a/test/lit/subtype-chain.wast b/test/lit/subtype-chain.wast index f0b774fabcc..ef6eacd66f4 100644 --- a/test/lit/subtype-chain.wast +++ b/test/lit/subtype-chain.wast @@ -7,7 +7,7 @@ ;; types. (module - ;; CHECK: (type $root (sub (struct ))) + ;; CHECK: (type $root (sub (struct))) (type $root (sub (struct))) ;; CHECK: (type $trunk (sub $root (struct (field i32)))) diff --git a/test/lit/validation/closed-world-interface.wast b/test/lit/validation/closed-world-interface.wast index 19b0faa10b6..b4fe965cf0d 100644 --- a/test/lit/validation/closed-world-interface.wast +++ b/test/lit/validation/closed-world-interface.wast @@ -13,7 +13,7 @@ ;; This is referred to by the type of a function export, but is still not allowed. ;; CHECK: publicly exposed type disallowed with a closed world: $struct, on -;; CHECK-NEXT: (struct ) +;; CHECK-NEXT: (struct) (module (type $struct (struct)) diff --git a/test/lit/validation/shared-struct.wast b/test/lit/validation/shared-struct.wast index ee25b6f24a0..1e96dc9f5a5 100644 --- a/test/lit/validation/shared-struct.wast +++ b/test/lit/validation/shared-struct.wast @@ -4,7 +4,7 @@ ;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED ;; NO-SHARED: global type requires additional features [--enable-reference-types --enable-gc --enable-shared-everything] -;; SHARED: (type $t (shared (struct ))) +;; SHARED: (type $t (shared (struct))) (module (type $t (shared (struct))) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 252673198b1..10f581d21ad 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -34,9 +34,9 @@ ;; CHECK: (type $12 (func (param i32 i64 v128))) ;; CHECK: (rec - ;; CHECK-NEXT: (type $s0 (struct )) + ;; CHECK-NEXT: (type $s0 (struct)) (type $s0 (struct)) - ;; CHECK: (type $s1 (struct )) + ;; CHECK: (type $s1 (struct)) (type $s1 (struct (field))) ) diff --git a/test/passes/roundtrip_typenames_features.txt b/test/passes/roundtrip_typenames_features.txt index 8078b6fae58..e78ae59e419 100644 --- a/test/passes/roundtrip_typenames_features.txt +++ b/test/passes/roundtrip_typenames_features.txt @@ -1,5 +1,5 @@ (module - (type $NamedStruct (struct )) + (type $NamedStruct (struct)) (type $ref?|$NamedStruct|_=>_none (func (param (ref null $NamedStruct)))) (export "export" (func $0)) (func $0 (type $ref?|$NamedStruct|_=>_none) (param $0 (ref null $NamedStruct)) From ee43476328df55757614d3a7db4419426fd3d3e9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 16 Jul 2024 11:26:22 -0700 Subject: [PATCH 449/553] [NFC] Clarify and standardize order in flexibleCopy (#6749) flexibleCopy always visited parents before children, but it visited vector children in reverse order: (call ;; 1 (call $a) ;; 3 (call $b) ;; 2 ) The order of children happened to not matter in any user of this code, and that's just what you get when you iterate over children in a vector and push them to a stack before visiting them, so this odd ordering was not noticed. For a new user I will introduce soon, however, it would be nice to have the normal pre-order: (call ;; 1 (call $a) ;; 2 (call $b) ;; 3 ) (2 & 3 swapped). This cannot be tested in the current code as it is NFC, but the later PR will depend on it and test it heavily. --- src/ir/ExpressionManipulator.cpp | 3 ++- src/ir/manipulation.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp index 4cac87a01b1..51ed7552d48 100644 --- a/src/ir/ExpressionManipulator.cpp +++ b/src/ir/ExpressionManipulator.cpp @@ -62,9 +62,10 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { #define DELEGATE_FIELD_CHILD(id, field) \ tasks.push_back({castOriginal->field, &castCopy->field}); +// Iterate in reverse order here so we visit children in normal order. #define DELEGATE_FIELD_CHILD_VECTOR(id, field) \ castCopy->field.resize(castOriginal->field.size()); \ - for (Index i = 0; i < castOriginal->field.size(); i++) { \ + for (auto i = int64_t(castOriginal->field.size()) - 1; i >= 0; i--) { \ tasks.push_back({castOriginal->field[i], &castCopy->field[i]}); \ } diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h index 64cd15dc3ce..e7816af9fce 100644 --- a/src/ir/manipulation.h +++ b/src/ir/manipulation.h @@ -68,6 +68,17 @@ inline OutputType* convert(InputType* input, MixedArena& allocator) { // expression before copying it. If it returns a non-null value then that is // used (effectively overriding the normal copy), and if it is null then we do a // normal copy. +// +// The order of iteration here is *pre*-order, that is, parents before children, +// so that it is possible to override an expression and all its children. +// Children themselves are visited in normal order. For example, this is the +// order of the following expression: +// +// (i32.add ;; visited first (and children not visited, if overridden) +// (call $a) ;; visited second +// (call $b) ;; visited third +// ) +// using CustomCopier = std::function; Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom); From 9de9d05de2f6780ac6d1394528b7e38223edf22b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 16:30:09 -0400 Subject: [PATCH 450/553] [threads] Allow i31refs of mixed shareability to compare equal (#6752) Normally, values of different types can never compare equal to each other, but since i31refs are not actually allocations, `ref.eq` has no way to differentiate a shared i31ref and an unshared i31ref with the same value, so it will report them as equal. Update the implementation of value equality to reflect this correctly. --- src/wasm/literal.cpp | 12 +++++++++--- test/spec/shared-polymorphism.wast | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 20b6b7234c5..300fc377385 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -412,6 +412,14 @@ void Literal::getBits(uint8_t (&buf)[16]) const { } bool Literal::operator==(const Literal& other) const { + // As a special case, shared and unshared i31 can compare equal even if their + // types are different (because one is shared and the other is not). + if (type.isRef() && other.type.isRef() && type.getHeapType().isBasic() && + other.type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31 && + other.type.getHeapType().getBasic(Unshared) == HeapType::i31) { + return i32 == other.i32; + } if (type != other.type) { return false; } @@ -445,9 +453,7 @@ bool Literal::operator==(const Literal& other) const { if (type.isData()) { return gcData == other.gcData; } - if (type.getHeapType() == HeapType::i31) { - return i32 == other.i32; - } + // i31 already handled. WASM_UNREACHABLE("unexpected type"); } WASM_UNREACHABLE("unexpected type"); diff --git a/test/spec/shared-polymorphism.wast b/test/spec/shared-polymorphism.wast index be8b5e467af..3ceead36211 100644 --- a/test/spec/shared-polymorphism.wast +++ b/test/spec/shared-polymorphism.wast @@ -23,3 +23,14 @@ (extern.convert_any (local.get 0)) ) ) + +(module + (func (export "eq") (param i32 i32) (result i32) + (ref.eq (ref.i31 (local.get 0)) (ref.i31_shared (local.get 1))) + ) +) + +(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) From 53b7dd1f0f129f0304a045ea00ce92334c01fb75 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 16:30:36 -0400 Subject: [PATCH 451/553] [threads] Update TypeSSA for shared types (#6753) When creating a new subtype, make sure to copy the supertype's shareability. --- src/passes/TypeSSA.cpp | 5 +- test/lit/passes/type-ssa-shared.wast | 72 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 test/lit/passes/type-ssa-shared.wast diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 3736f3ccf5b..dcd56f5d605 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -251,10 +251,13 @@ struct TypeSSA : public Pass { auto oldType = curr->type.getHeapType(); if (oldType.isStruct()) { builder[i] = oldType.getStruct(); - } else { + } else if (oldType.isArray()) { builder[i] = oldType.getArray(); + } else { + WASM_UNREACHABLE("unexpected type kind"); } builder[i].subTypeOf(oldType); + builder[i].setShared(oldType.getShared()); builder[i].setOpen(); } builder.createRecGroup(0, num); diff --git a/test/lit/passes/type-ssa-shared.wast b/test/lit/passes/type-ssa-shared.wast new file mode 100644 index 00000000000..d6266f7d9e5 --- /dev/null +++ b/test/lit/passes/type-ssa-shared.wast @@ -0,0 +1,72 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt --type-ssa -all -S -o - | filecheck %s + +;; TypeSSA should not fail on shared types. +(module + ;; CHECK: (type $struct (sub (shared (struct (field i32))))) + (type $struct (sub (shared (struct (field i32))))) + + ;; CHECK: (type $1 (func)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct_1 (sub $struct (shared (struct (field i32))))) + + ;; CHECK: (type $struct_2 (sub $struct (shared (struct (field i32))))) + + ;; CHECK: (type $struct_3 (sub $struct (shared (struct (field i32))))) + + ;; CHECK: (type $struct_4 (sub $struct (shared (struct (field i32))))) + + ;; CHECK: (type $struct_5 (sub $struct (shared (struct (field i32))))) + + ;; CHECK: (global $g (ref $struct) (struct.new $struct_4 + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: )) + (global $g (ref $struct) (struct.new $struct + (i32.const 42) + )) + + ;; CHECK: (global $h (ref $struct) (struct.new $struct_5 + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: )) + (global $h (ref $struct) (struct.new $struct + (i32.const 42) + )) + + ;; CHECK: (func $foo (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new_default $struct_1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct_2 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $foo + (drop + (struct.new_default $struct) + ) + (drop + (struct.new $struct + (i32.const 10) + ) + ) + ) + + ;; CHECK: (func $another-func (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.new $struct_3 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $another-func + (drop + (struct.new $struct + (i32.const 100) + ) + ) + ) +) From 43e8809d2683706b1ce43861ac8f9447d96a5273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 16 Jul 2024 16:36:47 -0400 Subject: [PATCH 452/553] Add C and JS APIs to control more pass options (#6713) Add functions to: * Set and get the trapsNeverHappen, closedWorld, generateStackIR and optimizeStackIR flags * Manage the list of passes to skip. --- src/binaryen-c.cpp | 40 ++++++++++++++ src/binaryen-c.h | 46 ++++++++++++++++ src/js/binaryen.js-post.js | 61 ++++++++++++++++++++++ test/binaryen.js/closed-world.js | 3 ++ test/binaryen.js/closed-world.js.txt | 1 + test/binaryen.js/generate-stack-ir.js | 3 ++ test/binaryen.js/generate-stack-ir.js.txt | 1 + test/binaryen.js/optimize-stack-ir.js | 3 ++ test/binaryen.js/optimize-stack-ir.js.txt | 1 + test/binaryen.js/passes-to-skip.js | 7 +++ test/binaryen.js/passes-to-skip.js.txt | 0 test/binaryen.js/traps-never-happen.js | 3 ++ test/binaryen.js/traps-never-happen.js.txt | 1 + 13 files changed, 170 insertions(+) create mode 100644 test/binaryen.js/closed-world.js create mode 100644 test/binaryen.js/closed-world.js.txt create mode 100644 test/binaryen.js/generate-stack-ir.js create mode 100644 test/binaryen.js/generate-stack-ir.js.txt create mode 100644 test/binaryen.js/optimize-stack-ir.js create mode 100644 test/binaryen.js/optimize-stack-ir.js.txt create mode 100644 test/binaryen.js/passes-to-skip.js create mode 100644 test/binaryen.js/passes-to-skip.js.txt create mode 100644 test/binaryen.js/traps-never-happen.js create mode 100644 test/binaryen.js/traps-never-happen.js.txt diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 298a5023368..afc3dbe5414 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -5373,6 +5373,18 @@ bool BinaryenGetDebugInfo(void) { return globalPassOptions.debugInfo; } void BinaryenSetDebugInfo(bool on) { globalPassOptions.debugInfo = on != 0; } +bool BinaryenGetTrapsNeverHappen(void) { + return globalPassOptions.trapsNeverHappen; +} + +void BinaryenSetTrapsNeverHappen(bool on) { + globalPassOptions.trapsNeverHappen = on; +} + +bool BinaryenGetClosedWorld(void) { return globalPassOptions.closedWorld; } + +void BinaryenSetClosedWorld(bool on) { globalPassOptions.closedWorld = on; } + bool BinaryenGetLowMemoryUnused(void) { return globalPassOptions.lowMemoryUnused; } @@ -5393,6 +5405,22 @@ bool BinaryenGetFastMath(void) { return globalPassOptions.fastMath; } void BinaryenSetFastMath(bool value) { globalPassOptions.fastMath = value; } +bool BinaryenGetGenerateStackIR(void) { + return globalPassOptions.generateStackIR; +} + +void BinaryenSetGenerateStackIR(bool on) { + globalPassOptions.generateStackIR = on; +} + +bool BinaryenGetOptimizeStackIR(void) { + return globalPassOptions.optimizeStackIR; +} + +void BinaryenSetOptimizeStackIR(bool on) { + globalPassOptions.optimizeStackIR = on; +} + const char* BinaryenGetPassArgument(const char* key) { assert(key); const auto& args = globalPassOptions.arguments; @@ -5415,6 +5443,18 @@ void BinaryenSetPassArgument(const char* key, const char* value) { void BinaryenClearPassArguments(void) { globalPassOptions.arguments.clear(); } +bool BinaryenHasPassToSkip(const char* pass) { + assert(pass); + return globalPassOptions.passesToSkip.count(pass); +} + +void BinaryenAddPassToSkip(const char* pass) { + assert(pass); + globalPassOptions.passesToSkip.insert(pass); +} + +void BinaryenClearPassesToSkip(void) { globalPassOptions.passesToSkip.clear(); } + BinaryenIndex BinaryenGetAlwaysInlineMaxSize(void) { return globalPassOptions.inlining.alwaysInlineMaxSize; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 35f1d8eb8ac..0b1319f3024 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -2925,6 +2925,24 @@ BINARYEN_API bool BinaryenGetDebugInfo(void); // Applies to all modules, globally. BINARYEN_API void BinaryenSetDebugInfo(bool on); +// Gets whether no traps can be considered reached at runtime when optimizing. +// Applies to all modules, globally. +BINARYEN_API bool BinaryenGetTrapsNeverHappen(void); + +// Enables or disables whether no traps can be considered reached at +// runtime when optimizing. Applies to all modules, globally. +BINARYEN_API void BinaryenSetTrapsNeverHappen(bool on); + +// Gets whether considering that the code outside of the module does +// not inspect or interact with GC and function references. Applies to +// all modules, globally. +BINARYEN_API bool BinaryenGetClosedWorld(void); + +// Enables or disables whether considering that the code outside of +// the module does not inspect or interact with GC and function +// references. Applies to all modules, globally. +BINARYEN_API void BinaryenSetClosedWorld(bool on); + // Gets whether the low 1K of memory can be considered unused when optimizing. // Applies to all modules, globally. BINARYEN_API bool BinaryenGetLowMemoryUnused(void); @@ -2950,6 +2968,22 @@ BINARYEN_API bool BinaryenGetFastMath(void); // Applies to all modules, globally. BINARYEN_API void BinaryenSetFastMath(bool value); +// Gets whether to generate StackIR during binary writing. +// Applies to all modules, globally. +BINARYEN_API bool BinaryenGetGenerateStackIR(void); + +// Enable or disable StackIR generation during binary writing. +// Applies to all modules, globally. +BINARYEN_API void BinaryenSetGenerateStackIR(bool on); + +// Gets whether to optimize StackIR during binary writing. +// Applies to all modules, globally. +BINARYEN_API bool BinaryenGetOptimizeStackIR(void); + +// Enable or disable StackIR optimization during binary writing. +// Applies to all modules, globally. +BINARYEN_API void BinaryenSetOptimizeStackIR(bool on); + // Gets the value of the specified arbitrary pass argument. // Applies to all modules, globally. BINARYEN_API const char* BinaryenGetPassArgument(const char* name); @@ -2962,6 +2996,18 @@ BINARYEN_API void BinaryenSetPassArgument(const char* name, const char* value); // Applies to all modules, globally. BINARYEN_API void BinaryenClearPassArguments(); +// Gets whether a pass is in the set of passes to skip. +// Applies to all modules, globally. +BINARYEN_API bool BinaryenHasPassToSkip(const char* pass); + +// Add a pass to the set of passes to skip. +// Applies to all modules, globally. +BINARYEN_API void BinaryenAddPassToSkip(const char* pass); + +// Clears the set of passes to skip. +// Applies to all modules, globally. +BINARYEN_API void BinaryenClearPassesToSkip(void); + // Gets the function size at which we always inline. // Applies to all modules, globally. BINARYEN_API BinaryenIndex BinaryenGetAlwaysInlineMaxSize(void); diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 097c28bc75e..55e1a7ad7b3 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -3412,6 +3412,30 @@ Module['setDebugInfo'] = function(on) { Module['_BinaryenSetDebugInfo'](on); }; +// Gets whether no traps can be considered reached at runtime when optimizing. +Module['getTrapsNeverHappen'] = function() { + return Boolean(Module['_BinaryenGetTrapsNeverHappen']()); +}; + +// Enables or disables whether no traps can be considered reached at +// runtime when optimizing. +Module['setTrapsNeverHappen'] = function(on) { + Module['_BinaryenSetTrapsNeverHappen'](on); +}; + +// Gets whether considering that the code outside of the module does +// not inspect or interact with GC and function references. +Module['getClosedWorld'] = function() { + return Boolean(Module['_BinaryenGetClosedWorld']()); +}; + +// Enables or disables whether considering that the code outside of +// the module does not inspect or interact with GC and function +// references. +Module['setClosedWorld'] = function(on) { + Module['_BinaryenSetClosedWorld'](on); +}; + // Gets whether the low 1K of memory can be considered unused when optimizing. Module['getLowMemoryUnused'] = function() { return Boolean(Module['_BinaryenGetLowMemoryUnused']()); @@ -3445,6 +3469,26 @@ Module['setFastMath'] = function(value) { Module['_BinaryenSetFastMath'](value); }; +// Gets whether to generate StackIR during binary writing. +Module['getGenerateStackIR'] = function() { + return Boolean(Module['_BinaryenGetGenerateStackIR']()); +}; + +// Enable or disable StackIR generation during binary writing. +Module['setGenerateStackIR'] = function(value) { + Module['_BinaryenSetGenerateStackIR'](value); +}; + +// Gets whether to optimize StackIR during binary writing. +Module['getOptimizeStackIR'] = function() { + return Boolean(Module['_BinaryenGetOptimizeStackIR']()); +}; + +// Enable or disable StackIR optimisation during binary writing. +Module['setOptimizeStackIR'] = function(value) { + Module['_BinaryenSetOptimizeStackIR'](value); +}; + // Gets the value of the specified arbitrary pass argument. Module['getPassArgument'] = function(key) { return preserveStack(() => { @@ -3464,6 +3508,23 @@ Module['clearPassArguments'] = function() { Module['_BinaryenClearPassArguments'](); }; +// Gets whether a pass is in the set of passes to skip. +Module['hasPassToSkip'] = function(pass) { + return preserveStack(() => { + return Boolean(Module['_BinaryenHasPassToSkip'](strToStack(pass))); + }); +}; + +// Add a pass to the set of passes to skip. +Module['addPassToSkip'] = function (pass) { + preserveStack(() => { Module['_BinaryenAddPassToSkip'](strToStack(pass)) }); +}; + +// Clears the set of passes to skip. +Module['clearPassesToSkip'] = function() { + Module['_BinaryenClearPassesToSkip'](); +}; + // Gets the function size at which we always inline. Module['getAlwaysInlineMaxSize'] = function() { return Module['_BinaryenGetAlwaysInlineMaxSize'](); diff --git a/test/binaryen.js/closed-world.js b/test/binaryen.js/closed-world.js new file mode 100644 index 00000000000..7c0d50dd815 --- /dev/null +++ b/test/binaryen.js/closed-world.js @@ -0,0 +1,3 @@ +console.log("// closedWorld=" + binaryen.getClosedWorld()); +binaryen.setClosedWorld(true); +assert(binaryen.getClosedWorld() == true); diff --git a/test/binaryen.js/closed-world.js.txt b/test/binaryen.js/closed-world.js.txt new file mode 100644 index 00000000000..1c2aa471bac --- /dev/null +++ b/test/binaryen.js/closed-world.js.txt @@ -0,0 +1 @@ +// closedWorld=false diff --git a/test/binaryen.js/generate-stack-ir.js b/test/binaryen.js/generate-stack-ir.js new file mode 100644 index 00000000000..8aac2ccd8f5 --- /dev/null +++ b/test/binaryen.js/generate-stack-ir.js @@ -0,0 +1,3 @@ +console.log("// generateStackIR=" + binaryen.getGenerateStackIR()); +binaryen.setGenerateStackIR(true); +assert(binaryen.getGenerateStackIR() == true); diff --git a/test/binaryen.js/generate-stack-ir.js.txt b/test/binaryen.js/generate-stack-ir.js.txt new file mode 100644 index 00000000000..184febf82da --- /dev/null +++ b/test/binaryen.js/generate-stack-ir.js.txt @@ -0,0 +1 @@ +// generateStackIR=false diff --git a/test/binaryen.js/optimize-stack-ir.js b/test/binaryen.js/optimize-stack-ir.js new file mode 100644 index 00000000000..ec3a7c54d6d --- /dev/null +++ b/test/binaryen.js/optimize-stack-ir.js @@ -0,0 +1,3 @@ +console.log("// optimizeStackIR=" + binaryen.getOptimizeStackIR()); +binaryen.setOptimizeStackIR(true); +assert(binaryen.getOptimizeStackIR() == true); diff --git a/test/binaryen.js/optimize-stack-ir.js.txt b/test/binaryen.js/optimize-stack-ir.js.txt new file mode 100644 index 00000000000..07d1721b33a --- /dev/null +++ b/test/binaryen.js/optimize-stack-ir.js.txt @@ -0,0 +1 @@ +// optimizeStackIR=false diff --git a/test/binaryen.js/passes-to-skip.js b/test/binaryen.js/passes-to-skip.js new file mode 100644 index 00000000000..c95bd5d4724 --- /dev/null +++ b/test/binaryen.js/passes-to-skip.js @@ -0,0 +1,7 @@ +assert(!binaryen.hasPassToSkip("thePass")); + +binaryen.addPassToSkip("thePass"); +assert(binaryen.hasPassToSkip("thePass")); + +binaryen.clearPassesToSkip(); +assert(!binaryen.hasPassToSkip("thePass")); diff --git a/test/binaryen.js/passes-to-skip.js.txt b/test/binaryen.js/passes-to-skip.js.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/binaryen.js/traps-never-happen.js b/test/binaryen.js/traps-never-happen.js new file mode 100644 index 00000000000..d1c91bf0404 --- /dev/null +++ b/test/binaryen.js/traps-never-happen.js @@ -0,0 +1,3 @@ +console.log("// trapsNeverHappen=" + binaryen.getTrapsNeverHappen()); +binaryen.setTrapsNeverHappen(true); +assert(binaryen.getTrapsNeverHappen() == true); diff --git a/test/binaryen.js/traps-never-happen.js.txt b/test/binaryen.js/traps-never-happen.js.txt new file mode 100644 index 00000000000..586e4d25c78 --- /dev/null +++ b/test/binaryen.js/traps-never-happen.js.txt @@ -0,0 +1 @@ +// trapsNeverHappen=false From a8df0bf7901a78caccdcb6fad96fa3bdb6697ca1 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 17:11:54 -0400 Subject: [PATCH 453/553] [NFC][threads] Ignore type-ssa-shared.wast in fuzzer (#6754) The fuzzer does not yet properly handle initial contents containing shared types. --- scripts/fuzz_opt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index ada930127c7..c6a68e85c30 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -357,6 +357,7 @@ def is_git_repo(): 'shared-struct.wast', 'shared-array.wast', 'shared-i31.wast', + 'type-ssa-shared.wast', ] From d91f1c4ea8d4d8fc075fc868d6f7c05829003968 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 18:37:13 -0400 Subject: [PATCH 454/553] [threads] Fix feature detection for shared basic heap types (#6756) The logic for adding the shared-everything feature was not previously executed for shared basic heap types. --- src/wasm/wasm-type.cpp | 8 ++++---- test/lit/validation/shared-absheaptype.wast | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 test/lit/validation/shared-absheaptype.wast diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index adb2c7fa82c..bfab4b95538 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1526,6 +1526,10 @@ FeatureSet HeapType::getFeatures() const { FeatureSet feats = FeatureSet::None; void noteChild(HeapType* heapType) { + if (heapType->isShared()) { + feats |= FeatureSet::SharedEverything; + } + if (heapType->isBasic()) { switch (heapType->getBasic(Unshared)) { case HeapType::ext: @@ -1565,10 +1569,6 @@ FeatureSet HeapType::getFeatures() const { feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; } - if (heapType->isShared()) { - feats |= FeatureSet::SharedEverything; - } - if (heapType->isStruct() || heapType->isArray()) { feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; } else if (heapType->isSignature()) { diff --git a/test/lit/validation/shared-absheaptype.wast b/test/lit/validation/shared-absheaptype.wast new file mode 100644 index 00000000000..6ab3c02196f --- /dev/null +++ b/test/lit/validation/shared-absheaptype.wast @@ -0,0 +1,11 @@ +;; Test that shared structs require shared-everything threads + +;; RUN: not wasm-opt %s 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED + +;; NO-SHARED: global type requires additional features [--enable-reference-types --enable-gc --enable-shared-everything] +;; SHARED: (import "" "" (global $gimport$0 (ref null (shared any)))) + +(module + (global (import "" "") (ref null (shared any))) +) From 6d2bef3ff80bb96455207852d506c5bf12a6a851 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 16 Jul 2024 19:19:34 -0400 Subject: [PATCH 455/553] [threads] Validate all features required by ref.null (#6757) `ref.null` of shared types should only be allowed when shared-everything is enabled, but we were previously checking only that reference types were enabled when validating `ref.null`. Update the code to check all features required by the null type and factor out shared logic for printing lists of missing feature options in error messages. --- scripts/fuzz_opt.py | 2 ++ src/wasm/wasm-validator.cpp | 40 +++++++++++++-------- test/lit/validation/shared-absheaptype.wast | 2 +- test/lit/validation/shared-null.wast | 12 +++++++ 4 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 test/lit/validation/shared-null.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index c6a68e85c30..f4b64f44ce8 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -357,6 +357,8 @@ def is_git_repo(): 'shared-struct.wast', 'shared-array.wast', 'shared-i31.wast', + 'shared-null.wast', + 'shared-absheaptype.wast', 'type-ssa-shared.wast', ] diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 143baee416e..e18191beaaf 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -223,6 +223,22 @@ struct ValidationInfo { } }; +std::string getMissingFeaturesList(Module& wasm, FeatureSet feats) { + std::stringstream ss; + bool first = true; + ss << '['; + (feats - wasm.features).iterFeatures([&](FeatureSet feat) { + if (first) { + first = false; + } else { + ss << " "; + } + ss << "--enable-" << feat.toString(); + }); + ss << ']'; + return ss.str(); +} + struct FunctionValidator : public WalkerPass> { bool isFunctionParallel() override { return true; } @@ -2188,9 +2204,12 @@ void FunctionValidator::visitRefNull(RefNull* curr) { // If we are not in a function, this is a global location like a table. We // allow RefNull there as we represent tables that way regardless of what // features are enabled. - shouldBeTrue(!getFunction() || getModule()->features.hasReferenceTypes(), - curr, - "ref.null requires reference-types [--enable-reference-types]"); + auto feats = curr->type.getFeatures(); + if (!shouldBeTrue(!getFunction() || feats <= getModule()->features, + curr, + "ref.null requires additional features")) { + getStream() << getMissingFeaturesList(*getModule(), feats) << '\n'; + } if (!shouldBeTrue( curr->type.isNullable(), curr, "ref.null types must be nullable")) { return; @@ -3711,18 +3730,9 @@ static void validateGlobals(Module& module, ValidationInfo& info) { for (auto& g : module.globals) { auto globalFeats = g->type.getFeatures(); if (!info.shouldBeTrue(globalFeats <= module.features, g->name, "")) { - auto& stream = info.getStream(nullptr); - stream << "global type requires additional features ["; - bool first = true; - (globalFeats - module.features).iterFeatures([&](FeatureSet feat) { - if (first) { - first = false; - } else { - stream << " "; - } - stream << "--enable-" << feat.toString(); - }); - stream << "]\n"; + info.getStream(nullptr) + << "global type requires additional features " + << getMissingFeaturesList(module, globalFeats) << '\n'; } } } diff --git a/test/lit/validation/shared-absheaptype.wast b/test/lit/validation/shared-absheaptype.wast index 6ab3c02196f..4426f31b3e6 100644 --- a/test/lit/validation/shared-absheaptype.wast +++ b/test/lit/validation/shared-absheaptype.wast @@ -1,4 +1,4 @@ -;; Test that shared structs require shared-everything threads +;; Test that shared basic heap types require shared-everything threads ;; RUN: not wasm-opt %s 2>&1 | filecheck %s --check-prefix NO-SHARED ;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED diff --git a/test/lit/validation/shared-null.wast b/test/lit/validation/shared-null.wast new file mode 100644 index 00000000000..1c34873bb49 --- /dev/null +++ b/test/lit/validation/shared-null.wast @@ -0,0 +1,12 @@ +;; Test that shared nulls require shared-everything threads + +;; RUN: not wasm-opt %s 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED + +;; NO-SHARED: ref.null requires additional features +;; NO-SHARED: [--enable-reference-types --enable-shared-everything] +;; SHARED: (ref.null (shared none)) + +(module + (func (drop (ref.null (shared none)))) +) From 994d8d31381dbc9dbaa89809c75b2c8d804e0d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Wed, 17 Jul 2024 11:30:07 -0400 Subject: [PATCH 456/553] Make it possible to skip several passes (#6714) --skip-pass can now be specified more than once on the commandline. --- src/tools/optimization-options.h | 2 +- test/lit/passes/O1_skip_passes.wast | 65 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 test/lit/passes/O1_skip_passes.wast diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h index f04b7321120..333380d0490 100644 --- a/src/tools/optimization-options.h +++ b/src/tools/optimization-options.h @@ -311,7 +311,7 @@ struct OptimizationOptions : public ToolOptions { "-sp", "Skip a pass (do not run it)", OptimizationOptionsCategory, - Options::Arguments::One, + Options::Arguments::N, [this](Options*, const std::string& pass) { passOptions.passesToSkip.insert(pass); }); diff --git a/test/lit/passes/O1_skip_passes.wast b/test/lit/passes/O1_skip_passes.wast new file mode 100644 index 00000000000..7e84306e7cc --- /dev/null +++ b/test/lit/passes/O1_skip_passes.wast @@ -0,0 +1,65 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: foreach %s %t wasm-opt -O2 --skip-pass=coalesce-locals --skip-pass=simplify-locals --skip-pass=simplify-locals-nostructure -S -o - 2>&1 | filecheck %s + +;; Check that we can skip several passes. Note that no local.tee is introduced. + +(module + ;; CHECK: (import "a" "b" (func $log (param i32 i32))) + (import "a" "b" (func $log (param i32 i32))) + + ;; CHECK: (func $foo (param $p i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $p) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $log + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $p) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $log + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $foo (export "foo") (param $p i32) + ;; The locals $x and $y can be coalesced into a single local, but as + ;; we do not run that pass, they will not be. They could be + ;; initialized using a tee but the passes that introduce tees are + ;; not run either. + (local $x i32) + (local $y i32) + + (local.set $x + (i32.add + (local.get $p) + (i32.const 1) + ) + ) + (call $log + (local.get $x) + (local.get $x) + ) + + (local.set $y + (i32.add + (local.get $p) + (i32.const 1) + ) + ) + (call $log + (local.get $y) + (local.get $y) + ) + ) +) From 55d888acac2e78f110e298e2502517db1523a67e Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 12:42:57 -0400 Subject: [PATCH 457/553] [threads] Validate all features required by ref.null (#6758) `ref.null` of shared types should only be allowed when shared-everything is enabled, but we were previously checking only that reference types were enabled when validating `ref.null`. Update the code to check all features required by the null type and factor out shared logic for printing lists of missing feature options in error messages. --- src/wasm-builder.h | 6 +++-- test/lit/ctor-eval/shared-i31.wast | 38 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 test/lit/ctor-eval/shared-i31.wast diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 1e768b11ccf..6663417f868 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1217,8 +1217,10 @@ class Builder { if (type.isFunction()) { return makeRefFunc(value.getFunc(), type.getHeapType()); } - if (type.isRef() && type.getHeapType() == HeapType::i31) { - return makeRefI31(makeConst(value.geti31())); + if (type.isRef() && type.getHeapType().isBasic() && + type.getHeapType().getBasic(Unshared) == HeapType::i31) { + return makeRefI31(makeConst(value.geti31()), + type.getHeapType().getShared()); } if (type.isString()) { // The string is already WTF-16, but we need to convert from `Literals` to diff --git a/test/lit/ctor-eval/shared-i31.wast b/test/lit/ctor-eval/shared-i31.wast new file mode 100644 index 00000000000..2c1d8da5929 --- /dev/null +++ b/test/lit/ctor-eval/shared-i31.wast @@ -0,0 +1,38 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-ctor-eval %s --ctors=test --kept-exports=test,other --quiet -all -S -o - | filecheck %s + +;; We should be able to update `global` with a proper shared i31 reference. + +(module + ;; CHECK: (type $0 (func (result (ref null (shared any))))) + + ;; CHECK: (global $global (mut (ref null (shared i31))) (ref.i31_shared + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: )) + (global $global (mut (ref null (shared i31))) (ref.null (shared none))) + + (func $test (export "test") (result (ref null (shared any))) + (global.set $global + (ref.i31_shared + (i32.const 42) + ) + ) + (global.get $global) + ) + + ;; CHECK: (export "test" (func $test_2)) + + ;; CHECK: (export "other" (func $other)) + + ;; CHECK: (func $other (type $0) (result (ref null (shared any))) + ;; CHECK-NEXT: (global.get $global) + ;; CHECK-NEXT: ) + (func $other (export "other") (result (ref null (shared any))) + (global.get $global) + ) +) +;; CHECK: (func $test_2 (type $0) (result (ref null (shared any))) +;; CHECK-NEXT: (ref.i31_shared +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) From 9cee7d0c886fac271674ab495b3c15134719abdc Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 17 Jul 2024 10:08:48 -0700 Subject: [PATCH 458/553] [NFC] Add changelog entries for the last release and since (#6755) --- CHANGELOG.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d37e89e367..d7e301ef3a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,12 +21,17 @@ Current Trunk apply to the most recent --foo pass on the commandline, if foo is a pass (while global pass arguments - that are not the name of a pass - remain, as before, global for all passes). (#6687) + - Add C and JS APIs to control more pass options (trapsNeverHappen, + closedWorld, generateStackIR, optimizeStackIR, and the list of skipped + passes). (#6713) + - A C APIs for getting/setting the type of Functions (#6721). + - Allow using `--skip-pass` on the commandline multiple times (#6714). v118 ---- - - StackIR is now handled entirely during binary writing. This is mostly not - noticeable, except that: + - StackIR is now handled entirely during binary writing (#6568). This is + mostly not noticeable, except that: - Text output no longer notes `(; has Stack IR ;)` (as Stack IR only exists during binary writing). - `--generate-stack-ir`, `--optimize-stack-ir`, and `--print-stack-ir` are @@ -44,10 +49,15 @@ v118 - Source map locations from instructions are no longer automatically propagated to function epilogues. - Add a new `BinaryenModuleReadWithFeatures` function to the C API that allows - to configure which features to enable in the parser. - - The build-time option to use legacy WasmGC opcodes is removed. + to configure which features to enable in the parser. (#6380) + - The build-time option to use legacy WasmGC opcodes is removed. (#5874) - The strings in `string.const` instructions must now be valid WTF-8. - The `TraverseCalls` flag for `ExpressionRunner` is removed. + - C API: Support adding data segments individually (#6346) + - Add sourcemap support to wasm-metadce and wasm-merge (#6372). + - Fix semantics of return calls (#6448, #6451, #6464, #6470, #6474). + - Add table64 lowering pass (#6595). + - Add TraceCalls instrumentation pass (#6619). v117 ---- From ddf919bb00d07c65caa516dcec3a5d65cc824abb Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 17 Jul 2024 10:48:34 -0700 Subject: [PATCH 459/553] Error more clearly on wasm components (#6751) Component binary format: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#component-definitions Context: https://github.com/WebAssembly/binaryen/issues/6728#issuecomment-2231288924 --- src/wasm/wasm-binary.cpp | 10 +++++++++- test/lit/binary/component-error.test | 6 ++++++ test/lit/binary/component-error.test.wasm | Bin 0 -> 8 bytes 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/lit/binary/component-error.test create mode 100644 test/lit/binary/component-error.test.wasm diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 74d74f473f7..ee8afeb93ed 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2243,7 +2243,15 @@ void WasmBinaryReader::verifyInt64(int64_t x) { void WasmBinaryReader::readHeader() { BYN_TRACE("== readHeader\n"); verifyInt32(BinaryConsts::Magic); - verifyInt32(BinaryConsts::Version); + auto version = getInt32(); + if (version != BinaryConsts::Version) { + if (version == 0x1000d) { + throwError("this looks like a wasm component, which Binaryen does not " + "support yet (see " + "https://github.com/WebAssembly/binaryen/issues/6728)"); + } + throwError("invalid version"); + } } void WasmBinaryReader::readStart() { diff --git a/test/lit/binary/component-error.test b/test/lit/binary/component-error.test new file mode 100644 index 00000000000..57bcec4573b --- /dev/null +++ b/test/lit/binary/component-error.test @@ -0,0 +1,6 @@ +# Verify that we show an error when given a component. + +;; RUN: not wasm-opt %s.wasm 2>&1 | filecheck %s + +;; CHECK: this looks like a wasm component, which Binaryen does not support yet (see https://github.com/WebAssembly/binaryen/issues/6728) + diff --git a/test/lit/binary/component-error.test.wasm b/test/lit/binary/component-error.test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..13d20e9f03ed5ca6672a62c2e3a0f6c5408bcdf1 GIT binary patch literal 8 PcmZQbEY9U+U}OLQ2e<)H literal 0 HcmV?d00001 From a9758b867ad77bf3f7390123ad4f4ba92a38a1bd Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 15:58:30 -0400 Subject: [PATCH 460/553] [threads][NFC] Do not include cont in shared types test (#6759) Once the fuzzer is updated to be able to handle initial contents with shared types, it still will not be able to handle initial contents with continuation types. To avoid future issues, remove continuations from lit/basic/shared-types.wast. --- test/lit/basic/shared-types.wast | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/test/lit/basic/shared-types.wast b/test/lit/basic/shared-types.wast index f74d0023fd4..25e593fd2a7 100644 --- a/test/lit/basic/shared-types.wast +++ b/test/lit/basic/shared-types.wast @@ -21,8 +21,6 @@ (type $func (shared (func))) ;; CHECK: (type $array (shared (array i8))) (type $array (shared (array i8))) - ;; CHECK: (type $cont (shared (cont $func))) - (type $cont (shared (cont $func))) ) ;; CHECK: (func $use-types (type $0) @@ -32,7 +30,6 @@ ;; CHECK-NEXT: (local $3 (ref $bot)) ;; CHECK-NEXT: (local $4 (ref $func)) ;; CHECK-NEXT: (local $5 (ref $array)) - ;; CHECK-NEXT: (local $6 (ref $cont)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-types @@ -42,31 +39,27 @@ (local (ref $bot)) (local (ref $func)) (local (ref $array)) - (local (ref $cont)) ) ;; CHECK: (func $use-basic-types (type $0) ;; CHECK-NEXT: (local $0 (ref (shared extern))) ;; CHECK-NEXT: (local $1 (ref (shared func))) - ;; CHECK-NEXT: (local $2 (ref (shared cont))) - ;; CHECK-NEXT: (local $3 (ref (shared any))) - ;; CHECK-NEXT: (local $4 (ref (shared eq))) - ;; CHECK-NEXT: (local $5 (ref (shared i31))) - ;; CHECK-NEXT: (local $6 (ref (shared struct))) - ;; CHECK-NEXT: (local $7 (ref (shared array))) - ;; CHECK-NEXT: (local $8 (ref (shared exn))) - ;; CHECK-NEXT: (local $9 (ref (shared string))) - ;; CHECK-NEXT: (local $10 (ref (shared none))) - ;; CHECK-NEXT: (local $11 (ref (shared noextern))) - ;; CHECK-NEXT: (local $12 (ref (shared nofunc))) - ;; CHECK-NEXT: (local $13 (ref (shared nocont))) - ;; CHECK-NEXT: (local $14 (ref (shared noexn))) + ;; CHECK-NEXT: (local $2 (ref (shared any))) + ;; CHECK-NEXT: (local $3 (ref (shared eq))) + ;; CHECK-NEXT: (local $4 (ref (shared i31))) + ;; CHECK-NEXT: (local $5 (ref (shared struct))) + ;; CHECK-NEXT: (local $6 (ref (shared array))) + ;; CHECK-NEXT: (local $7 (ref (shared exn))) + ;; CHECK-NEXT: (local $8 (ref (shared string))) + ;; CHECK-NEXT: (local $9 (ref (shared none))) + ;; CHECK-NEXT: (local $10 (ref (shared noextern))) + ;; CHECK-NEXT: (local $11 (ref (shared nofunc))) + ;; CHECK-NEXT: (local $12 (ref (shared noexn))) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $use-basic-types (local (ref (shared extern))) (local (ref (shared func))) - (local (ref (shared cont))) (local (ref (shared any))) (local (ref (shared eq))) (local (ref (shared i31))) @@ -77,7 +70,6 @@ (local (ref (shared none))) (local (ref (shared noextern))) (local (ref (shared nofunc))) - (local (ref (shared nocont))) (local (ref (shared noexn))) ) ) From 4dee6fe0a920f95d31b0921a22a8f5f979e2e14d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 18:02:08 -0400 Subject: [PATCH 461/553] Revert "[threads] Allow i31refs of mixed shareability to compare equal (#6752)" (#6761) Allowing Literals with different types to compare equal causes problems for passes that want equality to mean real equality, e.g. because they are using literals as map keys or because they otherwise need to use them interchangeably. At a minimum, we would need to differentiate a `refEq` operation where mixed-shareability i31refs can compare equal from physical equality on Literals, but there is also appetite to disallow mixed-shareability ref.eq at the spec level. See https://github.com/WebAssembly/shared-everything-threads/issues/76. --- src/wasm/literal.cpp | 12 +++--------- test/spec/shared-polymorphism.wast | 11 ----------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 300fc377385..20b6b7234c5 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -412,14 +412,6 @@ void Literal::getBits(uint8_t (&buf)[16]) const { } bool Literal::operator==(const Literal& other) const { - // As a special case, shared and unshared i31 can compare equal even if their - // types are different (because one is shared and the other is not). - if (type.isRef() && other.type.isRef() && type.getHeapType().isBasic() && - other.type.getHeapType().isBasic() && - type.getHeapType().getBasic(Unshared) == HeapType::i31 && - other.type.getHeapType().getBasic(Unshared) == HeapType::i31) { - return i32 == other.i32; - } if (type != other.type) { return false; } @@ -453,7 +445,9 @@ bool Literal::operator==(const Literal& other) const { if (type.isData()) { return gcData == other.gcData; } - // i31 already handled. + if (type.getHeapType() == HeapType::i31) { + return i32 == other.i32; + } WASM_UNREACHABLE("unexpected type"); } WASM_UNREACHABLE("unexpected type"); diff --git a/test/spec/shared-polymorphism.wast b/test/spec/shared-polymorphism.wast index 3ceead36211..be8b5e467af 100644 --- a/test/spec/shared-polymorphism.wast +++ b/test/spec/shared-polymorphism.wast @@ -23,14 +23,3 @@ (extern.convert_any (local.get 0)) ) ) - -(module - (func (export "eq") (param i32 i32) (result i32) - (ref.eq (ref.i31 (local.get 0)) (ref.i31_shared (local.get 1))) - ) -) - -(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) From 1e7be1ea067d3e2f3044d49392637325abcd4a01 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 18:02:25 -0400 Subject: [PATCH 462/553] Update the ref_eq.wast spec test to match upstream (#6762) --- test/spec/ref_eq.wast | 171 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 164 insertions(+), 7 deletions(-) diff --git a/test/spec/ref_eq.wast b/test/spec/ref_eq.wast index a5224834cdf..001efd69f89 100644 --- a/test/spec/ref_eq.wast +++ b/test/spec/ref_eq.wast @@ -1,11 +1,168 @@ (module - (func $compare (export "compare") (param $x eqref) (param $y eqref) (result i32) - (ref.eq - (local.get $x) - (local.get $y) - ) + (type $st (sub (struct))) + (type $st' (sub (struct (field i32)))) + (type $at (array i8)) + (type $st-sub1 (sub $st (struct))) + (type $st-sub2 (sub $st (struct))) + (type $st'-sub1 (sub $st' (struct (field i32)))) + (type $st'-sub2 (sub $st' (struct (field i32)))) + + (table 20 (ref null eq)) + + (func (export "init") + (table.set (i32.const 0) (ref.null eq)) + (table.set (i32.const 1) (ref.null i31)) + (table.set (i32.const 2) (ref.i31 (i32.const 7))) + (table.set (i32.const 3) (ref.i31 (i32.const 7))) + (table.set (i32.const 4) (ref.i31 (i32.const 8))) + (table.set (i32.const 5) (struct.new_default $st)) + (table.set (i32.const 6) (struct.new_default $st)) + (table.set (i32.const 7) (array.new_default $at (i32.const 0))) + (table.set (i32.const 8) (array.new_default $at (i32.const 0))) + ) + + (func (export "eq") (param $i i32) (param $j i32) (result i32) + (ref.eq (table.get (local.get $i)) (table.get (local.get $j))) ) ) -;; All nulls compare equal, regardless of their type. -(assert_return (invoke "compare" (ref.null none) (ref.null eq)) (i32.const 1)) +(invoke "init") + +(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 2) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 2)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 3)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 3) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 2)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 3)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 4) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 4)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 5) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 5)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 6) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 6)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 7) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 7)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 8) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 8)) (i32.const 1)) + +(assert_invalid + (module + (func (export "eq") (param $r (ref any)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null any)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref func)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null func)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref extern)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null extern)) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) From 1434591fbd62f611cc530ed024a1b1477e2e7614 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 18:51:40 -0400 Subject: [PATCH 463/553] [threads] Fix shared ref.eq and disallow mixed-shareability (#6763) Update the validator to reject mixed-shareability ref.eq, although this is still under discussion in https://github.com/WebAssembly/shared-everything-threads/issues/76. Fix the implementation of `Literal::operator==` to work properly with shared i31ref. --- scripts/fuzz_opt.py | 1 + src/wasm/literal.cpp | 3 +- src/wasm/wasm-validator.cpp | 6 + test/spec/shared-polymorphism.wast | 2 - test/spec/shared-ref_eq.wast | 202 +++++++++++++++++++++++++++++ 5 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 test/spec/shared-ref_eq.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index f4b64f44ce8..b9d42d6346d 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -360,6 +360,7 @@ def is_git_repo(): 'shared-null.wast', 'shared-absheaptype.wast', 'type-ssa-shared.wast', + 'shared-ref_eq.wast', ] diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 20b6b7234c5..a49fa1b6271 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -445,7 +445,8 @@ bool Literal::operator==(const Literal& other) const { if (type.isData()) { return gcData == other.gcData; } - if (type.getHeapType() == HeapType::i31) { + assert(type.getHeapType().isBasic()); + if (type.getHeapType().getBasic(Unshared) == HeapType::i31) { return i32 == other.i32; } WASM_UNREACHABLE("unexpected type"); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e18191beaaf..29e7a2c9c4b 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2306,6 +2306,12 @@ void FunctionValidator::visitRefEq(RefEq* curr) { eqref, curr->right, "ref.eq's right argument should be a subtype of eqref"); + if (curr->left->type.isRef() && curr->right->type.isRef()) { + shouldBeEqual(curr->left->type.getHeapType().getShared(), + curr->right->type.getHeapType().getShared(), + curr, + "ref.eq operands must have the same shareability"); + } } void FunctionValidator::visitTableGet(TableGet* curr) { diff --git a/test/spec/shared-polymorphism.wast b/test/spec/shared-polymorphism.wast index be8b5e467af..5c9d905e75d 100644 --- a/test/spec/shared-polymorphism.wast +++ b/test/spec/shared-polymorphism.wast @@ -2,8 +2,6 @@ ;; references. (module (func (drop (ref.eq (ref.null (shared none)) (ref.null (shared none))))) - (func (drop (ref.eq (ref.null (shared none)) (ref.null none)))) - (func (drop (ref.eq (ref.null none) (ref.null (shared none))))) (func (param (ref null (shared i31))) (drop (i31.get_s (local.get 0)))) (func (param (ref null (shared i31))) (drop (i31.get_u (local.get 0)))) diff --git a/test/spec/shared-ref_eq.wast b/test/spec/shared-ref_eq.wast new file mode 100644 index 00000000000..662138ee6be --- /dev/null +++ b/test/spec/shared-ref_eq.wast @@ -0,0 +1,202 @@ +(module + (type $st (sub (shared (struct)))) + (type $st' (sub (shared (struct (field i32))))) + (type $at (shared (array i8))) + (type $st-sub1 (sub $st (shared (struct)))) + (type $st-sub2 (sub $st (shared (struct)))) + (type $st'-sub1 (sub $st' (shared (struct (field i32))))) + (type $st'-sub2 (sub $st' (shared (struct (field i32))))) + + (table 20 (ref null (shared eq))) + + (func (export "init") + (table.set (i32.const 0) (ref.null (shared eq))) + (table.set (i32.const 1) (ref.null (shared i31))) + (table.set (i32.const 2) (ref.i31_shared (i32.const 7))) + (table.set (i32.const 3) (ref.i31_shared (i32.const 7))) + (table.set (i32.const 4) (ref.i31_shared (i32.const 8))) + (table.set (i32.const 5) (struct.new_default $st)) + (table.set (i32.const 6) (struct.new_default $st)) + (table.set (i32.const 7) (array.new_default $at (i32.const 0))) + (table.set (i32.const 8) (array.new_default $at (i32.const 0))) + ) + + (func (export "eq") (param $i i32) (param $j i32) (result i32) + (ref.eq (table.get (local.get $i)) (table.get (local.get $j))) + ) +) + +(invoke "init") + +(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 0) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 1) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 2) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 2)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 3)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 2) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 3) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 2)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 3)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 3) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 4) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 4)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 4) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 5) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 5)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 5) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 6) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 6)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 6) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 7) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 7)) (i32.const 1)) +(assert_return (invoke "eq" (i32.const 7) (i32.const 8)) (i32.const 0)) + +(assert_return (invoke "eq" (i32.const 8) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 2)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 3)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 4)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 5)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 6)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 7)) (i32.const 0)) +(assert_return (invoke "eq" (i32.const 8) (i32.const 8)) (i32.const 1)) + +(assert_invalid + (module + (func (export "eq") (param $r (ref (shared any))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null (shared any))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null (shared func))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null (shared func))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref (shared extern))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r (ref null (shared extern))) (result i32) + (ref.eq (local.get $r) (local.get $r)) + ) + ) + "type mismatch" +) + +;; Mixed shared / unshared eq +(assert_invalid + (module + (func (export "eq") (param $r1 (ref eq)) (param $r2 (ref (shared eq))) (result i32) + (ref.eq (local.get $r1) (local.get $r2)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r1 (ref (shared eq))) (param $r2 (ref eq)) (result i32) + (ref.eq (local.get $r1) (local.get $r2)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r1 eqref) (param $r2 (ref null (shared eq))) (result i32) + (ref.eq (local.get $r1) (local.get $r2)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (export "eq") (param $r1 (ref null (shared eq))) (param $r2 eqref) (result i32) + (ref.eq (local.get $r1) (local.get $r2)) + ) + ) + "type mismatch" +) From 29746f14b8acd987ae137e2054391fc7afd3b3db Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 17 Jul 2024 19:35:26 -0400 Subject: [PATCH 464/553] [threads] Simplify and generalize heap type writing without GC (#6765) We represent `ref.null`s as having bottom heap types, even when GC is not enabled. Bottom heap types are a feature of the GC proposal, so in that case the binary writer needs to write the corresponding top type instead. We previously had separate logic for this for each type hierarchy in the binary writer, but that did not handle shared types and would not have automatically handled other new types, either. Simplify and generalize the implementation and test that we can write `ref.null`s of shared types without GC enabled. --- scripts/fuzz_opt.py | 1 + src/wasm/wasm-binary.cpp | 15 +-------------- test/lit/basic/shared-null-no-gc.wast | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 test/lit/basic/shared-null-no-gc.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index b9d42d6346d..a591f94144b 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -361,6 +361,7 @@ def is_git_repo(): 'shared-absheaptype.wast', 'type-ssa-shared.wast', 'shared-ref_eq.wast', + 'shared-null-no-gc.wast', ] diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index ee8afeb93ed..d35edadc8fd 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1629,20 +1629,7 @@ void WasmBinaryWriter::writeHeapType(HeapType type) { // only actually valid with GC. Otherwise, emit the corresponding valid top // types instead. if (!wasm->features.hasGC()) { - if (HeapType::isSubType(type, HeapType::func)) { - type = HeapType::func; - } else if (HeapType::isSubType(type, HeapType::ext)) { - type = HeapType::ext; - } else if (HeapType::isSubType(type, HeapType::exn)) { - type = HeapType::exn; - } else if (wasm->features.hasStrings()) { - // Strings are enabled, and this isn't a func or an ext, so it must be a - // string type (string or stringview), which we'll emit below, or a bottom - // type (which we must allow, because we wouldn't know whether to emit a - // string or stringview for it). - } else { - WASM_UNREACHABLE("invalid type without GC"); - } + type = type.getTop(); } if (!type.isBasic()) { diff --git a/test/lit/basic/shared-null-no-gc.wast b/test/lit/basic/shared-null-no-gc.wast new file mode 100644 index 00000000000..b920f80f8b7 --- /dev/null +++ b/test/lit/basic/shared-null-no-gc.wast @@ -0,0 +1,19 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; Test that we can write a binary without crashing when using a shared bottom +;; type without GC enabled. + +;; RUN: wasm-opt %s --enable-reference-types --enable-shared-everything --roundtrip -S -o - | filecheck %s + +(module + ;; CHECK: (func $test + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null (shared nofunc)) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test + (drop + (ref.null (shared func)) + ) + ) +) From 6b93a84032cd00840c797d52ac01a7ca3bcb913e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 17 Jul 2024 16:58:16 -0700 Subject: [PATCH 465/553] binaryen.js: Avoid catching exit, which confuses Node error reporting (#6764) Fixes https://github.com/emscripten-core/emscripten/issues/17228 This seems the right default in binaryen.js which is used as a library through npm mostly. We aren't a main program that wants to control node exclusively. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95e5be6f949..2b38f0baa49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -500,6 +500,9 @@ if(EMSCRIPTEN) target_link_libraries(binaryen_wasm optimized "-Wno-error=closure") target_link_libraries(binaryen_wasm optimized "-flto") target_link_libraries(binaryen_wasm debug "--profiling") + # Avoid catching exit as that can confuse error reporting in Node, + # see https://github.com/emscripten-core/emscripten/issues/17228 + target_link_libraries(binaryen_wasm "-sNODEJS_CATCH_EXIT=0") install(TARGETS binaryen_wasm DESTINATION ${CMAKE_INSTALL_BINDIR}) # binaryen.js JavaScript variant @@ -550,6 +553,9 @@ if(EMSCRIPTEN) target_link_libraries(binaryen_js optimized "-flto") target_link_libraries(binaryen_js debug "--profiling") target_link_libraries(binaryen_js debug "-sASSERTIONS") + # Avoid catching exit as that can confuse error reporting in Node, + # see https://github.com/emscripten-core/emscripten/issues/17228 + target_link_libraries(binaryen_js "-sNODEJS_CATCH_EXIT=0") install(TARGETS binaryen_js DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() From 08436189d3f35c958872b34bf8b0a8575e186d27 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 13:54:21 -0400 Subject: [PATCH 466/553] [threads] Simplify and generalize reftype writing without GC (#6766) Similar to #6765, but for types instead of heap types. Generalize the logic for transforming written reference types to types that are supported without GC so that it will automatically handle shared types and other new types correctly. --- scripts/fuzz_opt.py | 2 +- src/wasm/wasm-binary.cpp | 24 +++++++------------ ...ull-no-gc.wast => shared-types-no-gc.wast} | 15 ++++++++---- 3 files changed, 20 insertions(+), 21 deletions(-) rename test/lit/basic/{shared-null-no-gc.wast => shared-types-no-gc.wast} (51%) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index a591f94144b..e7826c0f35b 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -361,7 +361,7 @@ def is_git_repo(): 'shared-absheaptype.wast', 'type-ssa-shared.wast', 'shared-ref_eq.wast', - 'shared-null-no-gc.wast', + 'shared-types-no-gc.wast', ] diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index d35edadc8fd..20815b7014d 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1520,23 +1520,15 @@ void WasmBinaryWriter::writeType(Type type) { // internally use more refined versions of those types, but we cannot emit // those more refined types. if (!wasm->features.hasGC()) { - if (Type::isSubType(type, Type(HeapType::func, Nullable))) { - o << S32LEB(BinaryConsts::EncodedType::funcref); - return; - } - if (Type::isSubType(type, Type(HeapType::ext, Nullable))) { - o << S32LEB(BinaryConsts::EncodedType::externref); - return; - } - if (Type::isSubType(type, Type(HeapType::exn, Nullable))) { - o << S32LEB(BinaryConsts::EncodedType::exnref); - return; - } - if (Type::isSubType(type, Type(HeapType::string, Nullable))) { - o << S32LEB(BinaryConsts::EncodedType::stringref); - return; + auto ht = type.getHeapType(); + if (ht.isBasic() && ht.getBasic(Unshared) == HeapType::string) { + // Do not overgeneralize stringref to anyref. We have tests that when a + // stringref is expected, we actually get a stringref. If we see a + // string, the stringref feature must be enabled. + type = Type(HeapTypes::string.getBasic(ht.getShared()), Nullable); + } else { + type = Type(type.getHeapType().getTop(), Nullable); } - WASM_UNREACHABLE("bad type without GC"); } auto heapType = type.getHeapType(); if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) { diff --git a/test/lit/basic/shared-null-no-gc.wast b/test/lit/basic/shared-types-no-gc.wast similarity index 51% rename from test/lit/basic/shared-null-no-gc.wast rename to test/lit/basic/shared-types-no-gc.wast index b920f80f8b7..94c664f5847 100644 --- a/test/lit/basic/shared-null-no-gc.wast +++ b/test/lit/basic/shared-types-no-gc.wast @@ -1,19 +1,26 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; Test that we can write a binary without crashing when using a shared bottom -;; type without GC enabled. +;; Test that we can write a binary without crashing when using shared reference +;; types without GC enabled. ;; RUN: wasm-opt %s --enable-reference-types --enable-shared-everything --roundtrip -S -o - | filecheck %s (module - ;; CHECK: (func $test + ;; CHECK: (func $null ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.null (shared nofunc)) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - (func $test + (func $null (drop (ref.null (shared func)) ) ) + + ;; CHECK: (func $signature (result (ref null (shared func))) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $signature (result (ref null (shared func))) + (unreachable) + ) ) From b91966f7999175e8b03da9a7a9dcdb07e4749fb1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 18 Jul 2024 11:21:23 -0700 Subject: [PATCH 467/553] Monomorphize all the things (#6760) Previously call operands were monomorphized (considered as part of the call context, so we can create a specialized function with those operands fixed) if they were constant or had a different type than the function parameter's type. This generalizes that to pull in pretty much all the code we possibly can, including nested code. For example: (call $foo (struct.new $struct (i32.const 10) (local.get $x) (local.get $y) ) ) This can turn into (call $foo_mono (local.get $x) (local.get $y) ) The struct.new and even one of the struct.new's children is moved into the called function, replacing the original ref argument with two other ones. If the original called function was this: (func $foo (param $ref (ref ..)) .. ) then the monomorphized function then looks like this: (func $foo_mono (param $x i32) (param $y i32) (local $ref (ref ..)) (local.set $ref (struct.new $struct (i32.const 10) (local.get $x) (local.get $y) ) ) .. ) The struct.new and its constant child appear here, and we read the parameters. To do this, generalize the code that creates the call context to accept everything that is impossible to copy (like a local.get) or that would be tricky and likely unworthwhile (like another call or a tuple). Also check for effect interactions, as this code motion does some reordering. For this to work, we need to adjust how we compute the costs we compare when deciding what to monomorphize. Before we just compared the called function to the monomorphized called function, which was good enough when the call context only contained consts, but now it can contain arbitrarily nested code. The proper comparison is between these two: * Old function + call context * New monomorphized function Including the call context makes this a fair comparison. In the example above, the struct.new and the i32.const are part of the call context, and so they are in the monomorphized function, so if we didn't count them in other function we'd decide not to optimize anything with a large context. The new functionality is tested in a new file. A few parts of existing tests needed changes to not become pointless after this improvement, namely by replacing stuff that we now optimize with things that we don't like replacing an i32.eqz with a local.get. There are also a handful of test outcomes that change in CAREFUL mode due to the new cost analysis. --- src/passes/Monomorphize.cpp | 288 ++- test/lit/passes/monomorphize-consts.wast | 213 +- test/lit/passes/monomorphize-context.wast | 1805 +++++++++++++++++ test/lit/passes/monomorphize-mvp.wast | 26 +- test/lit/passes/monomorphize-types.wast | 268 +-- .../no-inline-monomorphize-inlining.wast | 64 +- 6 files changed, 2331 insertions(+), 333 deletions(-) create mode 100644 test/lit/passes/monomorphize-context.wast diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index 8c08db55bde..1fd81b9d118 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -85,13 +85,18 @@ // compute the LUB of a bunch of calls to a target and then investigate // that one case and use it in all those callers. // TODO: Not just direct calls? But updating vtables is complex. +// TODO: Should we look at no-inline flags? We do move code between functions, +// but it isn't normal inlining. // #include "ir/cost.h" +#include "ir/effects.h" #include "ir/find_all.h" +#include "ir/iteration.h" #include "ir/manipulation.h" #include "ir/module-utils.h" #include "ir/names.h" +#include "ir/properties.h" #include "ir/return-utils.h" #include "ir/type-updating.h" #include "ir/utils.h" @@ -212,33 +217,204 @@ struct CallContext { // remaining values by updating |newOperands| (for example, if all the values // sent are constants, then |newOperands| will end up empty, as we have // nothing left to send). + // + // The approach implemented here tries to move as much code into the call + // context as possible. That may not always be helpful, say in situations like + // this: + // + // (call $foo + // (i32.add + // (local.get $x) + // (local.get $y) + // ) + // ) + // + // If we move the i32.add into $foo then it will still be adding two unknown + // values (which will be parameters rather than locals). Moving the add might + // just increase code size if so. However, there are many other situations + // where the more code, the better: + // + // (call $foo + // (i32.eqz + // (local.get $x) + // ) + // ) + // + // While the value remains unknown, after moving the i32.eqz into the target + // function we may be able to use the fact that it has at most 1 bit set. + // Even larger benefits can happen in WasmGC: + // + // (call $foo + // (struct.new $T + // (local.get $x) + // (local.get $y) + // ) + // ) + // + // If the struct never escapes then we may be able to remove the allocation + // after monomorphization, even if we know nothing about the values in its + // fields. + // + // TODO: Explore other options that are more careful about how much code is + // moved. void buildFromCall(CallInfo& info, std::vector& newOperands, - Module& wasm) { + Module& wasm, + const PassOptions& options) { Builder builder(wasm); + // First, find the things we can move into the context and the things we + // cannot. Some things simply cannot be moved out of the calling function, + // such as a local.set, but also we need to handle effect interactions among + // the operands, because each time we move code into the context we are + // pushing it into the called function, which changes the order of + // operations, for example: + // + // (call $foo + // (first + // (a) + // ) + // (second + // (b) + // ) + // ) + // + // (func $foo (param $first) (param $second) + // ) + // + // If we move |first| and |a| into the context then we get this: + // + // (call $foo + // ;; |first| and |a| were removed from here. + // (second + // (b) + // ) + // ) + // + // (func $foo (param $second) + // ;; |first| is now a local, and we assign it inside the called func. + // (local $first) + // (local.set $first + // (first + // (a) + // ) + // ) + // ) + // + // After this code motion we execute |second| and |b| *before* the call, and + // |first| and |a| after, so we cannot do this transformation if the order + // of operations between them matters. + // + // The key property here is that all things that are moved into the context + // (moved into the monomorphized function) remain ordered with respect to + // each other, but must be moved past all non-moving things after them. For + // example, say we want to move B and D in this list (of expressions in + // execution order): + // + // A, B, C, D, E + // + // After moving B and D we end up with this: + // + // A, C, E and executing later in the monomorphized function: B, D + // + // Then we must be able to move B past C and E, and D past E. It is simplest + // to compute this in reverse order, starting from E and going back, and + // then each time we want to move something we can check if it can cross + // over all the non-moving effects we've seen so far. To compute this, first + // list out the post-order of the expressions, and then we'll iterate in + // reverse. + struct Lister + : public PostWalker> { + std::vector list; + void visitExpression(Expression* curr) { list.push_back(curr); } + } lister; + // As a quick estimate, we need space for at least the operands. + lister.list.reserve(operands.size()); + + for (auto* operand : info.call->operands) { + lister.walk(operand); + } + + // Go in reverse post-order as explained earlier, noting what cannot be + // moved into the context, and while accumulating the effects that are not + // moving. + std::unordered_set immovable; + EffectAnalyzer nonMovingEffects(options, wasm); + for (auto i = int64_t(lister.list.size()) - 1; i >= 0; i--) { + auto* curr = lister.list[i]; + + // This may have been marked as immovable because of the parent. We do + // that because if a parent is immovable then we can't move the children + // into the context (if we did, they would execute after the parent, but + // it needs their values). + bool currImmovable = immovable.count(curr) > 0; + if (!currImmovable) { + // This might be movable or immovable. Check both effect interactions + // (as described before, we want to move this past immovable code) and + // reasons intrinsic to the expression itself that might prevent moving. + ShallowEffectAnalyzer currEffects(options, wasm, curr); + if (currEffects.invalidates(nonMovingEffects) || + !canBeMovedIntoContext(curr, currEffects)) { + immovable.insert(curr); + currImmovable = true; + } + } + + if (currImmovable) { + // Regardless of whether this was marked immovable because of the + // parent, or because we just found it cannot be moved, accumulate the + // effects, and also mark its immediate children (so that we do the same + // when we get to them). + nonMovingEffects.visit(curr); + for (auto* child : ChildIterator(curr)) { + immovable.insert(child); + } + } + } + + // We now know which code can be moved and which cannot, so we can do the + // final processing of the call operands. We do this as a copy operation, + // copying as much as possible into the call context. Code that cannot be + // moved ends up as values sent to the monomorphized function. + // + // The copy operation works in pre-order, which allows us to override + // entire children as needed: + // + // (call $foo + // (problem + // (a) + // ) + // (later) + // ) + // + // We visit |problem| first, and if there is a problem that prevents us + // moving it into the context then we override the copy and then it and + // its child |a| remain in the caller (and |a| is never visited in the + // copy). for (auto* operand : info.call->operands) { - // Process the operand. This is a copy operation, as we are trying to move - // (copy) code from the callsite into the called function. When we find we - // can copy then we do so, and when we cannot that value remains as a - // value sent from the call. operands.push_back(ExpressionManipulator::flexibleCopy( operand, wasm, [&](Expression* child) -> Expression* { - if (canBeMovedIntoContext(child)) { - // This can be moved, great: let the copy happen. + if (!child) { + // This is an optional child that is not present. Let the copy of + // the nullptr happen. + return nullptr; + } + + if (!immovable.count(child)) { + // This can be moved; let the copy happen. return nullptr; } - // This cannot be moved, so we stop here: this is a value that is sent - // into the monomorphized function. It is a new operand in the call, - // and in the context operands it is a local.get, that reads that - // value. + // This cannot be moved. Do not copy it into the call context. In the + // example above, |problem| remains as an operand on the call (so we + // add it to |newOperands|), and in the call context all we have is a + // local.get that reads that sent value. auto paramIndex = newOperands.size(); newOperands.push_back(child); // TODO: If one operand is a tee and another a get, we could actually // reuse the local, effectively showing the monomorphized - // function that the values are the same. (But then the checks - // later down to is would need to check index too.) + // function that the values are the same. EquivalentSets may + // help here. return builder.makeLocalGet(paramIndex, child->type); })); } @@ -247,12 +423,49 @@ struct CallContext { } // Checks whether an expression can be moved into the context. - bool canBeMovedIntoContext(Expression* curr) { - // Constant numbers, funcs, strings, etc. can all be copied, so it is ok to - // add them to the context. - // TODO: Allow global.get as well, and anything else that is purely - // copyable. - return Properties::isSingleConstantExpression(curr); + bool canBeMovedIntoContext(Expression* curr, + const ShallowEffectAnalyzer& effects) { + // Pretty much everything can be moved into the context if we can copy it + // between functions, such as constants, globals, etc. The things we cannot + // copy are now checked for. + if (effects.branchesOut || effects.hasExternalBreakTargets()) { + // This branches or returns. We can't move control flow between functions. + return false; + } + if (effects.accessesLocal()) { + // Reads/writes to local state cannot be moved around. + return false; + } + if (effects.calls) { + // We can in principle move calls, but for simplicity we avoid such + // situations (which might involve recursion etc.). + return false; + } + if (Properties::isControlFlowStructure(curr)) { + // We can in principle move entire control flow structures with their + // children, but for simplicity stop when we see one rather than look + // inside to see if we could transfer all its contents. (We would also + // need to be careful when handling If arms, etc.) + return false; + } + for (auto* child : ChildIterator(curr)) { + if (child->type.isTuple()) { + // Consider this: + // + // (call $target + // (tuple.extract 2 1 + // (local.get $tuple) + // ) + // ) + // + // We cannot move the tuple.extract into the context, because then the + // call would have a tuple param. While it is possible to split up the + // tuple, or to check if we can also move the children with the parent, + // for simplicity just ignore this rare situation. + return false; + } + } + return true; } // Check if a context is trivial relative to a call, that is, the context @@ -389,7 +602,7 @@ struct Monomorphize : public Pass { // if we use that context. CallContext context; std::vector newOperands; - context.buildFromCall(info, newOperands, wasm); + context.buildFromCall(info, newOperands, wasm, getPassOptions()); // See if we've already evaluated this function + call context. If so, then // we've memoized the result. @@ -447,8 +660,22 @@ struct Monomorphize : public Pass { doOpts(func); doOpts(monoFunc.get()); + // The cost before monomorphization is the old body + the context + // operands. The operands will be *removed* from the calling code if we + // optimize, and moved into the monomorphized function, so the proper + // comparison is the context + the old body, versus the new body (which + // includes the reverse-inlined call context). auto costBefore = CostAnalyzer(func->body).cost; + for (auto* operand : context.operands) { + // Note that a slight oddity is that we have *not* optimized the + // operands before. We optimize func before and after, but the operands + // are in the calling function, which we are not modifying here. In + // theory that might lead to false positives, if the call's operands are + // very unoptimized. + costBefore += CostAnalyzer(operand).cost; + } auto costAfter = CostAnalyzer(monoFunc->body).cost; + // TODO: We should probably only accept improvements above some minimum, // to avoid optimizing cases where we duplicate a huge function but // only optimize a tiny part of it compared to the original. @@ -486,14 +713,19 @@ struct Monomorphize : public Pass { // Copy the function as the base for the new one. auto newFunc = ModuleUtils::copyFunctionWithoutAdd(func, wasm, newName); - // Generate the new signature, and apply it to the new function. + // A local.get is a value that arrives in a parameter. Anything else is + // something that we are reverse-inlining into the function, so we don't + // need a param for it. Note that we might have multiple gets nested here, + // if we are copying part of the original parameter but not all children, so + // we scan each operand for all such local.gets. + // + // Use this information to generate the new signature, and apply it to the + // new function. std::vector newParams; for (auto* operand : context.operands) { - // A local.get is a value that arrives in a parameter. Anything else is - // something that we are reverse-inlining into the function, so we don't - // need a param for it. - if (operand->is()) { - newParams.push_back(operand->type); + FindAll gets(operand); + for (auto* get : gets.list) { + newParams.push_back(get->type); } } // If we were dropped then we are pulling the drop into the monomorphized @@ -501,7 +733,7 @@ struct Monomorphize : public Pass { auto newResults = context.dropped ? Type::none : func->getResults(); newFunc->type = Signature(Type(newParams), newResults); - // We must update local indexes: the new function has a potentially + // We must update local indexes: the new function has a potentially // different number of parameters, and parameters are at the very bottom of // the local index space. We are also replacing old params with vars. To // track this, map each old index to the new one. @@ -559,7 +791,7 @@ struct Monomorphize : public Pass { // (local.get $param) ;; copied old body // ) // - // We need to add such an local.set in the prelude of the function for each + // We need to add such a local.set in the prelude of the function for each // operand in the context. std::vector pre; for (Index i = 0; i < context.operands.size(); i++) { diff --git a/test/lit/passes/monomorphize-consts.wast b/test/lit/passes/monomorphize-consts.wast index ec59edfeae5..d7136756977 100644 --- a/test/lit/passes/monomorphize-consts.wast +++ b/test/lit/passes/monomorphize-consts.wast @@ -12,85 +12,59 @@ ;; ALWAYS: (type $0 (func (param i32))) - ;; ALWAYS: (type $1 (func)) + ;; ALWAYS: (type $1 (func (param i32 i32 funcref stringref))) - ;; ALWAYS: (type $2 (func (param i32 i32 funcref stringref))) + ;; ALWAYS: (type $2 (func (param i32) (result i32))) - ;; ALWAYS: (type $3 (func (param i32) (result i32))) + ;; ALWAYS: (type $3 (func (result i32))) - ;; ALWAYS: (type $4 (func (result i32))) + ;; ALWAYS: (type $4 (func (param i32 i32))) ;; ALWAYS: (import "a" "b" (func $import (type $0) (param i32))) - ;; CAREFUL: (type $0 (func)) + ;; CAREFUL: (type $0 (func (param i32))) ;; CAREFUL: (type $1 (func (param i32 i32 funcref stringref))) - ;; CAREFUL: (type $2 (func (param i32))) + ;; CAREFUL: (type $2 (func (param i32) (result i32))) - ;; CAREFUL: (type $3 (func (param i32) (result i32))) + ;; CAREFUL: (type $3 (func (result i32))) - ;; CAREFUL: (type $4 (func (result i32))) + ;; CAREFUL: (type $4 (func (param i32 i32))) - ;; CAREFUL: (import "a" "b" (func $import (type $2) (param i32))) + ;; CAREFUL: (import "a" "b" (func $import (type $0) (param i32))) (import "a" "b" (func $import (param i32))) ;; ALWAYS: (elem declare func $calls) - ;; ALWAYS: (func $calls (type $1) + ;; ALWAYS: (func $calls (type $4) (param $x i32) (param $y i32) ;; ALWAYS-NEXT: (call $target_9 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 2) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $target_9 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 3) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $y) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $target_10 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 2) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; CAREFUL: (elem declare func $calls) - ;; CAREFUL: (func $calls (type $0) - ;; CAREFUL-NEXT: (call $target - ;; CAREFUL-NEXT: (i32.const 1) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 2) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (ref.func $calls) - ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL: (func $calls (type $4) (param $x i32) (param $y i32) + ;; CAREFUL-NEXT: (call $target_9 + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (call $target - ;; CAREFUL-NEXT: (i32.const 1) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 3) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (ref.func $calls) - ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: (call $target_9 + ;; CAREFUL-NEXT: (local.get $y) ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (call $target - ;; CAREFUL-NEXT: (i32.const 3) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 2) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (ref.func $calls) - ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: (call $target_10 + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls - ;; All but the eqz parameter are constants that can be handled. In ALWAYS - ;; mode we optimize and remove all but that one. In CAREFUL mode we end up - ;; not doing anything, as the target function's body optimizes out anyhow - ;; (so there is no benefit from monomorphization, after opts). + (func $calls (param $x i32) (param $y i32) + ;; All but the local.get are constants that can be handled. (call $target (i32.const 1) - (i32.eqz - (i32.const 2) - ) + (local.get $x) (ref.func $calls) (string.const "foo") ) @@ -100,9 +74,7 @@ ;; This will call the same refined function as the previous call. (call $target (i32.const 1) - (i32.eqz - (i32.const 3) ;; this changed - ) + (local.get $y) ;; this changed (ref.func $calls) (string.const "foo") ) @@ -111,64 +83,42 @@ ;; call a different refined function. (call $target (i32.const 3) ;; this changed - (i32.eqz - (i32.const 2) - ) + (local.get $x) (ref.func $calls) (string.const "foo") ) ) - ;; ALWAYS: (func $more-calls (type $1) + ;; ALWAYS: (func $more-calls (type $0) (param $x i32) ;; ALWAYS-NEXT: (call $target_9 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 999) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $other-target_11 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 999) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $work_12 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 999) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $more-calls (type $0) - ;; CAREFUL-NEXT: (call $target - ;; CAREFUL-NEXT: (i32.const 1) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 999) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (ref.func $calls) - ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL: (func $more-calls (type $0) (param $x i32) + ;; CAREFUL-NEXT: (call $target_9 + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (call $other-target - ;; CAREFUL-NEXT: (i32.const 1) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 999) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (ref.func $calls) - ;; CAREFUL-NEXT: (string.const "foo") + ;; CAREFUL-NEXT: (call $other-target_11 + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (call $work_9 - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 999) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $work_12 + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $more-calls + (func $more-calls (param $x i32) ;; Identical to the first call in the previous function (except for the non- ;; constant second param, which is ok to be different). We should call the ;; same refined function before, even though we are in a different ;; function here. (call $target (i32.const 1) - (i32.eqz - (i32.const 999) - ) + (local.get $x) (ref.func $calls) (string.const "foo") ) @@ -178,9 +128,7 @@ ;; a different refined function than before (call $other-target (i32.const 1) - (i32.eqz - (i32.const 999) - ) + (local.get $x) (ref.func $calls) (string.const "foo") ) @@ -190,22 +138,16 @@ ;; unlock actual work. (call $work (i32.const 3) - (i32.eqz - (i32.const 999) - ) + (local.get $x) (ref.func $calls) (string.const "foo") ) ) - ;; ALWAYS: (func $fail (type $1) + ;; ALWAYS: (func $fail (type $0) (param $x i32) ;; ALWAYS-NEXT: (call $target - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 1) - ;; ALWAYS-NEXT: ) - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 999) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: (block (result funcref) ;; ALWAYS-NEXT: (ref.func $calls) ;; ALWAYS-NEXT: ) @@ -214,14 +156,10 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $fail (type $0) + ;; CAREFUL: (func $fail (type $0) (param $x i32) ;; CAREFUL-NEXT: (call $target - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 1) - ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 999) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: (block (result funcref) ;; CAREFUL-NEXT: (ref.func $calls) ;; CAREFUL-NEXT: ) @@ -230,15 +168,11 @@ ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $fail + (func $fail (param $x i32) ;; No operand is a constant here, so we do nothing. (call $target - (i32.eqz - (i32.const 1) - ) - (i32.eqz - (i32.const 999) - ) + (local.get $x) + (local.get $x) (block (result funcref) (ref.func $calls) ) @@ -248,7 +182,7 @@ ) ) - ;; ALWAYS: (func $mutual-recursion-a (type $3) (param $x i32) (result i32) + ;; ALWAYS: (func $mutual-recursion-a (type $2) (param $x i32) (result i32) ;; ALWAYS-NEXT: (if (result i32) ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: (then @@ -264,7 +198,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $mutual-recursion-a (type $3) (param $0 i32) (result i32) + ;; CAREFUL: (func $mutual-recursion-a (type $2) (param $0 i32) (result i32) ;; CAREFUL-NEXT: (if (result i32) ;; CAREFUL-NEXT: (local.get $0) ;; CAREFUL-NEXT: (then @@ -272,9 +206,7 @@ ;; CAREFUL-NEXT: (call $mutual-recursion-b ;; CAREFUL-NEXT: (local.get $0) ;; CAREFUL-NEXT: ) - ;; CAREFUL-NEXT: (call $mutual-recursion-b - ;; CAREFUL-NEXT: (i32.const 0) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $mutual-recursion-b_13) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (else @@ -308,15 +240,15 @@ ) ) - ;; ALWAYS: (func $mutual-recursion-b (type $3) (param $x i32) (result i32) + ;; ALWAYS: (func $mutual-recursion-b (type $2) (param $x i32) (result i32) ;; ALWAYS-NEXT: (i32.add ;; ALWAYS-NEXT: (call $mutual-recursion-a_14) ;; ALWAYS-NEXT: (i32.const 1337) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $mutual-recursion-b (type $3) (param $0 i32) (result i32) + ;; CAREFUL: (func $mutual-recursion-b (type $2) (param $0 i32) (result i32) ;; CAREFUL-NEXT: (i32.add - ;; CAREFUL-NEXT: (call $mutual-recursion-a_10) + ;; CAREFUL-NEXT: (call $mutual-recursion-a_14) ;; CAREFUL-NEXT: (i32.const 1337) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) @@ -330,7 +262,7 @@ ) ) - ;; ALWAYS: (func $target (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS: (func $target (type $1) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) @@ -362,7 +294,7 @@ ) ) - ;; ALWAYS: (func $other-target (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS: (func $other-target (type $1) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $func) ;; ALWAYS-NEXT: ) @@ -395,7 +327,7 @@ ) ) - ;; ALWAYS: (func $work (type $2) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) + ;; ALWAYS: (func $work (type $1) (param $x i32) (param $y i32) (param $func funcref) (param $str stringref) ;; ALWAYS-NEXT: (call $import ;; ALWAYS-NEXT: (i32.add ;; ALWAYS-NEXT: (local.get $x) @@ -590,7 +522,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $mutual-recursion-b_13 (type $4) (result i32) +;; ALWAYS: (func $mutual-recursion-b_13 (type $3) (result i32) ;; ALWAYS-NEXT: (local $x i32) ;; ALWAYS-NEXT: (local.set $x ;; ALWAYS-NEXT: (i32.const 0) @@ -603,7 +535,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $mutual-recursion-a_14 (type $4) (result i32) +;; ALWAYS: (func $mutual-recursion-a_14 (type $3) (result i32) ;; ALWAYS-NEXT: (local $x i32) ;; ALWAYS-NEXT: (local.set $x ;; ALWAYS-NEXT: (i32.const 0) @@ -624,7 +556,19 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; CAREFUL: (func $work_9 (type $2) (param $0 i32) +;; CAREFUL: (func $target_9 (type $0) (param $0 i32) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $target_10 (type $0) (param $0 i32) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $other-target_11 (type $0) (param $0 i32) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $work_12 (type $0) (param $0 i32) ;; CAREFUL-NEXT: (call $import ;; CAREFUL-NEXT: (i32.const 3) ;; CAREFUL-NEXT: ) @@ -633,6 +577,15 @@ ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) -;; CAREFUL: (func $mutual-recursion-a_10 (type $4) (result i32) +;; CAREFUL: (func $mutual-recursion-b_13 (type $3) (result i32) +;; CAREFUL-NEXT: (i32.add +;; CAREFUL-NEXT: (call $mutual-recursion-a +;; CAREFUL-NEXT: (i32.const 0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: (i32.const 1337) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $mutual-recursion-a_14 (type $3) (result i32) ;; CAREFUL-NEXT: (i32.const 42) ;; CAREFUL-NEXT: ) diff --git a/test/lit/passes/monomorphize-context.wast b/test/lit/passes/monomorphize-context.wast new file mode 100644 index 00000000000..d3bc4a242e0 --- /dev/null +++ b/test/lit/passes/monomorphize-context.wast @@ -0,0 +1,1805 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; As in monomorphize-types.wast, test in both "always" mode, which always +;; monomorphizes, and in "careful" mode which does it only when it appears to +;; actually help. + +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL + +(module + ;; ALWAYS: (type $0 (func (param i32) (result i32))) + + ;; ALWAYS: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 anyref funcref i32 f64 i32 anyref anyref))) + + ;; ALWAYS: (type $2 (func (param i32 i32 i32 i32 i32 i32))) + + ;; ALWAYS: (type $struct (struct)) + (type $struct (struct)) + + (memory 10 20) + + ;; ALWAYS: (global $imm i32 (i32.const 10)) + ;; CAREFUL: (type $0 (func (param i32) (result i32))) + + ;; CAREFUL: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 anyref funcref i32 f64 i32 anyref anyref))) + + ;; CAREFUL: (type $2 (func (param i32 i32 i32 i32 i32 i32))) + + ;; CAREFUL: (global $imm i32 (i32.const 10)) + (global $imm i32 (i32.const 10)) + + ;; ALWAYS: (global $mut (mut i32) (i32.const 20)) + ;; CAREFUL: (global $mut (mut i32) (i32.const 20)) + (global $mut (mut i32) (i32.const 20)) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (elem declare func $target) + + ;; ALWAYS: (func $caller (type $0) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (block $out (result i32) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (br_if $out + ;; ALWAYS-NEXT: (i32.const 12) + ;; ALWAYS-NEXT: (i32.const 13) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (if (result i32) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (else + ;; ALWAYS-NEXT: (i32.const 3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $caller + ;; ALWAYS-NEXT: (i32.const 4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.tee $x + ;; ALWAYS-NEXT: (i32.const 5) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 14) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) (param $x i32) (result i32) + ;; CAREFUL-NEXT: (block $out (result i32) + ;; CAREFUL-NEXT: (call $target_2 + ;; CAREFUL-NEXT: (br_if $out + ;; CAREFUL-NEXT: (i32.const 12) + ;; CAREFUL-NEXT: (i32.const 13) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (if (result i32) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (else + ;; CAREFUL-NEXT: (i32.const 3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $caller + ;; CAREFUL-NEXT: (i32.const 4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.tee $x + ;; CAREFUL-NEXT: (i32.const 5) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 14) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller (param $x i32) (result i32) + ;; Show the variety of things we can and cannot move into the call context. + ;; + ;; Note that in CAREFUL mode we only optimize here if we properly take into + ;; account the call context in the cost. The function we are calling has + ;; an empty body, so the monomorphized function will contain basically just + ;; the moved code from the call context. If we didn't measure that in the + ;; cost before monomorphization then it would seem like we went from cost 0 + ;; (empty body) to the cost of the operations that remain after we + ;; optimize (which is the i32.load, which might trap so it remains). But if + ;; we take into account the context, then monomorphization definitely helps + ;; as it removes a bunch of constants. + (block $out (result i32) + (call $target + ;; We can't move control flow. + (br_if $out + (i32.const 12) + (i32.const 13) + ) + ;; We can't move control flow structures. + (block (result i32) + (i32.const 0) + ) + (if (result i32) + (i32.const 1) + (then + (i32.const 2) + ) + (else + (i32.const 3) + ) + ) + ;; We don't move calls. + (call $caller + (i32.const 4) + ) + ;; We can't move local operations. + (local.get $x) + (local.tee $x + (i32.const 5) + ) + ;; We can move globals, even mutable. + (global.get $imm) + (global.get $mut) + ;; We can move loads and other options that might trap. + (i32.load + (i32.const 6) + ) + ;; We can move constants. + (i32.const 7) + (ref.null any) + (ref.func $target) + ;; We can move math operations. + (i32.eqz + (i32.const 8) + ) + (f64.add + (f64.const 2.71828) + (f64.const 3.14159) + ) + ;; We can move selects. + (select + (i32.const 9) + (i32.const 10) + (i32.const 11) + ) + ;; We can move GC operations. + (ref.cast (ref null none) + (ref.null none) + ) + (struct.new $struct) + ) + (i32.const 14) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 anyref) (param $11 funcref) (param $12 i32) (param $13 f64) (param $14 i32) (param $15 anyref) (param $16 anyref) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 anyref) (param $11 funcref) (param $12 i32) (param $13 f64) (param $14 i32) (param $15 anyref) (param $16 anyref) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param anyref) + (param funcref) + (param i32) + (param f64) + (param i32) + (param anyref) + (param anyref) + ) +) + +;; ALWAYS: (func $target_2 (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) +;; ALWAYS-NEXT: (local $6 i32) +;; ALWAYS-NEXT: (local $7 i32) +;; ALWAYS-NEXT: (local $8 i32) +;; ALWAYS-NEXT: (local $9 i32) +;; ALWAYS-NEXT: (local $10 i32) +;; ALWAYS-NEXT: (local $11 i32) +;; ALWAYS-NEXT: (local $12 i32) +;; ALWAYS-NEXT: (local $13 i32) +;; ALWAYS-NEXT: (local $14 i32) +;; ALWAYS-NEXT: (local $15 i32) +;; ALWAYS-NEXT: (local $16 anyref) +;; ALWAYS-NEXT: (local $17 funcref) +;; ALWAYS-NEXT: (local $18 i32) +;; ALWAYS-NEXT: (local $19 f64) +;; ALWAYS-NEXT: (local $20 i32) +;; ALWAYS-NEXT: (local $21 anyref) +;; ALWAYS-NEXT: (local $22 anyref) +;; ALWAYS-NEXT: (local.set $6 +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $7 +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $8 +;; ALWAYS-NEXT: (local.get $2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $9 +;; ALWAYS-NEXT: (local.get $3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $10 +;; ALWAYS-NEXT: (local.get $4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $11 +;; ALWAYS-NEXT: (local.get $5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $12 +;; ALWAYS-NEXT: (global.get $imm) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $13 +;; ALWAYS-NEXT: (global.get $mut) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $14 +;; ALWAYS-NEXT: (i32.load +;; ALWAYS-NEXT: (i32.const 6) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $15 +;; ALWAYS-NEXT: (i32.const 7) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $16 +;; ALWAYS-NEXT: (ref.null none) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $17 +;; ALWAYS-NEXT: (ref.func $target) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $18 +;; ALWAYS-NEXT: (i32.eqz +;; ALWAYS-NEXT: (i32.const 8) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $19 +;; ALWAYS-NEXT: (f64.add +;; ALWAYS-NEXT: (f64.const 2.71828) +;; ALWAYS-NEXT: (f64.const 3.14159) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $20 +;; ALWAYS-NEXT: (select +;; ALWAYS-NEXT: (i32.const 9) +;; ALWAYS-NEXT: (i32.const 10) +;; ALWAYS-NEXT: (i32.const 11) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $21 +;; ALWAYS-NEXT: (ref.cast nullref +;; ALWAYS-NEXT: (ref.null none) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $22 +;; ALWAYS-NEXT: (struct.new_default $struct) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (i32.load +;; CAREFUL-NEXT: (i32.const 6) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $0 (func (param i32) (result i32))) + + ;; ALWAYS: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 anyref funcref i32 f64 i32 anyref anyref) (result i32))) + + ;; ALWAYS: (type $2 (func (param i32 i32 i32 i32 i32 i32))) + + ;; ALWAYS: (type $struct (struct)) + (type $struct (struct)) + + (memory 10 20) + + ;; ALWAYS: (global $imm i32 (i32.const 10)) + ;; CAREFUL: (type $0 (func (param i32) (result i32))) + + ;; CAREFUL: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 anyref funcref i32 f64 i32 anyref anyref) (result i32))) + + ;; CAREFUL: (type $2 (func (param i32 i32 i32 i32 i32 i32))) + + ;; CAREFUL: (global $imm i32 (i32.const 10)) + (global $imm i32 (i32.const 10)) + + ;; ALWAYS: (global $mut (mut i32) (i32.const 20)) + ;; CAREFUL: (global $mut (mut i32) (i32.const 20)) + (global $mut (mut i32) (i32.const 20)) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (elem declare func $target) + + ;; ALWAYS: (func $caller (type $0) (param $x i32) (result i32) + ;; ALWAYS-NEXT: (block $out (result i32) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (br_if $out + ;; ALWAYS-NEXT: (i32.const 12) + ;; ALWAYS-NEXT: (i32.const 13) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (if (result i32) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: (then + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (else + ;; ALWAYS-NEXT: (i32.const 3) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $caller + ;; ALWAYS-NEXT: (i32.const 4) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.tee $x + ;; ALWAYS-NEXT: (i32.const 5) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 14) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) (param $x i32) (result i32) + ;; CAREFUL-NEXT: (block $out (result i32) + ;; CAREFUL-NEXT: (call $target_2 + ;; CAREFUL-NEXT: (br_if $out + ;; CAREFUL-NEXT: (i32.const 12) + ;; CAREFUL-NEXT: (i32.const 13) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (if (result i32) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: (then + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (else + ;; CAREFUL-NEXT: (i32.const 3) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $caller + ;; CAREFUL-NEXT: (i32.const 4) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.tee $x + ;; CAREFUL-NEXT: (i32.const 5) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 14) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller (param $x i32) (result i32) + ;; As above, but now the call is dropped, so the context can include the + ;; drop. + (block $out (result i32) + (drop + (call $target + (br_if $out + (i32.const 12) + (i32.const 13) + ) + (block (result i32) + (i32.const 0) + ) + (if (result i32) + (i32.const 1) + (then + (i32.const 2) + ) + (else + (i32.const 3) + ) + ) + (call $caller + (i32.const 4) + ) + (local.get $x) + (local.tee $x + (i32.const 5) + ) + (global.get $imm) + (global.get $mut) + (i32.load + (i32.const 6) + ) + (i32.const 7) + (ref.null any) + (ref.func $target) + (i32.eqz + (i32.const 8) + ) + (f64.add + (f64.const 2.71828) + (f64.const 3.14159) + ) + (select + (i32.const 9) + (i32.const 10) + (i32.const 11) + ) + (ref.cast (ref null none) + (ref.null none) + ) + (struct.new $struct) + ) + ) + (i32.const 14) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 anyref) (param $11 funcref) (param $12 i32) (param $13 f64) (param $14 i32) (param $15 anyref) (param $16 anyref) (result i32) + ;; ALWAYS-NEXT: (local.get $7) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 anyref) (param $11 funcref) (param $12 i32) (param $13 f64) (param $14 i32) (param $15 anyref) (param $16 anyref) (result i32) + ;; CAREFUL-NEXT: (local.get $7) + ;; CAREFUL-NEXT: ) + (func $target + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param i32) + (param anyref) + (param funcref) + (param i32) + (param f64) + (param i32) + (param anyref) + (param anyref) + (result i32) + (local.get 7) + ) +) + + + + +;; ALWAYS: (func $target_2 (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) +;; ALWAYS-NEXT: (local $6 i32) +;; ALWAYS-NEXT: (local $7 i32) +;; ALWAYS-NEXT: (local $8 i32) +;; ALWAYS-NEXT: (local $9 i32) +;; ALWAYS-NEXT: (local $10 i32) +;; ALWAYS-NEXT: (local $11 i32) +;; ALWAYS-NEXT: (local $12 i32) +;; ALWAYS-NEXT: (local $13 i32) +;; ALWAYS-NEXT: (local $14 i32) +;; ALWAYS-NEXT: (local $15 i32) +;; ALWAYS-NEXT: (local $16 anyref) +;; ALWAYS-NEXT: (local $17 funcref) +;; ALWAYS-NEXT: (local $18 i32) +;; ALWAYS-NEXT: (local $19 f64) +;; ALWAYS-NEXT: (local $20 i32) +;; ALWAYS-NEXT: (local $21 anyref) +;; ALWAYS-NEXT: (local $22 anyref) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result i32) +;; ALWAYS-NEXT: (local.set $6 +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $7 +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $8 +;; ALWAYS-NEXT: (local.get $2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $9 +;; ALWAYS-NEXT: (local.get $3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $10 +;; ALWAYS-NEXT: (local.get $4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $11 +;; ALWAYS-NEXT: (local.get $5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $12 +;; ALWAYS-NEXT: (global.get $imm) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $13 +;; ALWAYS-NEXT: (global.get $mut) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $14 +;; ALWAYS-NEXT: (i32.load +;; ALWAYS-NEXT: (i32.const 6) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $15 +;; ALWAYS-NEXT: (i32.const 7) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $16 +;; ALWAYS-NEXT: (ref.null none) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $17 +;; ALWAYS-NEXT: (ref.func $target) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $18 +;; ALWAYS-NEXT: (i32.eqz +;; ALWAYS-NEXT: (i32.const 8) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $19 +;; ALWAYS-NEXT: (f64.add +;; ALWAYS-NEXT: (f64.const 2.71828) +;; ALWAYS-NEXT: (f64.const 3.14159) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $20 +;; ALWAYS-NEXT: (select +;; ALWAYS-NEXT: (i32.const 9) +;; ALWAYS-NEXT: (i32.const 10) +;; ALWAYS-NEXT: (i32.const 11) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $21 +;; ALWAYS-NEXT: (ref.cast nullref +;; ALWAYS-NEXT: (ref.null none) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $22 +;; ALWAYS-NEXT: (struct.new_default $struct) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.get $13) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (i32.load +;; CAREFUL-NEXT: (i32.const 6) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + (memory 10 20) + + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param f32))) + + ;; ALWAYS: (type $2 (func (param f64))) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (func $caller (type $0) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (block $label$1 (result f64) + ;; ALWAYS-NEXT: (f64.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (call $target_3) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param f32))) + + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (f32.demote_f64 + ;; CAREFUL-NEXT: (block $label$1 (result f64) + ;; CAREFUL-NEXT: (f64.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (call $target_2) + ;; CAREFUL-NEXT: ) + (func $caller + ;; Nesting: the f32.demote_f64 operation can be moved into the context, but + ;; its child cannot, so we stop there. (In CAREFUL mode, we end up doing + ;; nothing here, as the benefit of monomorphization is not worth it.) + (call $target + (f32.demote_f64 + (block $label$1 (result f64) + (f64.const 0) + ) + ) + ) + + ;; Now the child is an f64.abs, which can be moved into the context, so it + ;; all is moved. This ends up worthwhile in CAREFUL mode (since we can + ;; optimize all the math here). + (call $target + (f32.demote_f64 + (f64.abs ;; this changed + (f64.const 0) + ) + ) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $f32 f32) + ;; ALWAYS-NEXT: (f32.store + ;; ALWAYS-NEXT: (i32.const 42) + ;; ALWAYS-NEXT: (local.get $f32) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 f32) + ;; CAREFUL-NEXT: (f32.store + ;; CAREFUL-NEXT: (i32.const 42) + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $target (param $f32 f32) + ;; When monomorphized the first time, the param here will be f64 and not + ;; i32, showing we handle a type change. + ;; + ;; When monomorphized the second time, the param will go away entirely. + (f32.store + (i32.const 42) + (local.get $f32) + ) + ) +) + + +;; ALWAYS: (func $target_2 (type $2) (param $0 f64) +;; ALWAYS-NEXT: (local $f32 f32) +;; ALWAYS-NEXT: (local.set $f32 +;; ALWAYS-NEXT: (f32.demote_f64 +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f32.store +;; ALWAYS-NEXT: (i32.const 42) +;; ALWAYS-NEXT: (local.get $f32) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_3 (type $0) +;; ALWAYS-NEXT: (local $f32 f32) +;; ALWAYS-NEXT: (local.set $f32 +;; ALWAYS-NEXT: (f32.demote_f64 +;; ALWAYS-NEXT: (f64.abs +;; ALWAYS-NEXT: (f64.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f32.store +;; ALWAYS-NEXT: (i32.const 42) +;; ALWAYS-NEXT: (local.get $f32) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (type $0) +;; CAREFUL-NEXT: (f32.store +;; CAREFUL-NEXT: (i32.const 42) +;; CAREFUL-NEXT: (f32.const 0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $struct (struct (field (mut f32)) (field (mut f64)))) + ;; CAREFUL: (type $struct (struct (field (mut f32)) (field (mut f64)))) + (type $struct (struct (field (mut f32)) (field (mut f64)))) + + ;; ALWAYS: (type $1 (func (param f32) (result anyref))) + + ;; ALWAYS: (type $2 (func (param f64) (result anyref))) + + ;; ALWAYS: (type $3 (func (param f64))) + + ;; ALWAYS: (type $4 (func (param (ref $struct)) (result anyref))) + + ;; ALWAYS: (func $caller (type $1) (param $x f32) (result anyref) + ;; ALWAYS-NEXT: (call $target_4 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $1 (func (param f64))) + + ;; CAREFUL: (type $2 (func (param f32) (result anyref))) + + ;; CAREFUL: (type $3 (func (param f64) (result anyref))) + + ;; CAREFUL: (type $4 (func (param (ref $struct)) (result anyref))) + + ;; CAREFUL: (func $caller (type $2) (param $x f32) (result anyref) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (struct.new $struct + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (f64.const 4.2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller (param $x f32) (result anyref) + ;; We can reverse-inline the struct.new and the nested constant, leaving + ;; only the local.get as a remaining param. (In CAREFUL mode, however, this + ;; does not look promising enough to optimize.) + (call $target + (struct.new $struct + (local.get $x) + (f64.const 4.2) + ) + ) + ) + + ;; ALWAYS: (func $caller-flip (type $2) (param $x f64) (result anyref) + ;; ALWAYS-NEXT: (call $target_5 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-flip (type $3) (param $x f64) (result anyref) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (struct.new $struct + ;; CAREFUL-NEXT: (f32.const 13.369999885559082) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-flip (param $x f64) (result anyref) + ;; As above, but with struct.new's children flipped (which does not change + ;; anything). + (call $target + (struct.new $struct + (f32.const 13.37) + (local.get $x) + ) + ) + ) + + ;; ALWAYS: (func $dropped-caller (type $3) (param $x f64) + ;; ALWAYS-NEXT: (call $target_6 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $dropped-caller (type $1) (param $x f64) + ;; CAREFUL-NEXT: (call $target_4 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $dropped-caller (param $x f64) + ;; As above, but the outcome is dropped. As the target function only does + ;; some struct.sets, escape analysis after monomorphization can prove that + ;; we can remove all the code, so this is optimized in CAREFUL mode. + (drop + (call $target + (struct.new $struct + (f32.const 13.37) + (local.get $x) + ) + ) + ) + ) + + ;; ALWAYS: (func $target (type $4) (param $ref (ref $struct)) (result anyref) + ;; ALWAYS-NEXT: (struct.set $struct 0 + ;; ALWAYS-NEXT: (local.get $ref) + ;; ALWAYS-NEXT: (f32.add + ;; ALWAYS-NEXT: (struct.get $struct 0 + ;; ALWAYS-NEXT: (local.get $ref) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (f32.const 1.100000023841858) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (struct.set $struct 1 + ;; ALWAYS-NEXT: (local.get $ref) + ;; ALWAYS-NEXT: (f64.max + ;; ALWAYS-NEXT: (struct.get $struct 1 + ;; ALWAYS-NEXT: (local.get $ref) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (f64.const -1.2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $ref) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $4) (param $0 (ref $struct)) (result anyref) + ;; CAREFUL-NEXT: (struct.set $struct 0 + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (f32.add + ;; CAREFUL-NEXT: (struct.get $struct 0 + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (f32.const 1.100000023841858) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (struct.set $struct 1 + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (f64.max + ;; CAREFUL-NEXT: (struct.get $struct 1 + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (f64.const -1.2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: ) + (func $target (param $ref (ref $struct)) (result anyref) + ;; Do some operations on the reference, but do not escape it. + (struct.set $struct 0 + (local.get $ref) + (f32.add + (struct.get $struct 0 + (local.get $ref) + ) + (f32.const 1.1) + ) + ) + (struct.set $struct 1 + (local.get $ref) + (f64.max + (struct.get $struct 1 + (local.get $ref) + ) + (f64.const -1.2) + ) + ) + (local.get $ref) + ) +) + +;; ALWAYS: (func $target_4 (type $1) (param $0 f32) (result anyref) +;; ALWAYS-NEXT: (local $ref (ref $struct)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: (f64.const 4.2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result anyref) +;; ALWAYS-NEXT: (struct.set $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f32.add +;; ALWAYS-NEXT: (struct.get $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f32.const 1.100000023841858) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (struct.set $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f64.max +;; ALWAYS-NEXT: (struct.get $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f64.const -1.2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_5 (type $2) (param $0 f64) (result anyref) +;; ALWAYS-NEXT: (local $ref (ref $struct)) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (f32.const 13.369999885559082) +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result anyref) +;; ALWAYS-NEXT: (struct.set $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f32.add +;; ALWAYS-NEXT: (struct.get $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f32.const 1.100000023841858) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (struct.set $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f64.max +;; ALWAYS-NEXT: (struct.get $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f64.const -1.2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_6 (type $3) (param $0 f64) +;; ALWAYS-NEXT: (local $ref (ref $struct)) +;; ALWAYS-NEXT: (drop +;; ALWAYS-NEXT: (block (result anyref) +;; ALWAYS-NEXT: (local.set $ref +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (f32.const 13.369999885559082) +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (block (result anyref) +;; ALWAYS-NEXT: (struct.set $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f32.add +;; ALWAYS-NEXT: (struct.get $struct 0 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f32.const 1.100000023841858) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (struct.set $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: (f64.max +;; ALWAYS-NEXT: (struct.get $struct 1 +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (f64.const -1.2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.get $ref) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_4 (type $1) (param $0 f64) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $struct (struct (field i16) (field (mut i8)) (field (mut f64)))) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $struct (struct (field i16) (field (mut i8)) (field (mut f64)))) + (type $struct (struct (field i16) (field (mut i8)) (field (mut f64)))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (type $2 (func (param (ref $struct)))) + + ;; ALWAYS: (type $3 (func (param i32 f64))) + + ;; ALWAYS: (func $caller (type $1) + ;; ALWAYS-NEXT: (local $i32 i32) + ;; ALWAYS-NEXT: (local $f64 f64) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (local.get $i32) + ;; ALWAYS-NEXT: (local.get $f64) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $2 (func (param (ref $struct)))) + + ;; CAREFUL: (type $3 (func (param i32 f64))) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (local $i32 i32) + ;; CAREFUL-NEXT: (local $f64 f64) + ;; CAREFUL-NEXT: (call $target_2 + ;; CAREFUL-NEXT: (local.get $i32) + ;; CAREFUL-NEXT: (local.get $f64) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + (local $i32 i32) + (local $f64 f64) + ;; The first operand can be moved to the context, but not the other two. Of + ;; those two, the order of iteration matters, as they have different types + ;; (if we got mixed up and reordered them, we'd error). + (call $target + (struct.new $struct + (i32.const 0) + (local.get $i32) + (local.get $f64) + ) + ) + ) + + ;; ALWAYS: (func $target (type $2) (param $0 (ref $struct)) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $2) (param $0 (ref $struct)) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param (ref $struct)) + (nop) + ) +) + +;; ALWAYS: (func $target_2 (type $3) (param $0 i32) (param $1 f64) +;; ALWAYS-NEXT: (local $2 (ref $struct)) +;; ALWAYS-NEXT: (local.set $2 +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (type $3) (param $0 i32) (param $1 f64) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $array (sub (array (mut i8)))) + (type $array (sub (array (mut i8)))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (type $2 (func (param i32))) + + ;; ALWAYS: (type $3 (func (param anyref anyref) (result i32))) + + ;; ALWAYS: (type $4 (func (param i32 i32 i32))) + + ;; ALWAYS: (func $caller (type $1) + ;; ALWAYS-NEXT: (call $target_3) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32))) + + ;; CAREFUL: (type $2 (func (param anyref anyref) (result i32))) + + ;; CAREFUL: (type $3 (func (param i32 i32 i32))) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target_3) + ;; CAREFUL-NEXT: ) + (func $caller + ;; Call the target with array.new which has an optional child, the initial + ;; value. Set it in one and leave it as nullptr in the other to see we + ;; handle both properly when we move the array.new + children into the + ;; monomorphized function. + (drop + (call $target + (array.new_default $array + (i32.const 1) + ) + (array.new $array + (i32.const 2) + (i32.const 3) + ) + ) + ) + ) + + ;; ALWAYS: (func $caller-unknown (type $2) (param $x i32) + ;; ALWAYS-NEXT: (call $target_4 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-unknown (type $1) (param $x i32) + ;; CAREFUL-NEXT: (call $target_4 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-unknown (param $x i32) + ;; As above, but now there are unknown children, which are not moved. + (drop + (call $target + (array.new_default $array + (local.get $x) + ) + (array.new $array + (local.get $x) + (local.get $x) + ) + ) + ) + ) + + ;; ALWAYS: (func $target (type $3) (param $0 anyref) (param $1 anyref) (result i32) + ;; ALWAYS-NEXT: (unreachable) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $2) (param $0 anyref) (param $1 anyref) (result i32) + ;; CAREFUL-NEXT: (unreachable) + ;; CAREFUL-NEXT: ) + (func $target (param anyref) (param anyref) (result i32) + (unreachable) + ) +) + + +;; ALWAYS: (func $target_3 (type $1) +;; ALWAYS-NEXT: (local $0 anyref) +;; ALWAYS-NEXT: (local $1 anyref) +;; ALWAYS-NEXT: (local.set $0 +;; ALWAYS-NEXT: (array.new_default $array +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (array.new $array +;; ALWAYS-NEXT: (i32.const 2) +;; ALWAYS-NEXT: (i32.const 3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (unreachable) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_4 (type $4) (param $0 i32) (param $1 i32) (param $2 i32) +;; ALWAYS-NEXT: (local $3 anyref) +;; ALWAYS-NEXT: (local $4 anyref) +;; ALWAYS-NEXT: (local.set $3 +;; ALWAYS-NEXT: (array.new_default $array +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $4 +;; ALWAYS-NEXT: (array.new $array +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: (local.get $2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (unreachable) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_3 (type $0) +;; CAREFUL-NEXT: (unreachable) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $target_4 (type $3) (param $0 i32) (param $1 i32) (param $2 i32) +;; CAREFUL-NEXT: (unreachable) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $struct (struct (field anyref))) + (type $struct (struct (field anyref))) + + ;; ALWAYS: (type $1 (func (param anyref) (result anyref))) + + ;; ALWAYS: (func $caller (type $1) (param $x anyref) (result anyref) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (local.get $x) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func (param anyref) (result anyref))) + + ;; CAREFUL: (func $caller (type $0) (param $x anyref) (result anyref) + ;; CAREFUL-NEXT: (call $target_2 + ;; CAREFUL-NEXT: (local.get $x) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller (param $x anyref) (result anyref) + ;; A call with a deeply nested param. We can move all of it but the + ;; local.get into the monomorphized function. + (call $target + (struct.new $struct + (struct.new $struct + (struct.new $struct + (struct.new $struct + (struct.new $struct + (struct.new $struct + (local.get $x) + ) + ) + ) + ) + ) + ) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 anyref) (result anyref) + ;; ALWAYS-NEXT: (unreachable) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $0) (param $0 anyref) (result anyref) + ;; CAREFUL-NEXT: (unreachable) + ;; CAREFUL-NEXT: ) + (func $target (param anyref) (result anyref) + (unreachable) + ) +) + +;; ALWAYS: (func $target_2 (type $1) (param $0 anyref) (result anyref) +;; ALWAYS-NEXT: (local $1 anyref) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (unreachable) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_2 (type $0) (param $0 anyref) (result anyref) +;; CAREFUL-NEXT: (unreachable) +;; CAREFUL-NEXT: ) +(module + (memory 10 20) + + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param i32 i32))) + + ;; ALWAYS: (type $2 (func (param i32))) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (func $caller (type $0) + ;; ALWAYS-NEXT: (call $target + ;; ALWAYS-NEXT: (i32.load + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const -1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 11) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32 i32))) + + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const -1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 11) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + ;; The two operands here cannot be reordered: the first loads, and the + ;; second stores. If we move the first into the context but not the second + ;; (which is what we'd normally do: the first can be copied, while the + ;; second is a control flow structure) then we'd execute the second before + ;; the first, as we'd execute the first only after doing the call, which + ;; would be wrong. + (call $target + (i32.load + (i32.const 0) + ) + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0xffffffff) + ) + (i32.const 11) + ) + ) + ) + + ;; ALWAYS: (func $caller-flip (type $0) + ;; ALWAYS-NEXT: (call $target_3 + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const -1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 11) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-flip (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const -1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 11) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-flip + ;; With the order reversed, there is no problem: the load can be moved into + ;; the context (in ALWAYS, at least). + (call $target + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0xffffffff) + ) + (i32.const 11) + ) + (i32.load + (i32.const 0) + ) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 i32) (param $1 i32) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) (param $1 i32) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param i32) (param i32) + ) +) + +;; ALWAYS: (func $target_3 (type $2) (param $0 i32) +;; ALWAYS-NEXT: (local $1 i32) +;; ALWAYS-NEXT: (local $2 i32) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $2 +;; ALWAYS-NEXT: (i32.load +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) +(module + (memory 10 20) + + ;; ALWAYS: (type $0 (func (param i32))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (func $caller (type $1) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.load + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32))) + + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (i32.atomic.rmw8.cmpxchg_u + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + ;; Effect interaction between a parent and child: the child reads while the + ;; parent writes (and also reads), so they cannot be reordered. But the + ;; parent executes later anyhow, so it is fine to optimize the atomic + ;; operation into the context. + (call $target + (i32.atomic.rmw8.cmpxchg_u + (i32.const 0) + (block (result i32) ;; Use a block to prevent the child from being + ;; moved into the context. + (i32.load + (i32.const 0) + ) + ) + (i32.const 1) + ) + ) + ;; Note that we cannot test the reverse, since if the block were on the + ;; outside then anything inside it would not be moved. + ) + + ;; ALWAYS: (func $target (type $0) (param $0 i32) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param i32) + ) +) + +;; ALWAYS: (func $target_2 (type $0) (param $0 i32) +;; ALWAYS-NEXT: (local $1 i32) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (i32.atomic.rmw8.cmpxchg_u +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: (i32.const 1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) +(module + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $struct (struct (field i32) (field i32))) + (type $struct (struct (field i32) (field i32))) + + (memory 10 20) + + ;; ALWAYS: (type $2 (func (param anyref))) + + ;; ALWAYS: (type $3 (func (param i32 i32))) + + ;; ALWAYS: (type $4 (func (param i32))) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (func $caller (type $0) + ;; ALWAYS-NEXT: (call $target_3 + ;; ALWAYS-NEXT: (i32.load + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param anyref))) + + ;; CAREFUL: (type $2 (func (param i32 i32))) + + ;; CAREFUL: (type $3 (func (param i32))) + + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target_3 + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + ;; Effect interaction between children of a call operand. The read and write + ;; cannot be reordered, so all we can move into the call context is the + ;; struct.new. + (call $target + (struct.new $struct + (i32.load + (i32.const 0) + ) + (block (result i32) ;; Use a block to prevent the child from being + ;; moved into the context. + (i32.store + (i32.const 0) + (i32.const 1) + ) + (i32.const 2) + ) + ) + ) + ) + + ;; ALWAYS: (func $caller-flip (type $0) + ;; ALWAYS-NEXT: (call $target_4 + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const 1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 2) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-flip (type $0) + ;; CAREFUL-NEXT: (call $target_4 + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const 1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 2) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-flip + ;; With the order reversed, there is no problem, and the load can also be + ;; optimized into the context. + (call $target + (struct.new $struct + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 1) + ) + (i32.const 2) + ) + (i32.load + (i32.const 0) + ) + ) + ) + ) + + ;; ALWAYS: (func $target (type $2) (param $0 anyref) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 anyref) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param anyref) + ) +) + + +;; ALWAYS: (func $target_3 (type $3) (param $0 i32) (param $1 i32) +;; ALWAYS-NEXT: (local $2 anyref) +;; ALWAYS-NEXT: (local.set $2 +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; ALWAYS: (func $target_4 (type $4) (param $0 i32) +;; ALWAYS-NEXT: (local $1 anyref) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (struct.new $struct +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: (i32.load +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_3 (type $2) (param $0 i32) (param $1 i32) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) + +;; CAREFUL: (func $target_4 (type $3) (param $0 i32) +;; CAREFUL-NEXT: (drop +;; CAREFUL-NEXT: (i32.load +;; CAREFUL-NEXT: (i32.const 0) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +;; CAREFUL-NEXT: ) +(module + (memory 10 20) + + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param i32 i32 i32 i32 i32 i32))) + + ;; ALWAYS: (type $2 (func (param i32 i32 i32 i32 i32))) + + ;; ALWAYS: (memory $0 10 20) + + ;; ALWAYS: (func $caller (type $0) + ;; ALWAYS-NEXT: (call $target_2 + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const -1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 11) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.load + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const -1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 11) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.load + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (block (result i32) + ;; ALWAYS-NEXT: (i32.store + ;; ALWAYS-NEXT: (i32.const 0) + ;; ALWAYS-NEXT: (i32.const -1) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (i32.const 11) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32 i32 i32 i32 i32 i32))) + + ;; CAREFUL: (memory $0 10 20) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const -1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 11) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const -1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 11) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (block (result i32) + ;; CAREFUL-NEXT: (i32.store + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: (i32.const -1) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.const 11) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (i32.load + ;; CAREFUL-NEXT: (i32.const 0) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + ;; Similar to before, but with a sequence of interleaved things with + ;; interactions. The same two items repeat three times. Any load cannot be + ;; moved into the context if there is a store after it, which means that the + ;; last load can be optimized and nothing else (in CAREFUL mode, however, + ;; that ends up not worthwhile). + (call $target + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0xffffffff) + ) + (i32.const 11) + ) + (i32.load + (i32.const 0) + ) + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0xffffffff) + ) + (i32.const 11) + ) + (i32.load + (i32.const 0) + ) + (block (result i32) + (i32.store + (i32.const 0) + (i32.const 0xffffffff) + ) + (i32.const 11) + ) + (i32.load + (i32.const 0) + ) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) + ) +) + + +;; ALWAYS: (func $target_2 (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) +;; ALWAYS-NEXT: (local $5 i32) +;; ALWAYS-NEXT: (local $6 i32) +;; ALWAYS-NEXT: (local $7 i32) +;; ALWAYS-NEXT: (local $8 i32) +;; ALWAYS-NEXT: (local $9 i32) +;; ALWAYS-NEXT: (local $10 i32) +;; ALWAYS-NEXT: (local.set $5 +;; ALWAYS-NEXT: (local.get $0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $6 +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $7 +;; ALWAYS-NEXT: (local.get $2) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $8 +;; ALWAYS-NEXT: (local.get $3) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $9 +;; ALWAYS-NEXT: (local.get $4) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $10 +;; ALWAYS-NEXT: (i32.load +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) +(module + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param f32))) + + ;; ALWAYS: (func $caller (type $0) + ;; ALWAYS-NEXT: (local $tuple (tuple i32 f32)) + ;; ALWAYS-NEXT: (call $target + ;; ALWAYS-NEXT: (tuple.extract 2 1 + ;; ALWAYS-NEXT: (local.get $tuple) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param f32))) + + ;; CAREFUL: (func $caller (type $0) + ;; CAREFUL-NEXT: (local $tuple (tuple i32 f32)) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (tuple.extract 2 1 + ;; CAREFUL-NEXT: (local.get $tuple) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller + (local $tuple (tuple i32 f32)) + ;; We cannot move the tuple.extract into the context, as that would mean the + ;; new call has a tuple param. Rather than handle that somehow, ignore it. + (call $target + (tuple.extract 2 1 + (local.get $tuple) + ) + ) + ) + + ;; ALWAYS: (func $target (type $1) (param $0 f32) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $1) (param $0 f32) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param $0 f32) + ) +) + diff --git a/test/lit/passes/monomorphize-mvp.wast b/test/lit/passes/monomorphize-mvp.wast index 567a4c2ce92..ade1f68953f 100644 --- a/test/lit/passes/monomorphize-mvp.wast +++ b/test/lit/passes/monomorphize-mvp.wast @@ -12,38 +12,28 @@ ;; RUN: foreach %s %t wasm-opt --monomorphize -S -o - | filecheck %s --check-prefix CAREFUL (module - ;; ALWAYS: (type $0 (func (result i32))) + ;; ALWAYS: (type $0 (func (param i32) (result i32))) ;; ALWAYS: (type $1 (func (param i32 i32) (result i32))) - ;; ALWAYS: (type $2 (func (param i32) (result i32))) - - ;; ALWAYS: (func $call (result i32) + ;; ALWAYS: (func $call (param $x i32) (result i32) ;; ALWAYS-NEXT: (call $target_2 - ;; ALWAYS-NEXT: (i32.eqz - ;; ALWAYS-NEXT: (i32.const 2) - ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: (local.get $x) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (type $0 (func (result i32))) + ;; CAREFUL: (type $0 (func (param i32) (result i32))) ;; CAREFUL: (type $1 (func (param i32 i32) (result i32))) - ;; CAREFUL: (type $2 (func (param i32) (result i32))) - - ;; CAREFUL: (func $call (result i32) + ;; CAREFUL: (func $call (param $x i32) (result i32) ;; CAREFUL-NEXT: (call $target_2 - ;; CAREFUL-NEXT: (i32.eqz - ;; CAREFUL-NEXT: (i32.const 2) - ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: (local.get $x) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $call (result i32) + (func $call (param $x i32) (result i32) ;; The second parameter can be monomorphized. (call $target - (i32.eqz - (i32.const 2) - ) + (local.get $x) (i32.const 1) ) ) diff --git a/test/lit/passes/monomorphize-types.wast b/test/lit/passes/monomorphize-types.wast index 49ae8353abf..7d90a0f87af 100644 --- a/test/lit/passes/monomorphize-types.wast +++ b/test/lit/passes/monomorphize-types.wast @@ -10,95 +10,97 @@ ;; ALWAYS: (type $A (sub (struct))) ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) + ;; ALWAYS: (type $1 (func (param (ref $A)))) + ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $1 (func (param (ref $A)))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; ALWAYS: (type $2 (func (param (ref $A)))) - - ;; ALWAYS: (type $3 (func)) + ;; ALWAYS: (type $3 (func (param (ref $B)))) - ;; ALWAYS: (type $4 (func (param (ref $B)))) + ;; ALWAYS: (type $4 (func (param (ref $A) (ref $B)))) - ;; ALWAYS: (import "a" "b" (func $import (type $2) (param (ref $A)))) - ;; CAREFUL: (type $2 (func (param (ref $A)))) + ;; ALWAYS: (import "a" "b" (func $import (type $1) (param (ref $A)))) + ;; CAREFUL: (type $3 (func (param (ref $A) (ref $B)))) - ;; CAREFUL: (type $3 (func)) + ;; CAREFUL: (type $4 (func (param (ref $B)))) - ;; CAREFUL: (import "a" "b" (func $import (type $2) (param (ref $A)))) + ;; CAREFUL: (import "a" "b" (func $import (type $1) (param (ref $A)))) (import "a" "b" (func $import (param (ref $A)))) - ;; ALWAYS: (func $calls (type $3) + ;; ALWAYS: (func $calls (type $4) (param $A (ref $A)) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $refinable - ;; ALWAYS-NEXT: (struct.new_default $A) + ;; ALWAYS-NEXT: (local.get $A) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable - ;; ALWAYS-NEXT: (struct.new_default $A) + ;; ALWAYS-NEXT: (local.get $A) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable_4 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable_4 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $calls (type $3) + ;; CAREFUL: (func $calls (type $3) (param $A (ref $A)) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $A) + ;; CAREFUL-NEXT: (local.get $A) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $A) + ;; CAREFUL-NEXT: (local.get $A) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls + (func $calls (param $A (ref $A)) (param $B (ref $B)) ;; Two calls with $A, two with $B. The calls to $B should both go to the ;; same new function which has a refined parameter of $B. ;; ;; However, in CAREFUL mode we won't do that, as there is no helpful ;; improvement in the target functions even with the refined types. (call $refinable - (struct.new $A) + (local.get $A) ) (call $refinable - (struct.new $A) + (local.get $A) ) (call $refinable - (struct.new $B) + (local.get $B) ) (call $refinable - (struct.new $B) + (local.get $B) ) ) - ;; ALWAYS: (func $call-import (type $3) + ;; ALWAYS: (func $call-import (type $3) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $import - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $call-import (type $3) + ;; CAREFUL: (func $call-import (type $4) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $call-import + (func $call-import (param $B (ref $B)) ;; Calls to imports are left as they are. (call $import - (struct.new $B) + (local.get $B) ) ) - ;; ALWAYS: (func $refinable (type $2) (param $ref (ref $A)) + ;; ALWAYS: (func $refinable (type $1) (param $ref (ref $A)) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $refinable (type $2) (param $0 (ref $A)) + ;; CAREFUL: (func $refinable (type $1) (param $0 (ref $A)) ;; CAREFUL-NEXT: (nop) ;; CAREFUL-NEXT: ) (func $refinable (param $ref (ref $A)) @@ -115,7 +117,7 @@ ) -;; ALWAYS: (func $refinable_4 (type $4) (param $0 (ref $B)) +;; ALWAYS: (func $refinable_4 (type $3) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $ref (ref $A)) ;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $0) @@ -129,8 +131,6 @@ ;; requires a fixup. ;; ALWAYS: (type $A (sub (struct))) - ;; CAREFUL: (type $0 (func)) - ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) ;; ALWAYS: (type $B (sub $A (struct))) @@ -139,27 +139,27 @@ - ;; ALWAYS: (type $2 (func)) + ;; ALWAYS: (type $2 (func (param (ref $B)))) ;; ALWAYS: (type $3 (func (param (ref $A)))) - ;; ALWAYS: (type $4 (func (param (ref $B)))) - - ;; ALWAYS: (func $calls (type $2) + ;; ALWAYS: (func $calls (type $2) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $refinable_2 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $2 (func (param (ref $B)))) + ;; CAREFUL: (type $3 (func (param (ref $A)))) - ;; CAREFUL: (func $calls (type $0) + ;; CAREFUL: (func $calls (type $2) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls + (func $calls (param $B (ref $B)) (call $refinable - (struct.new $B) + (local.get $B) ) ) @@ -190,7 +190,7 @@ ) -;; ALWAYS: (func $refinable_2 (type $4) (param $0 (ref $B)) +;; ALWAYS: (func $refinable_2 (type $2) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $unref (ref $A)) ;; ALWAYS-NEXT: (local $ref (ref $A)) ;; ALWAYS-NEXT: (local.set $ref @@ -209,84 +209,88 @@ ;; Multiple refinings of the same function, and of different functions. ;; ALWAYS: (type $A (sub (struct))) - ;; CAREFUL: (type $0 (func)) - ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) ;; ALWAYS: (type $B (sub $A (struct))) + ;; CAREFUL: (type $1 (func (param (ref $A)))) + ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; ALWAYS: (type $2 (func)) + ;; ALWAYS: (type $2 (func (param (ref $A)))) + + ;; ALWAYS: (type $3 (func (param (ref $B)))) ;; ALWAYS: (type $C (sub $B (struct))) - ;; CAREFUL: (type $3 (func (param (ref $A)))) + ;; CAREFUL: (type $3 (func (param (ref $A) (ref $B)))) ;; CAREFUL: (type $C (sub $B (struct))) (type $C (sub $B (struct))) - ;; ALWAYS: (type $4 (func (param (ref $A)))) + ;; ALWAYS: (type $5 (func (param (ref $A) (ref $B)))) - ;; ALWAYS: (type $5 (func (param (ref $B)))) + ;; ALWAYS: (type $6 (func (param (ref $C) (ref $B)))) - ;; ALWAYS: (type $6 (func (param (ref $C)))) + ;; ALWAYS: (type $7 (func (param (ref $C)))) - ;; ALWAYS: (func $calls1 (type $2) + ;; ALWAYS: (func $calls1 (type $5) (param $A (ref $A)) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $refinable1 - ;; ALWAYS-NEXT: (struct.new_default $A) + ;; ALWAYS-NEXT: (local.get $A) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable1_4 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $calls1 (type $0) + ;; CAREFUL: (type $5 (func (param (ref $C) (ref $B)))) + + ;; CAREFUL: (func $calls1 (type $3) (param $A (ref $A)) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $refinable1 - ;; CAREFUL-NEXT: (struct.new_default $A) + ;; CAREFUL-NEXT: (local.get $A) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable1 - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls1 + (func $calls1 (param $A (ref $A)) (param $B (ref $B)) (call $refinable1 - (struct.new $A) + (local.get $A) ) (call $refinable1 - (struct.new $B) + (local.get $B) ) ) - ;; ALWAYS: (func $calls2 (type $2) + ;; ALWAYS: (func $calls2 (type $6) (param $C (ref $C)) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $refinable1_5 - ;; ALWAYS-NEXT: (struct.new_default $C) + ;; ALWAYS-NEXT: (local.get $C) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable2_6 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $calls2 (type $0) + ;; CAREFUL: (func $calls2 (type $5) (param $C (ref $C)) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $refinable1 - ;; CAREFUL-NEXT: (struct.new_default $C) + ;; CAREFUL-NEXT: (local.get $C) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable2 - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls2 + (func $calls2 (param $C (ref $C)) (param $B (ref $B)) (call $refinable1 - (struct.new $C) + (local.get $C) ) (call $refinable2 - (struct.new $B) + (local.get $B) ) ) - ;; ALWAYS: (func $refinable1 (type $4) (param $ref (ref $A)) + ;; ALWAYS: (func $refinable1 (type $2) (param $ref (ref $A)) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $refinable1 (type $3) (param $0 (ref $A)) + ;; CAREFUL: (func $refinable1 (type $1) (param $0 (ref $A)) ;; CAREFUL-NEXT: (nop) ;; CAREFUL-NEXT: ) (func $refinable1 (param $ref (ref $A)) @@ -295,12 +299,12 @@ ) ) - ;; ALWAYS: (func $refinable2 (type $4) (param $ref (ref $A)) + ;; ALWAYS: (func $refinable2 (type $2) (param $ref (ref $A)) ;; ALWAYS-NEXT: (drop ;; ALWAYS-NEXT: (local.get $ref) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $refinable2 (type $3) (param $0 (ref $A)) + ;; CAREFUL: (func $refinable2 (type $1) (param $0 (ref $A)) ;; CAREFUL-NEXT: (nop) ;; CAREFUL-NEXT: ) (func $refinable2 (param $ref (ref $A)) @@ -310,7 +314,7 @@ ) ) -;; ALWAYS: (func $refinable1_4 (type $5) (param $0 (ref $B)) +;; ALWAYS: (func $refinable1_4 (type $3) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $ref (ref $A)) ;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $0) @@ -320,7 +324,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $refinable1_5 (type $6) (param $0 (ref $C)) +;; ALWAYS: (func $refinable1_5 (type $7) (param $0 (ref $C)) ;; ALWAYS-NEXT: (local $ref (ref $A)) ;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $0) @@ -330,7 +334,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; ALWAYS: (func $refinable2_6 (type $5) (param $0 (ref $B)) +;; ALWAYS: (func $refinable2_6 (type $3) (param $0 (ref $B)) ;; ALWAYS-NEXT: (local $ref (ref $A)) ;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $0) @@ -351,72 +355,84 @@ ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; ALWAYS: (type $2 (func (param (ref $B)))) + ;; ALWAYS: (type $2 (func (param (ref $A) (ref $B)))) - ;; ALWAYS: (type $3 (func)) + ;; ALWAYS: (type $3 (func (param (ref $B)))) - ;; ALWAYS: (type $4 (func (param (ref $A)))) + ;; ALWAYS: (type $4 (func (param (ref $B) (ref $B)))) - ;; ALWAYS: (import "a" "b" (func $import (type $2) (param (ref $B)))) - ;; CAREFUL: (type $2 (func (param (ref $B)))) + ;; ALWAYS: (import "a" "b" (func $import (type $3) (param (ref $B)))) + ;; CAREFUL: (type $2 (func (param (ref $A) (ref $B)))) - ;; CAREFUL: (type $3 (func)) + ;; CAREFUL: (type $3 (func (param (ref $B)))) - ;; CAREFUL: (type $4 (func (param (ref $A)))) + ;; CAREFUL: (type $4 (func (param (ref $B) (ref $B)))) - ;; CAREFUL: (import "a" "b" (func $import (type $2) (param (ref $B)))) + ;; CAREFUL: (import "a" "b" (func $import (type $3) (param (ref $B)))) (import "a" "b" (func $import (param (ref $B)))) ;; ALWAYS: (global $global (mut i32) (i32.const 1)) ;; CAREFUL: (global $global (mut i32) (i32.const 1)) (global $global (mut i32) (i32.const 1)) - ;; ALWAYS: (func $calls (type $3) + ;; ALWAYS: (func $calls (type $2) (param $A (ref $A)) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $refinable - ;; ALWAYS-NEXT: (struct.new_default $A) + ;; ALWAYS-NEXT: (local.get $A) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable - ;; ALWAYS-NEXT: (struct.new_default $A) + ;; ALWAYS-NEXT: (local.get $A) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable_3 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (call $refinable_3 - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $calls (type $3) + ;; CAREFUL: (func $calls (type $2) (param $A (ref $A)) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $A) + ;; CAREFUL-NEXT: (local.get $A) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable - ;; CAREFUL-NEXT: (struct.new_default $A) + ;; CAREFUL-NEXT: (local.get $A) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable_3 - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $refinable_3 - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls + (func $calls (param $A (ref $A)) (param $B (ref $B)) ;; The calls sending $B will switch to calling a refined version, as the ;; refined version is better, even in CAREFUL mode. (call $refinable - (struct.new $A) + (local.get $A) + (local.get $B) ) (call $refinable - (struct.new $A) + (local.get $A) + (local.get $B) ) (call $refinable - (struct.new $B) + (local.get $B) + (local.get $B) ) (call $refinable - (struct.new $B) + (local.get $B) + (local.get $B) ) ) - ;; ALWAYS: (func $refinable (type $4) (param $ref (ref $A)) + ;; ALWAYS: (func $refinable (type $2) (param $ref (ref $A)) (param $B (ref $B)) ;; ALWAYS-NEXT: (local $x (ref $A)) ;; ALWAYS-NEXT: (call $import ;; ALWAYS-NEXT: (ref.cast (ref $B) @@ -426,7 +442,7 @@ ;; ALWAYS-NEXT: (local.set $x ;; ALWAYS-NEXT: (select (result (ref $A)) ;; ALWAYS-NEXT: (local.get $ref) - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: (global.get $global) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) @@ -446,33 +462,32 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $refinable (type $4) (param $0 (ref $A)) - ;; CAREFUL-NEXT: (local $1 (ref $B)) + ;; CAREFUL: (func $refinable (type $2) (param $0 (ref $A)) (param $1 (ref $B)) ;; CAREFUL-NEXT: (local $2 (ref $B)) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (local.tee $1 + ;; CAREFUL-NEXT: (local.tee $2 ;; CAREFUL-NEXT: (ref.cast (ref $B) ;; CAREFUL-NEXT: (local.get $0) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (local.tee $2 + ;; CAREFUL-NEXT: (local.tee $1 ;; CAREFUL-NEXT: (select (result (ref $B)) + ;; CAREFUL-NEXT: (local.get $2) ;; CAREFUL-NEXT: (local.get $1) - ;; CAREFUL-NEXT: (struct.new_default $B) ;; CAREFUL-NEXT: (global.get $global) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (local.get $2) + ;; CAREFUL-NEXT: (local.get $1) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: (call $import - ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: (local.get $2) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $refinable (param $ref (ref $A)) + (func $refinable (param $ref (ref $A)) (param $B (ref $B)) ;; Note that this large function will end up optimized in CAREFUL mode, as a ;; side effect of our keeping optimizations we run for comparison purposes. @@ -494,7 +509,7 @@ ;; Use a select here so optimizations don't just merge $x and $ref. (select (result (ref $A)) (local.get $ref) - (struct.new $B) + (local.get $B) (global.get $global) ) ) @@ -517,12 +532,16 @@ ) ) -;; ALWAYS: (func $refinable_3 (type $2) (param $0 (ref $B)) +;; ALWAYS: (func $refinable_3 (type $4) (param $0 (ref $B)) (param $1 (ref $B)) ;; ALWAYS-NEXT: (local $x (ref $A)) ;; ALWAYS-NEXT: (local $ref (ref $A)) +;; ALWAYS-NEXT: (local $B (ref $B)) ;; ALWAYS-NEXT: (local.set $ref ;; ALWAYS-NEXT: (local.get $0) ;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $B +;; ALWAYS-NEXT: (local.get $1) +;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (block ;; ALWAYS-NEXT: (call $import ;; ALWAYS-NEXT: (ref.cast (ref $B) @@ -532,7 +551,7 @@ ;; ALWAYS-NEXT: (local.set $x ;; ALWAYS-NEXT: (select (result (ref $A)) ;; ALWAYS-NEXT: (local.get $ref) -;; ALWAYS-NEXT: (struct.new_default $B) +;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: (global.get $global) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) @@ -554,8 +573,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) -;; CAREFUL: (func $refinable_3 (type $2) (param $0 (ref $B)) -;; CAREFUL-NEXT: (local $1 (ref $B)) +;; CAREFUL: (func $refinable_3 (type $4) (param $0 (ref $B)) (param $1 (ref $B)) ;; CAREFUL-NEXT: (call $import ;; CAREFUL-NEXT: (local.get $0) ;; CAREFUL-NEXT: ) @@ -563,7 +581,7 @@ ;; CAREFUL-NEXT: (local.tee $1 ;; CAREFUL-NEXT: (select (result (ref $B)) ;; CAREFUL-NEXT: (local.get $0) -;; CAREFUL-NEXT: (struct.new_default $B) +;; CAREFUL-NEXT: (local.get $1) ;; CAREFUL-NEXT: (global.get $global) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) @@ -581,30 +599,30 @@ ;; ALWAYS: (type $A (sub (struct))) ;; CAREFUL: (type $A (sub (struct))) (type $A (sub (struct))) - ;; ALWAYS: (type $1 (func (param (ref $A)))) - ;; ALWAYS: (type $B (sub $A (struct))) - ;; CAREFUL: (type $1 (func (param (ref $A)))) - ;; CAREFUL: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; ALWAYS: (func $calls (type $1) (param $ref (ref $A)) + ;; ALWAYS: (type $2 (func (param (ref $B)))) + + ;; ALWAYS: (func $calls (type $2) (param $B (ref $B)) ;; ALWAYS-NEXT: (call $calls - ;; ALWAYS-NEXT: (struct.new_default $B) + ;; ALWAYS-NEXT: (local.get $B) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) - ;; CAREFUL: (func $calls (type $1) (param $ref (ref $A)) + ;; CAREFUL: (type $2 (func (param (ref $B)))) + + ;; CAREFUL: (func $calls (type $2) (param $B (ref $B)) ;; CAREFUL-NEXT: (call $calls - ;; CAREFUL-NEXT: (struct.new_default $B) + ;; CAREFUL-NEXT: (local.get $B) ;; CAREFUL-NEXT: ) ;; CAREFUL-NEXT: ) - (func $calls (param $ref (ref $A)) + (func $calls (param $B (ref $B)) ;; We should change nothing in this recursive call, even though we are ;; sending a more refined type, so we could try to monomorphize in theory. (call $calls - (struct.new $B) + (local.get $B) ) ) ) diff --git a/test/lit/passes/no-inline-monomorphize-inlining.wast b/test/lit/passes/no-inline-monomorphize-inlining.wast index b5dc2ed39a9..2479b46f4ec 100644 --- a/test/lit/passes/no-inline-monomorphize-inlining.wast +++ b/test/lit/passes/no-inline-monomorphize-inlining.wast @@ -19,87 +19,87 @@ ;; YESINLINE: (type $B (sub $A (struct))) (type $B (sub $A (struct))) - ;; NO_INLINE: (type $2 (func)) + ;; NO_INLINE: (type $2 (func (param (ref $A) (ref $B)))) ;; NO_INLINE: (type $3 (func (param (ref $A)))) ;; NO_INLINE: (type $4 (func (param (ref $B)))) - ;; NO_INLINE: (func $calls (type $2) + ;; NO_INLINE: (func $calls (type $2) (param $A (ref $A)) (param $B (ref $B)) ;; NO_INLINE-NEXT: (call $refinable_noinline - ;; NO_INLINE-NEXT: (struct.new_default $A) + ;; NO_INLINE-NEXT: (local.get $A) ;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: (call $refinable_noinline - ;; NO_INLINE-NEXT: (struct.new_default $A) + ;; NO_INLINE-NEXT: (local.get $A) ;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: (call $refinable_noinline_2 - ;; NO_INLINE-NEXT: (struct.new_default $B) + ;; NO_INLINE-NEXT: (local.get $B) ;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: (call $refinable_noinline_2 - ;; NO_INLINE-NEXT: (struct.new_default $B) + ;; NO_INLINE-NEXT: (local.get $B) ;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: ) - ;; YESINLINE: (type $2 (func)) + ;; YESINLINE: (type $2 (func (param (ref $A) (ref $B)))) - ;; YESINLINE: (func $calls (type $2) - ;; YESINLINE-NEXT: (local $0 (ref $A)) - ;; YESINLINE-NEXT: (local $1 (ref $A)) - ;; YESINLINE-NEXT: (local $2 (ref $B)) + ;; YESINLINE: (func $calls (type $2) (param $A (ref $A)) (param $B (ref $B)) + ;; YESINLINE-NEXT: (local $2 (ref $A)) ;; YESINLINE-NEXT: (local $3 (ref $A)) ;; YESINLINE-NEXT: (local $4 (ref $B)) ;; YESINLINE-NEXT: (local $5 (ref $A)) + ;; YESINLINE-NEXT: (local $6 (ref $B)) + ;; YESINLINE-NEXT: (local $7 (ref $A)) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline - ;; YESINLINE-NEXT: (local.set $0 - ;; YESINLINE-NEXT: (struct.new_default $A) + ;; YESINLINE-NEXT: (local.set $2 + ;; YESINLINE-NEXT: (local.get $A) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $0) + ;; YESINLINE-NEXT: (local.get $2) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline$1 - ;; YESINLINE-NEXT: (local.set $1 - ;; YESINLINE-NEXT: (struct.new_default $A) + ;; YESINLINE-NEXT: (local.set $3 + ;; YESINLINE-NEXT: (local.get $A) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $1) + ;; YESINLINE-NEXT: (local.get $3) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline_2$2 - ;; YESINLINE-NEXT: (local.set $2 - ;; YESINLINE-NEXT: (struct.new_default $B) + ;; YESINLINE-NEXT: (local.set $4 + ;; YESINLINE-NEXT: (local.get $B) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block - ;; YESINLINE-NEXT: (local.set $3 - ;; YESINLINE-NEXT: (local.get $2) + ;; YESINLINE-NEXT: (local.set $5 + ;; YESINLINE-NEXT: (local.get $4) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $3) + ;; YESINLINE-NEXT: (local.get $5) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline_2$3 - ;; YESINLINE-NEXT: (local.set $4 - ;; YESINLINE-NEXT: (struct.new_default $B) + ;; YESINLINE-NEXT: (local.set $6 + ;; YESINLINE-NEXT: (local.get $B) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block - ;; YESINLINE-NEXT: (local.set $5 - ;; YESINLINE-NEXT: (local.get $4) + ;; YESINLINE-NEXT: (local.set $7 + ;; YESINLINE-NEXT: (local.get $6) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $5) + ;; YESINLINE-NEXT: (local.get $7) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) - (func $calls + (func $calls (param $A (ref $A)) (param $B (ref $B)) ;; Two calls with $A, two with $B. The calls to $B will both go to the ;; same new monomorphized function which has a refined parameter of $B. ;; @@ -108,16 +108,16 @@ ;; inline the monomorphized ones). In YESINLINE mode we will inline all 4. ;; (call $refinable_noinline - (struct.new $A) + (local.get $A) ) (call $refinable_noinline - (struct.new $A) + (local.get $A) ) (call $refinable_noinline - (struct.new $B) + (local.get $B) ) (call $refinable_noinline - (struct.new $B) + (local.get $B) ) ) From fd867a3865d079b7f9c8ec1c7fc6d02a4de28b4c Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 14:43:23 -0400 Subject: [PATCH 468/553] [threads] ref.i31_shared requires shared-everything in validation (#6767) --- scripts/fuzz_opt.py | 1 + src/wasm/wasm-validator.cpp | 6 ++++++ test/lit/validation/shared-ref-i31.wast | 12 ++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 test/lit/validation/shared-ref-i31.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index e7826c0f35b..0f3bc3f3f76 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -362,6 +362,7 @@ def is_git_repo(): 'type-ssa-shared.wast', 'shared-ref_eq.wast', 'shared-types-no-gc.wast', + 'shared-ref-i31.wast', ] diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 29e7a2c9c4b..4e167df5650 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2727,6 +2727,12 @@ void FunctionValidator::visitCallRef(CallRef* curr) { void FunctionValidator::visitRefI31(RefI31* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "ref.i31 requires gc [--enable-gc]"); + if (curr->type.isRef() && curr->type.getHeapType().isShared()) { + shouldBeTrue( + getModule()->features.hasSharedEverything(), + curr, + "ref.i31_shared requires shared-everything [--enable-shared-everything]"); + } shouldBeSubType(curr->value->type, Type::i32, curr->value, diff --git a/test/lit/validation/shared-ref-i31.wast b/test/lit/validation/shared-ref-i31.wast new file mode 100644 index 00000000000..aaab2f47f8a --- /dev/null +++ b/test/lit/validation/shared-ref-i31.wast @@ -0,0 +1,12 @@ +;; Test that ref.i31_shared requires shared-everything threads + +;; RUN: not wasm-opt %s -all --disable-shared-everything 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED + +;; NO-SHARED: ref.i31_shared requires shared-everything [--enable-shared-everything] +;; SHARED: (ref.i31_shared +;; SHARED-NEXT: (i32.const 0) + +(module + (func (drop (ref.i31_shared (i32.const 0)))) +) From a744bec7bc744182822c6b86aa3159d08dea0b3c Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 16:39:15 -0400 Subject: [PATCH 469/553] Validate features for types used in tables (#6768) We previously special-cased things like GC types, but switch to a more general solution of detecting what features a table's type requires. --- scripts/fuzz_opt.py | 1 + src/wasm/wasm-validator.cpp | 21 ++++++++------------- test/lit/validation/table-type.wast | 12 ++++++++++++ 3 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 test/lit/validation/table-type.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 0f3bc3f3f76..9036c338f87 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -363,6 +363,7 @@ def is_git_repo(): 'shared-ref_eq.wast', 'shared-types-no-gc.wast', 'shared-ref-i31.wast', + 'table-type.wast', ] diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 4e167df5650..a191d2bddf3 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3845,8 +3845,7 @@ static void validateTables(Module& module, ValidationInfo& info) { } } - Type externref = Type(HeapType::ext, Nullable); - Type funcref = Type(HeapType::func, Nullable); + auto funcref = Type(HeapType::func, Nullable); for (auto& table : module.tables) { info.shouldBeTrue(table->initial <= table->max, "table", @@ -3855,17 +3854,13 @@ static void validateTables(Module& module, ValidationInfo& info) { table->type.isNullable(), "table", "Non-nullable reference types are not yet supported for tables"); - if (!module.features.hasGC()) { - info.shouldBeTrue(table->type.isFunction() || table->type == externref, - "table", - "Only function reference types or externref are valid " - "for table type (when GC is disabled)"); - } - if (!module.features.hasGC()) { - info.shouldBeTrue(table->type == funcref || table->type == externref, - "table", - "Only funcref and externref are valid for table type " - "(when gc is disabled)"); + auto typeFeats = table->type.getFeatures(); + if (!info.shouldBeTrue(table->type == funcref || + typeFeats <= module.features, + "table", + "table type requires additional features")) { + info.getStream(nullptr) + << getMissingFeaturesList(module, typeFeats) << '\n'; } if (table->is64()) { info.shouldBeTrue(module.features.hasMemory64(), diff --git a/test/lit/validation/table-type.wast b/test/lit/validation/table-type.wast new file mode 100644 index 00000000000..e00e8f5333f --- /dev/null +++ b/test/lit/validation/table-type.wast @@ -0,0 +1,12 @@ +;; Test that the features required by table types are checked + +;; RUN: not wasm-opt %s -all --disable-shared-everything 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s -all -S -o - | filecheck %s --check-prefix SHARED + +;; NO-SHARED: table type requires additional features +;; NO-SHARED: [--enable-shared-everything] +;; SHARED: (table $t 0 0 (ref null (shared func))) + +(module + (table $t 0 0 (ref null (shared func))) +) From 7b1ef0c9023368fffd1b6eb6771cab3690295fef Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 18 Jul 2024 13:40:20 -0700 Subject: [PATCH 470/553] Monomorphization: Add a limit on the number of parameters (#6774) --- src/passes/Monomorphize.cpp | 20 ++ test/lit/passes/monomorphize-limits.wast | 400 +++++++++++++++++++++++ 2 files changed, 420 insertions(+) create mode 100644 test/lit/passes/monomorphize-limits.wast diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index 1fd81b9d118..f46e27d830d 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -102,6 +102,7 @@ #include "ir/utils.h" #include "pass.h" #include "support/hash.h" +#include "wasm-limits.h" #include "wasm-type.h" #include "wasm.h" @@ -109,6 +110,15 @@ namespace wasm { namespace { +// A limit on the number of parameters we are willing to have on monomorphized +// functions. Large numbers can lead to large stack frames, which can be slow +// and lead to stack overflows. +// TODO: Tune this and perhaps make it a flag. +const Index MaxParams = 20; +// This must be less than the corresponding Web limitation, so we do not emit +// invalid binaries. +static_assert(MaxParams < WebLimitations::MaxFunctionParams); + // Core information about a call: the call itself, and if it is dropped, the // drop. struct CallInfo { @@ -628,6 +638,16 @@ struct Monomorphize : public Pass { std::unique_ptr monoFunc = makeMonoFunctionWithContext(func, context, wasm); + // If we ended up with too many params, give up. In theory we could try to + // monomorphize in ways that use less params, but this is a rare situation + // that is not easy to handle (when we move something into the context, it + // *removes* a param, which is good, but if it has many children and end up + // not moved, that is where the problem happens, so we'd need to backtrack). + // TODO: Consider doing more here. + if (monoFunc->getNumParams() >= MaxParams) { + return; + } + // Decide whether it is worth using the monomorphized function. auto worthwhile = true; if (onlyWhenHelpful) { diff --git a/test/lit/passes/monomorphize-limits.wast b/test/lit/passes/monomorphize-limits.wast new file mode 100644 index 00000000000..7b3baee5ed2 --- /dev/null +++ b/test/lit/passes/monomorphize-limits.wast @@ -0,0 +1,400 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; As in monomorphize-types.wast, test in both "always" mode, which always +;; monomorphizes, and in "careful" mode which does it only when it appears to +;; actually help. + +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL + +(module + ;; ALWAYS: (type $0 (func)) + + ;; ALWAYS: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) + + ;; ALWAYS: (func $caller-consts (type $0) + ;; ALWAYS-NEXT: (call $many-params_3) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $1 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) + + ;; CAREFUL: (func $caller-consts (type $0) + ;; CAREFUL-NEXT: (call $many-params_3) + ;; CAREFUL-NEXT: ) + (func $caller-consts + ;; The called func has a large number of params, in fact too many for us to + ;; allow in monomorphized functions. However, all the params are constant, + ;; so they go into the call context and are no longer params, and we can + ;; optimize. + (call $many-params + (i32.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (i32.const 0) + (i32.const 5) (i32.const 5) (i32.const 5) (i32.const 5) (i32.const 5) + (i32.const 15) (i32.const 15) (i32.const 15) (i32.const 15) (i32.const 15) + (i32.const 20) (i32.const 20) (i32.const 20) (i32.const 20) (i32.const 20) + (i32.const 25) (i32.const 25) (i32.const 25) (i32.const 25) (i32.const 25) + ) + ) + + ;; ALWAYS: (func $caller-locals (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; ALWAYS-NEXT: (call $many-params + ;; ALWAYS-NEXT: (local.get $0) + ;; ALWAYS-NEXT: (local.get $1) + ;; ALWAYS-NEXT: (local.get $2) + ;; ALWAYS-NEXT: (local.get $3) + ;; ALWAYS-NEXT: (local.get $4) + ;; ALWAYS-NEXT: (local.get $5) + ;; ALWAYS-NEXT: (local.get $6) + ;; ALWAYS-NEXT: (local.get $7) + ;; ALWAYS-NEXT: (local.get $8) + ;; ALWAYS-NEXT: (local.get $9) + ;; ALWAYS-NEXT: (local.get $10) + ;; ALWAYS-NEXT: (local.get $11) + ;; ALWAYS-NEXT: (local.get $12) + ;; ALWAYS-NEXT: (local.get $13) + ;; ALWAYS-NEXT: (local.get $14) + ;; ALWAYS-NEXT: (local.get $15) + ;; ALWAYS-NEXT: (local.get $16) + ;; ALWAYS-NEXT: (local.get $17) + ;; ALWAYS-NEXT: (local.get $18) + ;; ALWAYS-NEXT: (local.get $19) + ;; ALWAYS-NEXT: (local.get $20) + ;; ALWAYS-NEXT: (local.get $21) + ;; ALWAYS-NEXT: (local.get $22) + ;; ALWAYS-NEXT: (local.get $23) + ;; ALWAYS-NEXT: (local.get $24) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-locals (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; CAREFUL-NEXT: (call $many-params + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: (local.get $2) + ;; CAREFUL-NEXT: (local.get $3) + ;; CAREFUL-NEXT: (local.get $4) + ;; CAREFUL-NEXT: (local.get $5) + ;; CAREFUL-NEXT: (local.get $6) + ;; CAREFUL-NEXT: (local.get $7) + ;; CAREFUL-NEXT: (local.get $8) + ;; CAREFUL-NEXT: (local.get $9) + ;; CAREFUL-NEXT: (local.get $10) + ;; CAREFUL-NEXT: (local.get $11) + ;; CAREFUL-NEXT: (local.get $12) + ;; CAREFUL-NEXT: (local.get $13) + ;; CAREFUL-NEXT: (local.get $14) + ;; CAREFUL-NEXT: (local.get $15) + ;; CAREFUL-NEXT: (local.get $16) + ;; CAREFUL-NEXT: (local.get $17) + ;; CAREFUL-NEXT: (local.get $18) + ;; CAREFUL-NEXT: (local.get $19) + ;; CAREFUL-NEXT: (local.get $20) + ;; CAREFUL-NEXT: (local.get $21) + ;; CAREFUL-NEXT: (local.get $22) + ;; CAREFUL-NEXT: (local.get $23) + ;; CAREFUL-NEXT: (local.get $24) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-locals + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + ;; As above, but now we send unknown local values. These would remain as + ;; parameters, so we do not optimize. + (call $many-params + (local.get 0) (local.get 1) (local.get 2) (local.get 3) (local.get 4) + (local.get 5) (local.get 6) (local.get 7) (local.get 8) (local.get 9) + (local.get 10) (local.get 11) (local.get 12) (local.get 13) (local.get 14) + (local.get 15) (local.get 16) (local.get 17) (local.get 18) (local.get 19) + (local.get 20) (local.get 21) (local.get 22) (local.get 23) (local.get 24) + ) + ) + + ;; ALWAYS: (func $many-params (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $many-params (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $many-params + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + ) +) + +;; ALWAYS: (func $many-params_3 (type $0) +;; ALWAYS-NEXT: (local $0 i32) +;; ALWAYS-NEXT: (local $1 i32) +;; ALWAYS-NEXT: (local $2 i32) +;; ALWAYS-NEXT: (local $3 i32) +;; ALWAYS-NEXT: (local $4 i32) +;; ALWAYS-NEXT: (local $5 i32) +;; ALWAYS-NEXT: (local $6 i32) +;; ALWAYS-NEXT: (local $7 i32) +;; ALWAYS-NEXT: (local $8 i32) +;; ALWAYS-NEXT: (local $9 i32) +;; ALWAYS-NEXT: (local $10 i32) +;; ALWAYS-NEXT: (local $11 i32) +;; ALWAYS-NEXT: (local $12 i32) +;; ALWAYS-NEXT: (local $13 i32) +;; ALWAYS-NEXT: (local $14 i32) +;; ALWAYS-NEXT: (local $15 i32) +;; ALWAYS-NEXT: (local $16 i32) +;; ALWAYS-NEXT: (local $17 i32) +;; ALWAYS-NEXT: (local $18 i32) +;; ALWAYS-NEXT: (local $19 i32) +;; ALWAYS-NEXT: (local $20 i32) +;; ALWAYS-NEXT: (local $21 i32) +;; ALWAYS-NEXT: (local $22 i32) +;; ALWAYS-NEXT: (local $23 i32) +;; ALWAYS-NEXT: (local $24 i32) +;; ALWAYS-NEXT: (local.set $0 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $1 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $2 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $3 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $4 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $5 +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $6 +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $7 +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $8 +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $9 +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $10 +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $11 +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $12 +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $13 +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $14 +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $15 +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $16 +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $17 +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $18 +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $19 +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $20 +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $21 +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $22 +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $23 +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (local.set $24 +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $many-params_3 (type $0) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) +(module + ;; ALWAYS: (type $array (array (mut i32))) + ;; CAREFUL: (type $0 (func)) + + ;; CAREFUL: (type $array (array (mut i32))) + (type $array (array (mut i32))) + + ;; ALWAYS: (type $1 (func)) + + ;; ALWAYS: (type $2 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) + + ;; ALWAYS: (type $3 (func (param (ref $array)))) + + ;; ALWAYS: (func $caller-consts (type $1) + ;; ALWAYS-NEXT: (call $target_3) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (type $2 (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32))) + + ;; CAREFUL: (type $3 (func (param (ref $array)))) + + ;; CAREFUL: (func $caller-consts (type $0) + ;; CAREFUL-NEXT: (call $target_3) + ;; CAREFUL-NEXT: ) + (func $caller-consts + ;; The called function has just one param, but the value sent has many + ;; children of its own. Here the children are constant, so they go into the + ;; call context, and we can optimize. + (call $target + (array.new_fixed $array 25 + (i32.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (i32.const 0) + (i32.const 5) (i32.const 5) (i32.const 5) (i32.const 5) (i32.const 5) + (i32.const 15) (i32.const 15) (i32.const 15) (i32.const 15) (i32.const 15) + (i32.const 20) (i32.const 20) (i32.const 20) (i32.const 20) (i32.const 20) + (i32.const 25) (i32.const 25) (i32.const 25) (i32.const 25) (i32.const 25) + ) + ) + ) + + ;; ALWAYS: (func $caller-locals (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; ALWAYS-NEXT: (call $target + ;; ALWAYS-NEXT: (array.new_fixed $array 25 + ;; ALWAYS-NEXT: (local.get $0) + ;; ALWAYS-NEXT: (local.get $1) + ;; ALWAYS-NEXT: (local.get $2) + ;; ALWAYS-NEXT: (local.get $3) + ;; ALWAYS-NEXT: (local.get $4) + ;; ALWAYS-NEXT: (local.get $5) + ;; ALWAYS-NEXT: (local.get $6) + ;; ALWAYS-NEXT: (local.get $7) + ;; ALWAYS-NEXT: (local.get $8) + ;; ALWAYS-NEXT: (local.get $9) + ;; ALWAYS-NEXT: (local.get $10) + ;; ALWAYS-NEXT: (local.get $11) + ;; ALWAYS-NEXT: (local.get $12) + ;; ALWAYS-NEXT: (local.get $13) + ;; ALWAYS-NEXT: (local.get $14) + ;; ALWAYS-NEXT: (local.get $15) + ;; ALWAYS-NEXT: (local.get $16) + ;; ALWAYS-NEXT: (local.get $17) + ;; ALWAYS-NEXT: (local.get $18) + ;; ALWAYS-NEXT: (local.get $19) + ;; ALWAYS-NEXT: (local.get $20) + ;; ALWAYS-NEXT: (local.get $21) + ;; ALWAYS-NEXT: (local.get $22) + ;; ALWAYS-NEXT: (local.get $23) + ;; ALWAYS-NEXT: (local.get $24) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $caller-locals (type $2) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (param $13 i32) (param $14 i32) (param $15 i32) (param $16 i32) (param $17 i32) (param $18 i32) (param $19 i32) (param $20 i32) (param $21 i32) (param $22 i32) (param $23 i32) (param $24 i32) + ;; CAREFUL-NEXT: (call $target + ;; CAREFUL-NEXT: (array.new_fixed $array 25 + ;; CAREFUL-NEXT: (local.get $0) + ;; CAREFUL-NEXT: (local.get $1) + ;; CAREFUL-NEXT: (local.get $2) + ;; CAREFUL-NEXT: (local.get $3) + ;; CAREFUL-NEXT: (local.get $4) + ;; CAREFUL-NEXT: (local.get $5) + ;; CAREFUL-NEXT: (local.get $6) + ;; CAREFUL-NEXT: (local.get $7) + ;; CAREFUL-NEXT: (local.get $8) + ;; CAREFUL-NEXT: (local.get $9) + ;; CAREFUL-NEXT: (local.get $10) + ;; CAREFUL-NEXT: (local.get $11) + ;; CAREFUL-NEXT: (local.get $12) + ;; CAREFUL-NEXT: (local.get $13) + ;; CAREFUL-NEXT: (local.get $14) + ;; CAREFUL-NEXT: (local.get $15) + ;; CAREFUL-NEXT: (local.get $16) + ;; CAREFUL-NEXT: (local.get $17) + ;; CAREFUL-NEXT: (local.get $18) + ;; CAREFUL-NEXT: (local.get $19) + ;; CAREFUL-NEXT: (local.get $20) + ;; CAREFUL-NEXT: (local.get $21) + ;; CAREFUL-NEXT: (local.get $22) + ;; CAREFUL-NEXT: (local.get $23) + ;; CAREFUL-NEXT: (local.get $24) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + ;; CAREFUL-NEXT: ) + (func $caller-locals + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + (param i32) (param i32) (param i32) (param i32) (param i32) + ;; As above, but now we send unknown local values in the nested child. Those + ;; would remain as parameters, so we do not optimize. + (call $target + (array.new_fixed $array 25 + (local.get 0) (local.get 1) (local.get 2) (local.get 3) (local.get 4) + (local.get 5) (local.get 6) (local.get 7) (local.get 8) (local.get 9) + (local.get 10) (local.get 11) (local.get 12) (local.get 13) (local.get 14) + (local.get 15) (local.get 16) (local.get 17) (local.get 18) (local.get 19) + (local.get 20) (local.get 21) (local.get 22) (local.get 23) (local.get 24) + ) + ) + ) + + ;; ALWAYS: (func $target (type $3) (param $array (ref $array)) + ;; ALWAYS-NEXT: (nop) + ;; ALWAYS-NEXT: ) + ;; CAREFUL: (func $target (type $3) (param $0 (ref $array)) + ;; CAREFUL-NEXT: (nop) + ;; CAREFUL-NEXT: ) + (func $target (param $array (ref $array)) + ) +) +;; ALWAYS: (func $target_3 (type $1) +;; ALWAYS-NEXT: (local $array (ref $array)) +;; ALWAYS-NEXT: (local.set $array +;; ALWAYS-NEXT: (array.new_fixed $array 25 +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (i32.const 0) +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: (i32.const 5) +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: (i32.const 15) +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: (i32.const 20) +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: (i32.const 25) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: ) +;; ALWAYS-NEXT: (nop) +;; ALWAYS-NEXT: ) + +;; CAREFUL: (func $target_3 (type $0) +;; CAREFUL-NEXT: (nop) +;; CAREFUL-NEXT: ) From 5a6eb1670762b1631d8236a32de38a3851183441 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 16:40:23 -0400 Subject: [PATCH 471/553] Validate features for types used in element segments (#6769) --- scripts/fuzz_opt.py | 1 + src/wasm/wasm-validator.cpp | 8 ++++++++ test/lit/validation/elem-type.wast | 12 ++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 test/lit/validation/elem-type.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 9036c338f87..f49234035c4 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -364,6 +364,7 @@ def is_git_repo(): 'shared-types-no-gc.wast', 'shared-ref-i31.wast', 'table-type.wast', + 'elem-type.wast', ] diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index a191d2bddf3..9994adf1ea7 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3877,6 +3877,14 @@ static void validateTables(Module& module, ValidationInfo& info) { segment->type.isNullable(), "elem", "Non-nullable reference types are not yet supported for tables"); + auto typeFeats = segment->type.getFeatures(); + if (!info.shouldBeTrue( + segment->type == funcref || typeFeats <= module.features, + "elem", + "element segment type requires additional features")) { + info.getStream(nullptr) + << getMissingFeaturesList(module, typeFeats) << '\n'; + } bool isPassive = !segment->table.is(); if (isPassive) { diff --git a/test/lit/validation/elem-type.wast b/test/lit/validation/elem-type.wast new file mode 100644 index 00000000000..c98593abafd --- /dev/null +++ b/test/lit/validation/elem-type.wast @@ -0,0 +1,12 @@ +;; Test that the features required by element segment types are checked + +;; RUN: not wasm-opt %s -all --disable-shared-everything 2>&1 | filecheck %s --check-prefix NO-SHARED +;; RUN: wasm-opt %s -all -S -o - | filecheck %s --check-prefix SHARED + +;; NO-SHARED: element segment type requires additional features +;; NO-SHARED: [--enable-shared-everything] +;; SHARED: (elem $e (ref null (shared func))) + +(module + (elem $e (ref null (shared func))) +) From 848a28966e58f8a9788d2e5cf15790120e06cdf6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 16:41:41 -0400 Subject: [PATCH 472/553] [threads] Update the fuzzer for shared types (#6771) Update the fuzzer to both handle shared types in initial contents and create and use new shared types without crashing or producing invalid modules. Since V8 does not have a complete implementation of shared-everything-threads yet, disable fuzzing V8 when shared-everything is enabled. To avoid losing too much coverage of V8, disable shared-everything in the fuzzer more frequently than other features. --- scripts/fuzz_opt.py | 26 ++-- src/tools/fuzzing/fuzzing.cpp | 141 +++++++++++------- src/tools/fuzzing/heap-types.cpp | 3 +- ...e-to-fuzz_all-features_metrics_noprint.txt | 83 +++++------ 4 files changed, 136 insertions(+), 117 deletions(-) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index f49234035c4..77fc664c94a 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -145,7 +145,11 @@ def randomize_feature_opts(): # 2/3 of the remaining 90% use them all. This is useful to maximize # coverage, as enabling more features enables more optimizations and # code paths, and also allows all initial contents to run. - pass + + # The shared-everything feature is new and we want to fuzz it, but it + # also currently disables fuzzing V8, so disable it most of the time. + if random.random() < 0.9: + FEATURE_OPTS.append('--disable-shared-everything') print('randomized feature opts:', '\n ' + '\n '.join(FEATURE_OPTS)) @@ -350,21 +354,6 @@ def is_git_repo(): 'exception-handling.wast', 'translate-to-new-eh.wast', 'rse-eh.wast', - # Shared types implementation in progress - 'type-merging-shared.wast', - 'shared-types.wast', - 'shared-polymorphism.wast', - 'shared-struct.wast', - 'shared-array.wast', - 'shared-i31.wast', - 'shared-null.wast', - 'shared-absheaptype.wast', - 'type-ssa-shared.wast', - 'shared-ref_eq.wast', - 'shared-types-no-gc.wast', - 'shared-ref-i31.wast', - 'table-type.wast', - 'elem-type.wast', ] @@ -847,7 +836,10 @@ def run(self, wasm, extra_d8_flags=[]): return run_vm([shared.V8, FUZZ_SHELL_JS] + shared.V8_OPTS + extra_d8_flags + ['--', wasm]) def can_run(self, wasm): - return True + # V8 does not support shared memories when running with + # shared-everything enabled, so do not fuzz shared-everything + # for now. + return all_disallowed(['shared-everything']) def can_compare_to_self(self): # With nans, VM differences can confuse us, so only very simple VMs diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 8e699fe1366..2aff7146e28 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -246,11 +246,8 @@ void TranslateToFuzzReader::setupHeapTypes() { // For GC, also generate random types. if (wasm.features.hasGC()) { - // Do not generate shared types until the fuzzer can be updated to handle - // them. - auto features = wasm.features - FeatureSet::SharedEverything; auto generator = - HeapTypeGenerator::create(random, features, upTo(MAX_NEW_GC_TYPES)); + HeapTypeGenerator::create(random, wasm.features, upTo(MAX_NEW_GC_TYPES)); auto result = generator.builder.build(); if (auto* err = result.getError()) { Fatal() << "Failed to build heap types: " << err->reason << " at index " @@ -288,10 +285,16 @@ void TranslateToFuzzReader::setupHeapTypes() { } // Basic types must be handled directly, since subTypes doesn't look at // those. + auto share = type.getShared(); + auto struct_ = HeapTypes::struct_.getBasic(share); + auto array = HeapTypes::array.getBasic(share); + auto eq = HeapTypes::eq.getBasic(share); + auto any = HeapTypes::any.getBasic(share); + auto func = HeapTypes::func.getBasic(share); if (type.isStruct()) { - interestingHeapSubTypes[HeapType::struct_].push_back(type); - interestingHeapSubTypes[HeapType::eq].push_back(type); - interestingHeapSubTypes[HeapType::any].push_back(type); + interestingHeapSubTypes[struct_].push_back(type); + interestingHeapSubTypes[eq].push_back(type); + interestingHeapSubTypes[any].push_back(type); // Note the mutable fields. auto& fields = type.getStruct().fields; @@ -301,15 +304,15 @@ void TranslateToFuzzReader::setupHeapTypes() { } } } else if (type.isArray()) { - interestingHeapSubTypes[HeapType::array].push_back(type); - interestingHeapSubTypes[HeapType::eq].push_back(type); - interestingHeapSubTypes[HeapType::any].push_back(type); + interestingHeapSubTypes[array].push_back(type); + interestingHeapSubTypes[eq].push_back(type); + interestingHeapSubTypes[any].push_back(type); if (type.getArray().element.mutable_) { mutableArrays.push_back(type); } } else if (type.isSignature()) { - interestingHeapSubTypes[HeapType::func].push_back(type); + interestingHeapSubTypes[func].push_back(type); } } @@ -2468,11 +2471,13 @@ Literal TranslateToFuzzReader::makeLiteral(Type type) { Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { auto heapType = type.getHeapType(); + auto share = heapType.getShared(); if (heapType.isBasic()) { assert(heapType.getBasic(Unshared) == HeapType::func); // With high probability, use the last created function if possible. // Otherwise, continue on to select some other function. - if (funcContext && !oneIn(4)) { + if (funcContext && funcContext->func->type.getShared() == share && + !oneIn(4)) { auto* target = funcContext->func; return builder.makeRefFunc(target->name, target->type); } @@ -2496,7 +2501,7 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { // here). if ((type.isNullable() && oneIn(2)) || (type.isNonNullable() && oneIn(16) && funcContext)) { - Expression* ret = builder.makeRefNull(HeapType::nofunc); + Expression* ret = builder.makeRefNull(HeapTypes::nofunc.getBasic(share)); if (!type.isNullable()) { assert(funcContext); ret = builder.makeRefAs(RefAsNonNull, ret); @@ -2511,7 +2516,10 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) { if (heapType.isBasic()) { // We need a specific signature type to create a function. Pick an arbitrary // signature if we only had generic 'func' here. - heapType = Signature(Type::none, Type::none); + TypeBuilder builder(1); + builder[0] = Signature(Type::none, Type::none); + builder[0].setShared(share); + heapType = (*builder.build())[0]; } auto* body = heapType.getSignature().results == Type::none ? (Expression*)builder.makeNop() @@ -2553,10 +2561,10 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { auto heapType = type.getHeapType(); assert(heapType.isBasic()); assert(wasm.features.hasReferenceTypes()); - assert(!heapType.isShared() && "TODO: handle shared types"); + auto share = heapType.getShared(); switch (heapType.getBasic(Unshared)) { case HeapType::ext: { - auto null = builder.makeRefNull(HeapType::ext); + auto null = builder.makeRefNull(HeapTypes::ext.getBasic(share)); // TODO: support actual non-nullable externrefs via imported globals or // similar. if (!type.isNullable()) { @@ -2575,12 +2583,16 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { // Choose a subtype we can materialize a constant for. We cannot // materialize non-nullable refs to func or i31 in global contexts. Nullability nullability = getSubType(type.getNullability()); - auto subtype = pick(FeatureOptions() - .add(FeatureSet::ReferenceTypes | FeatureSet::GC, - HeapType::i31, - HeapType::struct_, - HeapType::array) - .add(FeatureSet::Strings, HeapType::string)); + auto subtypeOpts = FeatureOptions().add( + FeatureSet::ReferenceTypes | FeatureSet::GC, + HeapType::i31, + HeapType::struct_, + HeapType::array); + if (share == Unshared) { + // Shared strings not yet supported. + subtypeOpts.add(FeatureSet::Strings, HeapType::string); + } + auto subtype = pick(subtypeOpts).getBasic(share); return makeConst(Type(subtype, nullability)); } case HeapType::eq: { @@ -2589,7 +2601,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { // a subtype of anyref, but we cannot create constants of it, except // for null. assert(type.isNullable()); - return builder.makeRefNull(HeapType::none); + return builder.makeRefNull(HeapTypes::none.getBasic(share)); } auto nullability = getSubType(type.getNullability()); // ref.i31 is not allowed in initializer expressions. @@ -2605,14 +2617,14 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { subtype = HeapType::array; break; } - return makeConst(Type(subtype, nullability)); + return makeConst(Type(subtype.getBasic(share), nullability)); } case HeapType::i31: { assert(wasm.features.hasGC()); if (type.isNullable() && oneIn(4)) { - return builder.makeRefNull(HeapType::none); + return builder.makeRefNull(HeapTypes::none.getBasic(share)); } - return builder.makeRefI31(makeConst(Type::i32)); + return builder.makeRefI31(makeConst(Type::i32), share); } case HeapType::struct_: { assert(wasm.features.hasGC()); @@ -2621,15 +2633,29 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { // Use a local static to avoid the expense of canonicalizing a new type // every time. static HeapType trivialStruct = HeapType(Struct()); - return builder.makeStructNew(trivialStruct, std::vector{}); + static HeapType sharedTrivialStruct = []() { + TypeBuilder builder(1); + builder[0] = Struct{}; + builder[0].setShared(); + return (*builder.build())[0]; + }(); + auto ht = share == Shared ? sharedTrivialStruct : trivialStruct; + return builder.makeStructNew(ht, std::vector{}); } case HeapType::array: { static HeapType trivialArray = HeapType(Array(Field(Field::PackedType::i8, Immutable))); - return builder.makeArrayNewFixed(trivialArray, {}); + static HeapType sharedTrivialArray = []() { + TypeBuilder builder(1); + builder[0] = Array(Field(Field::PackedType::i8, Immutable)); + builder[0].setShared(); + return (*builder.build())[0]; + }(); + auto ht = share == Shared ? sharedTrivialArray : trivialArray; + return builder.makeArrayNewFixed(ht, {}); } case HeapType::exn: { - auto null = builder.makeRefNull(HeapType::exn); + auto null = builder.makeRefNull(HeapTypes::exn.getBasic(share)); if (!type.isNullable()) { assert(funcContext); return builder.makeRefAs(RefAsNonNull, null); @@ -2638,6 +2664,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { } case HeapType::string: { // In non-function contexts all we can do is string.const. + assert(share == Unshared && "shared strings not supported"); if (!funcContext) { return makeStringConst(); } @@ -2671,7 +2698,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { case HeapType::nofunc: case HeapType::nocont: case HeapType::noexn: { - auto null = builder.makeRefNull(heapType); + auto null = builder.makeRefNull(heapType.getBasic(share)); if (!type.isNullable()) { assert(funcContext); return builder.makeRefAs(RefAsNonNull, null); @@ -4231,48 +4258,56 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) { return type; } if (type.isBasic() && oneIn(2)) { - assert(!type.isShared() && "TODO: handle shared types"); + auto share = type.getShared(); switch (type.getBasic(Unshared)) { case HeapType::func: // TODO: Typed function references. return pick(FeatureOptions() .add(FeatureSet::ReferenceTypes, HeapType::func) - .add(FeatureSet::GC, HeapType::nofunc)); + .add(FeatureSet::GC, HeapType::nofunc)) + .getBasic(share); case HeapType::cont: - return pick(HeapType::cont, HeapType::nocont); + return pick(HeapTypes::cont, HeapTypes::nocont).getBasic(share); case HeapType::ext: return pick(FeatureOptions() .add(FeatureSet::ReferenceTypes, HeapType::ext) - .add(FeatureSet::GC, HeapType::noext)); - case HeapType::any: + .add(FeatureSet::GC, HeapType::noext)) + .getBasic(share); + case HeapType::any: { assert(wasm.features.hasReferenceTypes()); assert(wasm.features.hasGC()); - return pick(FeatureOptions() - .add(FeatureSet::GC, - HeapType::any, - HeapType::eq, - HeapType::i31, - HeapType::struct_, - HeapType::array, - HeapType::none) - .add(FeatureSet::Strings, HeapType::string)); + auto options = FeatureOptions().add(FeatureSet::GC, + HeapType::any, + HeapType::eq, + HeapType::i31, + HeapType::struct_, + HeapType::array, + HeapType::none); + if (share == Unshared) { + // Shared strings not yet supported. + options.add(FeatureSet::Strings, HeapType::string); + } + return pick(options).getBasic(share); + } case HeapType::eq: assert(wasm.features.hasReferenceTypes()); assert(wasm.features.hasGC()); - return pick(HeapType::eq, - HeapType::i31, - HeapType::struct_, - HeapType::array, - HeapType::none); + return pick(HeapTypes::eq, + HeapTypes::i31, + HeapTypes::struct_, + HeapTypes::array, + HeapTypes::none) + .getBasic(share); case HeapType::i31: - return pick(HeapType::i31, HeapType::none); + return pick(HeapTypes::i31, HeapTypes::none).getBasic(share); case HeapType::struct_: - return pick(HeapType::struct_, HeapType::none); + return pick(HeapTypes::struct_, HeapTypes::none).getBasic(share); case HeapType::array: - return pick(HeapType::array, HeapType::none); + return pick(HeapTypes::array, HeapTypes::none).getBasic(share); case HeapType::exn: - return HeapType::exn; + return HeapTypes::exn.getBasic(share); case HeapType::string: + assert(share == Unshared); return HeapType::string; case HeapType::none: case HeapType::noext: diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index a1c879b4286..c1c13bc0a02 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -759,7 +759,8 @@ void Inhabitator::markExternRefsNullable() { auto children = type.getTypeChildren(); for (size_t i = 0; i < children.size(); ++i) { auto child = children[i]; - if (child.isRef() && child.getHeapType() == HeapType::ext && + if (child.isRef() && child.getHeapType().isBasic() && + child.getHeapType().getBasic(Unshared) == HeapType::ext && child.isNonNullable()) { markNullable({type, i}); } diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index aba60b9da76..6db0f908dd4 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,61 +1,52 @@ total - [exports] : 3 - [funcs] : 4 - [globals] : 24 + [exports] : 5 + [funcs] : 9 + [globals] : 26 [imports] : 5 [memories] : 1 [memory-data] : 20 [table-data] : 3 [tables] : 1 - [tags] : 1 - [total] : 846 - [vars] : 38 - ArrayCopy : 1 - ArrayGet : 3 - ArrayLen : 5 - ArrayNew : 24 - ArrayNewFixed : 1 - ArraySet : 1 + [tags] : 2 + [total] : 669 + [vars] : 27 + ArrayNew : 16 + ArrayNewFixed : 3 AtomicCmpxchg : 1 AtomicFence : 1 - AtomicNotify : 1 - AtomicRMW : 1 - Binary : 91 - Block : 75 - Break : 17 - Call : 13 - Const : 177 + Binary : 75 + Block : 70 + Break : 7 + Call : 26 + CallRef : 1 + Const : 143 Drop : 3 - GlobalGet : 50 - GlobalSet : 26 - I31Get : 2 - If : 26 - Load : 23 - LocalGet : 79 - LocalSet : 56 - Loop : 10 - MemoryCopy : 1 - Nop : 13 - Pop : 4 - RefAs : 16 - RefEq : 1 + GlobalGet : 37 + GlobalSet : 27 + I31Get : 1 + If : 20 + Load : 21 + LocalGet : 55 + LocalSet : 40 + Loop : 6 + Nop : 5 + Pop : 5 + RefAs : 2 + RefEq : 2 RefFunc : 5 - RefI31 : 5 - RefIsNull : 2 - RefNull : 23 - RefTest : 3 - Return : 2 - SIMDTernary : 1 - Select : 4 - Store : 2 + RefI31 : 2 + RefNull : 11 + RefTest : 2 + Return : 6 + Select : 2 StringConst : 6 - StringEncode : 1 + StringEq : 1 StringMeasure : 1 StringWTF16Get : 1 - StructGet : 1 - StructNew : 14 + StructNew : 17 StructSet : 1 Try : 4 - TupleMake : 6 - Unary : 29 - Unreachable : 13 + TupleExtract : 3 + TupleMake : 5 + Unary : 20 + Unreachable : 15 From 84daeca1d7bfa805825771611d563920f3ebf846 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 18 Jul 2024 16:43:16 -0400 Subject: [PATCH 473/553] [NFC] Add HeapType::isMaybeShared(BasicHeapType) utility (#6773) This abbreviates a common pattern where we first had to check whether a heap type was basic, then if it was, get its unshared version and compare it to some expected BasicHeapType. Suggested in https://github.com/WebAssembly/binaryen/pull/6771#discussion_r1683005495. --- src/literal.h | 2 +- src/tools/fuzzing/heap-types.cpp | 3 +-- src/wasm-builder.h | 3 +-- src/wasm-type.h | 6 ++++++ src/wasm/literal.cpp | 3 +-- src/wasm/wasm-binary.cpp | 2 +- src/wasm/wasm-validator.cpp | 2 +- src/wasm/wasm.cpp | 3 +-- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/literal.h b/src/literal.h index 45f76f247d8..f7703d9e604 100644 --- a/src/literal.h +++ b/src/literal.h @@ -281,7 +281,7 @@ class Literal { return i32; } int32_t geti31(bool signed_ = true) const { - assert(type.getHeapType().getBasic(Unshared) == HeapType::i31); + assert(type.getHeapType().isMaybeShared(HeapType::i31)); // Cast to unsigned for the left shift to avoid undefined behavior. return signed_ ? int32_t((uint32_t(i32) << 1)) >> 1 : (i32 & 0x7fffffff); } diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index c1c13bc0a02..7eaf23701f0 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -759,8 +759,7 @@ void Inhabitator::markExternRefsNullable() { auto children = type.getTypeChildren(); for (size_t i = 0; i < children.size(); ++i) { auto child = children[i]; - if (child.isRef() && child.getHeapType().isBasic() && - child.getHeapType().getBasic(Unshared) == HeapType::ext && + if (child.isRef() && child.getHeapType().isMaybeShared(HeapType::ext) && child.isNonNullable()) { markNullable({type, i}); } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 6663417f868..0ea41989d40 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1217,8 +1217,7 @@ class Builder { if (type.isFunction()) { return makeRefFunc(value.getFunc(), type.getHeapType()); } - if (type.isRef() && type.getHeapType().isBasic() && - type.getHeapType().getBasic(Unshared) == HeapType::i31) { + if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)) { return makeRefI31(makeConst(value.geti31()), type.getHeapType().getShared()); } diff --git a/src/wasm-type.h b/src/wasm-type.h index 69b50c07f26..b3640ff4124 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -385,6 +385,12 @@ class HeapType { Shareability getShared() const; + // Check if the type is a given basic heap type, while ignoring whether it is + // shared or not. + bool isMaybeShared(BasicHeapType type) { + return isBasic() && getBasic(Unshared) == type; + } + Signature getSignature() const; Continuation getContinuation() const; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index a49fa1b6271..6e9c3eaf4a1 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -57,8 +57,7 @@ Literal::Literal(Type type) : type(type) { return; } - if (type.isRef() && type.getHeapType().isBasic() && - type.getHeapType().getBasic(Unshared) == HeapType::i31) { + if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)) { assert(type.isNonNullable()); i32 = 0; return; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 20815b7014d..0a65fbadbf4 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1521,7 +1521,7 @@ void WasmBinaryWriter::writeType(Type type) { // those more refined types. if (!wasm->features.hasGC()) { auto ht = type.getHeapType(); - if (ht.isBasic() && ht.getBasic(Unshared) == HeapType::string) { + if (ht.isMaybeShared(HeapType::string)) { // Do not overgeneralize stringref to anyref. We have tests that when a // stringref is expected, we actually get a stringref. If we see a // string, the stringref feature must be enabled. diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 9994adf1ea7..287ab2e8fc4 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2910,7 +2910,7 @@ void FunctionValidator::visitStructSet(StructSet* curr) { return; } auto type = curr->ref->type.getHeapType(); - if (type.isBasic() && type.getBasic(Unshared) == HeapType::none) { + if (type.isMaybeShared(HeapType::none)) { return; } if (!shouldBeTrue( diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index c4f02128e6c..4c30a4e32bd 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -964,8 +964,7 @@ void RefI31::finalize() { if (value->type == Type::unreachable) { type = Type::unreachable; } else { - assert(type.isRef() && type.getHeapType().isBasic() && - type.getHeapType().getBasic(Unshared) == HeapType::i31); + assert(type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)); } } From a8066e6618b93ea101e82b64690b9b62d7562609 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 18 Jul 2024 14:46:23 -0700 Subject: [PATCH 474/553] Heap2Local: Properly handle failing array casts (#6772) Followup to #6727 which added support for failing casts in Struct2Local, but it turns out that it required Array2Struct changes as well. Specifically, when we turn an array into a struct then casts can look like they behave differently (what used to be an array input, becomes a struct), so like with RefTest that we already handled, check if the cast succeeds in the original form and handle that. --- src/passes/Heap2Local.cpp | 44 +++++++++-- test/lit/passes/heap2local.wast | 125 ++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 5 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 1e747d6ab99..c8d478ad586 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -862,6 +862,11 @@ struct Array2Struct : PostWalker { // The original type of the allocation, before we turn it into a struct. Type originalType; + // The type of the struct we are changing to (nullable and non-nullable + // variations). + Type nullStruct; + Type nonNullStruct; + Array2Struct(Expression* allocation, EscapeAnalyzer& analyzer, Function* func, @@ -928,9 +933,15 @@ struct Array2Struct : PostWalker { // lowered away to locals anyhow. auto nullArray = Type(arrayType, Nullable); auto nonNullArray = Type(arrayType, NonNullable); - auto nullStruct = Type(structType, Nullable); - auto nonNullStruct = Type(structType, NonNullable); + nullStruct = Type(structType, Nullable); + nonNullStruct = Type(structType, NonNullable); for (auto* reached : analyzer.reached) { + if (reached->is()) { + // Casts must be handled later: We need to see the old type, and to + // potentially replace the cast based on that, see below. + continue; + } + // We must check subtyping here because the allocation may be upcast as it // flows around. If we do see such upcasting then we are refining here and // must refinalize. @@ -1032,15 +1043,14 @@ struct Array2Struct : PostWalker { } // Some additional operations need special handling + void visitRefTest(RefTest* curr) { if (!analyzer.reached.count(curr)) { return; } // When we ref.test an array allocation, we cannot simply turn the array - // into a struct, as then the test will behave different. (Note that this is - // not a problem for ref.*cast*, as the cast simply goes away when the value - // flows through, and we verify it will do so in the escape analysis.) To + // into a struct, as then the test will behave differently. To properly // handle this, check if the test succeeds or not, and write out the outcome // here (similar to Struct2Local::visitRefTest). Note that we test on // |originalType| here and not |allocation->type|, as the allocation has @@ -1050,6 +1060,30 @@ struct Array2Struct : PostWalker { builder.makeConst(Literal(result)))); } + void visitRefCast(RefCast* curr) { + if (!analyzer.reached.count(curr)) { + return; + } + + // As with RefTest, we need to check if the cast succeeds with the array + // type before we turn it into a struct type (as after that change, the + // outcome of the cast will look different). + if (!Type::isSubType(originalType, curr->type)) { + // The cast fails, ensure we trap with an unreachable. + replaceCurrent(builder.makeSequence(builder.makeDrop(curr), + builder.makeUnreachable())); + } else { + // The cast succeeds. Update the type. (It is ok to use the non-nullable + // type here unconditionally, since we know the allocation flows through + // here, and anyhow we will be removing the reference during Struct2Local, + // later.) + curr->type = nonNullStruct; + } + + // Regardless of how we altered the type here, refinalize. + refinalize = true; + } + // Get the value in an expression we know must contain a constant index. Index getIndex(Expression* curr) { return curr->cast()->value.getUnsigned(); diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 2ce3e12dd88..2e38b7e4e3d 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -4303,3 +4303,128 @@ ) ) ) + +;; Array casts to structs and arrays. +(module + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $0 (func (result (ref struct)))) + (type $0 (func (result (ref struct)))) + ;; CHECK: (type $3 (func (result structref))) + + ;; CHECK: (type $4 (func (result (ref array)))) + + ;; CHECK: (type $array (array i8)) + (type $array (array i8)) + + ;; CHECK: (func $array.cast.struct (type $0) (result (ref struct)) + ;; CHECK-NEXT: (local $eq (ref eq)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $array.cast.struct (result (ref struct)) + (local $eq (ref eq)) + ;; This cast will fail: we cast an array to struct. That we go through + ;; (ref eq) in the middle, which seems like it could cast to struct, should + ;; not confuse us. And, as the cast fails, the reference does not escape. + ;; We can optimize here and will emit an unreachable for the failing cast. + (ref.cast (ref struct) + (local.tee $eq + (array.new_fixed $array 0) + ) + ) + ) + + ;; CHECK: (func $array.cast.struct.null (type $3) (result structref) + ;; CHECK-NEXT: (local $eq (ref eq)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $array.cast.struct.null (result (ref null struct)) + (local $eq (ref eq)) + ;; As above but the cast is to a nullable type, which changes nothing. + (ref.cast (ref null struct) + (local.tee $eq + (array.new_fixed $array 0) + ) + ) + ) + + ;; CHECK: (func $array.cast.array (type $4) (result (ref array)) + ;; CHECK-NEXT: (local $eq (ref eq)) + ;; CHECK-NEXT: (ref.cast (ref array) + ;; CHECK-NEXT: (local.tee $eq + ;; CHECK-NEXT: (array.new_fixed $array 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array.cast.array (result (ref array)) + (local $eq (ref eq)) + ;; Now we cast to array, and the cast succeeds, so we escape, and do + ;; nothing to optimize. + (ref.cast (ref array) + (local.tee $eq + (array.new_fixed $array 0) + ) + ) + ) + + ;; CHECK: (func $array.cast.array.set (type $1) + ;; CHECK-NEXT: (local $eq (ref eq)) + ;; CHECK-NEXT: (local $array (ref array)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array.cast.array.set + (local $eq (ref eq)) + (local $array (ref array)) + ;; As above, but now we store the result in a local rather than return it + ;; out, so it does not escape. + (local.set $array + (ref.cast (ref array) + (local.tee $eq + (array.new_fixed $array 0) + ) + ) + ) + ) + + ;; CHECK: (func $array.cast.struct.set (type $1) + ;; CHECK-NEXT: (local $eq (ref eq)) + ;; CHECK-NEXT: (local $struct (ref struct)) + ;; CHECK-NEXT: (local.tee $struct + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array.cast.struct.set + (local $eq (ref eq)) + (local $struct (ref struct)) + ;; As above, but now the cast fails and is stored to a struct local. We do not + ;; escape and we emit an unreachable for the cast. + (local.set $struct + (ref.cast (ref struct) + (local.tee $eq + (array.new_fixed $array 0) + ) + ) + ) + ) +) From 0973589200fc2b9a5d413a340667811748837289 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Mon, 22 Jul 2024 17:20:46 -0700 Subject: [PATCH 475/553] Make FunctionInfo's assignment operator argument const (#6780) Aside from the fact that there's no need for this to be non-const and this is the usual way to write an assignment operator, this is also needed because of a recent change to std::pair (https://github.com/llvm/llvm-project/pull/89652). This seems to be forcing pair to want the const version of the assignment operator of its members. --- src/passes/Inlining.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 9e0d3eb6740..e67a0f35bf7 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -103,7 +103,7 @@ struct FunctionInfo { } // Provide an explicit = operator as the |refs| field lacks one by default. - FunctionInfo& operator=(FunctionInfo& other) { + FunctionInfo& operator=(const FunctionInfo& other) { refs = other.refs.load(); size = other.size; hasCalls = other.hasCalls; From 538c5288be3c946b8d6a7ac467d13ebc793ee38a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 23 Jul 2024 16:02:59 -0400 Subject: [PATCH 476/553] [threads] Calculate shared heap type depths in subtypes.h (#6777) Fixes #6776. --- src/ir/subtypes.h | 21 ++++++++++----- test/gtest/type-builder.cpp | 51 +++++++++++++++++++++++++---------- test/lit/passes/gufa-tnh.wast | 29 ++++++++++++++++++++ 3 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h index 8645afb9898..767c79fd7ca 100644 --- a/src/ir/subtypes.h +++ b/src/ir/subtypes.h @@ -124,20 +124,27 @@ struct SubTypes { // Add the max depths of basic types. for (auto type : types) { HeapType basic; + auto share = type.getShared(); if (type.isStruct()) { - basic = HeapType::struct_; + basic = HeapTypes::struct_.getBasic(share); } else if (type.isArray()) { - basic = HeapType::array; + basic = HeapTypes::array.getBasic(share); } else { assert(type.isSignature()); - basic = HeapType::func; + basic = HeapTypes::func.getBasic(share); } - depths[basic] = std::max(depths[basic], depths[type] + 1); + auto& basicDepth = depths[basic]; + basicDepth = std::max(basicDepth, depths[type] + 1); } - depths[HeapType::eq] = - std::max(depths[HeapType::struct_], depths[HeapType::array]) + 1; - depths[HeapType::any] = depths[HeapType::eq] + 1; + for (auto share : {Unshared, Shared}) { + depths[HeapTypes::eq.getBasic(share)] = + std::max(depths[HeapTypes::struct_.getBasic(share)], + depths[HeapTypes::array.getBasic(share)]) + + 1; + depths[HeapTypes::any.getBasic(share)] = + depths[HeapTypes::eq.getBasic(share)] + 1; + } return depths; } diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index 2ad43d18980..97943551f5b 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -1110,12 +1110,18 @@ TEST_F(TypeTest, TestSubtypeErrors) { TEST_F(TypeTest, TestSubTypes) { Type anyref = Type(HeapType::any, Nullable); Type eqref = Type(HeapType::eq, Nullable); + Type sharedAnyref = Type(HeapTypes::any.getBasic(Shared), Nullable); + Type sharedEqref = Type(HeapTypes::eq.getBasic(Shared), Nullable); // Build type types, the second of which is a subtype. - TypeBuilder builder(2); + TypeBuilder builder(4); builder[0].setOpen() = Struct({Field(anyref, Immutable)}); builder[1].setOpen() = Struct({Field(eqref, Immutable)}); + // Make shared versions, too. + builder[2].setOpen().setShared() = Array(Field(sharedAnyref, Immutable)); + builder[3].setOpen().setShared() = Array(Field(sharedEqref, Immutable)); builder[1].subTypeOf(builder[0]); + builder[3].subTypeOf(builder[2]); auto result = builder.build(); ASSERT_TRUE(result); @@ -1125,20 +1131,37 @@ TEST_F(TypeTest, TestSubTypes) { // SubTypes utility code. Module wasm; Builder wasmBuilder(wasm); - wasm.addFunction(wasmBuilder.makeFunction( - "func", - Signature(Type::none, Type::none), - {Type(built[0], Nullable), Type(built[1], Nullable)}, - wasmBuilder.makeNop())); + wasm.addFunction(wasmBuilder.makeFunction("func", + Signature(Type::none, Type::none), + {Type(built[0], Nullable), + Type(built[1], Nullable), + Type(built[2], Nullable), + Type(built[3], Nullable)}, + wasmBuilder.makeNop())); SubTypes subTypes(wasm); - auto subTypes0 = subTypes.getImmediateSubTypes(built[0]); - EXPECT_TRUE(subTypes0.size() == 1 && subTypes0[0] == built[1]); - auto subTypes0Inclusive = subTypes.getSubTypes(built[0]); - EXPECT_TRUE(subTypes0Inclusive.size() == 2 && - subTypes0Inclusive[0] == built[1] && - subTypes0Inclusive[1] == built[0]); - auto subTypes1 = subTypes.getImmediateSubTypes(built[1]); - EXPECT_EQ(subTypes1.size(), 0u); + auto immSubTypes0 = subTypes.getImmediateSubTypes(built[0]); + ASSERT_EQ(immSubTypes0.size(), 1u); + EXPECT_EQ(immSubTypes0[0], built[1]); + auto subTypes0 = subTypes.getSubTypes(built[0]); + ASSERT_EQ(subTypes0.size(), 2u); + EXPECT_EQ(subTypes0[0], built[1]); + EXPECT_EQ(subTypes0[1], built[0]); + auto immSubTypes1 = subTypes.getImmediateSubTypes(built[1]); + EXPECT_EQ(immSubTypes1.size(), 0u); + + auto depths = subTypes.getMaxDepths(); + EXPECT_EQ(depths[HeapTypes::any.getBasic(Unshared)], 4u); + EXPECT_EQ(depths[HeapTypes::any.getBasic(Shared)], 4u); + EXPECT_EQ(depths[HeapTypes::eq.getBasic(Unshared)], 3u); + EXPECT_EQ(depths[HeapTypes::eq.getBasic(Shared)], 3u); + EXPECT_EQ(depths[HeapTypes::struct_.getBasic(Unshared)], 2u); + EXPECT_EQ(depths[HeapTypes::struct_.getBasic(Shared)], 0u); + EXPECT_EQ(depths[HeapTypes::array.getBasic(Unshared)], 0u); + EXPECT_EQ(depths[HeapTypes::array.getBasic(Shared)], 2u); + EXPECT_EQ(depths[built[0]], 1u); + EXPECT_EQ(depths[built[1]], 0u); + EXPECT_EQ(depths[built[2]], 1u); + EXPECT_EQ(depths[built[3]], 0u); } // Test reuse of a previously built type as supertype. diff --git a/test/lit/passes/gufa-tnh.wast b/test/lit/passes/gufa-tnh.wast index d276421f888..ecf031bbf9c 100644 --- a/test/lit/passes/gufa-tnh.wast +++ b/test/lit/passes/gufa-tnh.wast @@ -2034,3 +2034,32 @@ ) ) ) + +(module + ;; CHECK: (type $0 (func (param i32) (result (ref null (shared any))))) + + ;; CHECK: (table $0 3 3 (ref null (shared any))) + (table $0 3 3 (ref null (shared any))) + ;; CHECK: (elem $0 (table $0) (i32.const 0) (ref null (shared i31)) (item (ref.i31_shared + ;; CHECK-NEXT: (i32.const 999) + ;; CHECK-NEXT: ))) + (elem $0 (table $0) (i32.const 0) (ref null (shared i31)) (item (ref.i31_shared (i32.const 999)))) + ;; CHECK: (export "get" (func $0)) + + ;; CHECK: (func $0 (type $0) (param $0 i32) (result (ref null (shared any))) + ;; CHECK-NEXT: (ref.cast (ref null (shared i31)) + ;; CHECK-NEXT: (table.get $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $0 (export "get") (param $0 i32) (result (ref null (shared any))) + ;; Regression test for a bug where subtypes.h did not handle shared types + ;; correctly, causing this example to be misoptimized to return null. + (ref.cast (ref null (shared i31)) + (table.get $0 + (i32.const 0) + ) + ) + ) +) From 353e19e3343fb06eacdd8b438b305b536291bdd5 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 23 Jul 2024 14:03:46 -0700 Subject: [PATCH 477/553] Properly validate ref.cast when lacking a common supertype (#6741) When lacking a common supertype the GLB operation makes the type of the cast unreachable, which errors on getHeapType in the later code. Fixes #6738 --- src/wasm/wasm-validator.cpp | 15 +++++++++++++++ test/spec/ref_cast.wast | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 287ab2e8fc4..3abb106b30b 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2780,6 +2780,21 @@ void FunctionValidator::visitRefCast(RefCast* curr) { curr->ref->type.isRef(), curr, "ref.cast ref must have ref type")) { return; } + // If the cast is unreachable but not the ref (we ruled out the former + // earlier), then the cast is unreachable because the cast type had no + // common supertype with the ref, which is invalid. This is the same as the + // check below us, but we must do it first (as getHeapType fails otherwise). + if (!shouldBeUnequal( + curr->type, + Type(Type::unreachable), + curr, + "ref.cast target type and ref type must have a common supertype")) { + return; + } + // Also error (more generically) on i32 and anything else invalid here. + if (!shouldBeTrue(curr->type.isRef(), curr, "ref.cast must have ref type")) { + return; + } shouldBeEqual( curr->type.getHeapType().getBottom(), curr->ref->type.getHeapType().getBottom(), diff --git a/test/spec/ref_cast.wast b/test/spec/ref_cast.wast index 927d82ebcaf..c51e6b05719 100644 --- a/test/spec/ref_cast.wast +++ b/test/spec/ref_cast.wast @@ -170,6 +170,16 @@ "common supertype" ) +(assert_invalid + (module + (type $t0 (struct)) + (func (export "test-ref-cast-extern") (result anyref) + (ref.cast (ref extern) (struct.new $t0)) + ) + ) + "common supertype" +) + (assert_malformed (module quote "(func (ref.cast i32 (unreachable)))") "expected reftype" From 017b473f05b8dde4da8aadd154e6d2606071d2cb Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 24 Jul 2024 13:54:13 -0700 Subject: [PATCH 478/553] Validate RefAsNonNull (#6785) Fixes #6781 --- src/wasm/wasm-validator.cpp | 13 +++++++++++-- src/wasm/wasm.cpp | 8 +++++++- test/lit/validation/non-ref.wast | 13 +++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 test/lit/validation/non-ref.wast diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 3abb106b30b..ce7d0df3c22 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2230,10 +2230,19 @@ void FunctionValidator::visitRefIsNull(RefIsNull* curr) { } void FunctionValidator::visitRefAs(RefAs* curr) { + if (curr->value->type != Type::unreachable && + !shouldBeTrue( + curr->value->type.isRef(), curr, "ref.as value must be reference")) { + return; + } switch (curr->op) { - default: - // TODO: validate all the other ref.as_* + case RefAsNonNull: { + shouldBeTrue( + getModule()->features.hasReferenceTypes(), + curr, + "ref.as requires reference-types [--enable-reference-types]"); break; + } case AnyConvertExtern: { shouldBeTrue(getModule()->features.hasGC(), curr, diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 4c30a4e32bd..b17250e6c6c 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1223,7 +1223,13 @@ void ArrayInitElem::finalize() { } void RefAs::finalize() { - if (value->type == Type::unreachable) { + // An unreachable child means we are unreachable. Also set ourselves to + // unreachable when the child is invalid (say, it is an i32 or some other non- + // reference), which avoids getHeapType() erroring right after us (in this + // situation, the validator will report an error later). + // TODO: Remove that part when we solve the validation issue more generally, + // see https://github.com/WebAssembly/binaryen/issues/6781 + if (!value->type.isRef()) { type = Type::unreachable; return; } diff --git a/test/lit/validation/non-ref.wast b/test/lit/validation/non-ref.wast new file mode 100644 index 00000000000..a065b6723e4 --- /dev/null +++ b/test/lit/validation/non-ref.wast @@ -0,0 +1,13 @@ +;; RUN: not wasm-opt %s -all 2>&1 | filecheck %s + +;; CHECK: ref.as value must be reference + +(module + (func $test + (drop + (ref.as_non_null + (i32.const 42) + ) + ) + ) +) From d903dd30f6426b8eb07605cae01baf4158364e2d Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 25 Jul 2024 10:17:42 -0700 Subject: [PATCH 479/553] TupleOptimization: Properly handle subtyping in copies (#6786) We used the target's type for the read from the source, but due to subtyping those might be different. Found by the fuzzer. --- src/passes/TupleOptimization.cpp | 9 ++++-- test/lit/passes/tuple-optimization.wast | 42 +++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/passes/TupleOptimization.cpp b/src/passes/TupleOptimization.cpp index 25da1c5ec30..ca704f1a3d7 100644 --- a/src/passes/TupleOptimization.cpp +++ b/src/passes/TupleOptimization.cpp @@ -25,7 +25,7 @@ // (tuple.extract 3 0 // (local.get $tuple))) // -// If there are no other uses, then we just need one of the three lanes. By +// If there are no other uses, then we just need one of the three elements. By // lowing them to three separate locals, other passes can remove the other two. // // Specifically, this pass seeks out tuple locals that have these properties: @@ -320,8 +320,13 @@ struct TupleOptimization : public WalkerPass> { // we were confused earlier and the target should not be. assert(sourceBase); + // The source and target may have different element types due to + // subtyping (but their sizes must be equal). + auto sourceType = value->type; + assert(sourceType.size() == type.size()); + for (Index i = 0; i < type.size(); i++) { - auto* get = builder.makeLocalGet(sourceBase + i, type[i]); + auto* get = builder.makeLocalGet(sourceBase + i, sourceType[i]); contents.push_back(builder.makeLocalSet(targetBase + i, get)); } replace(builder.makeBlock(contents)); diff --git a/test/lit/passes/tuple-optimization.wast b/test/lit/passes/tuple-optimization.wast index d092d479f81..e0d68848e8a 100644 --- a/test/lit/passes/tuple-optimization.wast +++ b/test/lit/passes/tuple-optimization.wast @@ -15,7 +15,7 @@ ;; CHECK-NEXT: ) (func $just-set (local $tuple (tuple i32 i32)) - ;; This tuple local can be optimized into separate locals per lane. The + ;; This tuple local can be optimized into separate locals per element. The ;; tuple local itself then has no uses and other passes will remove it. (local.set $tuple (tuple.make 2 @@ -38,7 +38,7 @@ ;; CHECK-NEXT: ) (func $just-get (local $tuple (tuple i32 i32)) - ;; The default value of the tuple lanes is used here in the new locals we + ;; The default value of the tuple elements is used here in the new locals we ;; add. (drop (tuple.extract 2 0 @@ -1026,4 +1026,42 @@ ) ) ) + + ;; CHECK: (func $tuple.element.subtyping (type $0) + ;; CHECK-NEXT: (local $tuple_null (tuple i32 nullref)) + ;; CHECK-NEXT: (local $tuple_eq (tuple i32 eqref)) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 nullref) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 eqref) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $tuple.element.subtyping + (local $tuple_null (tuple i32 nullref)) + (local $tuple_eq (tuple i32 eqref)) + ;; The tee emits a nullref in the second element, which is written to an + ;; element of eqref. That is, the source and the target do not have + ;; identical type, which we need to properly handle and not error. + (local.set $tuple_eq + (local.tee $tuple_null + (tuple.make 2 + (i32.const 0) + (ref.null none) + ) + ) + ) + ) ) From 9cc1cb1ca66e89cbe7b7b5b52897f3bee3ee422c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 25 Jul 2024 11:16:45 -0700 Subject: [PATCH 480/553] Cost analysis: Remove "Unacceptable" hack (#6782) We marked various expressions as having cost "Unacceptable", fixed at 100, to ensure we never moved them out from an If arm, etc. Giving them such a high cost avoids that problem - the cost is higher than the limit we have for moving code from conditional to unconditional execution - but it also means the total cost is unrealistic. For example, a function with one such instruction + an add (cost 1) would end up with cost 101, and removing the add would look insignificant, which causes issues for things that want to compare costs (like Monomorphization). To fix this, adjust some costs. The main change here is to give casts a cost of 5. I measured this in depth, see the attached benchmark scripts, and it looks clear that in both V8 and SpiderMonkey the cost of a cast is high enough to make it not worth turning an if with ref.test arm into a select (which would always execute the test). Other costs adjusted here matter a lot less, because they are on operations that have side effects and so the optimizer will anyhow not move them from conditional to unconditional execution, but I tried to make them a bit more realistic while I was removing "Unacceptable": * Give most atomic operations the 10 cost we've been using for atomic loads/ stores. Perhaps wait and notify should be slower, however, but it seems like assuming fast switching might be more relevant. * Give growth operations a cost of 20, and throw operations a cost of 10. These numbers are entirely made up as I am not even sure how to measure them in a useful way (but, again, this should not matter much as they have side effects). --- scripts/benchmarking/bench.js | 159 ++++++++++ scripts/benchmarking/bench.wat | 283 ++++++++++++++++++ src/ir/cost.h | 54 ++-- src/passes/RemoveUnusedBrs.cpp | 10 +- test/lit/passes/remove-unused-brs_levels.wast | 143 ++++++++- 5 files changed, 615 insertions(+), 34 deletions(-) create mode 100644 scripts/benchmarking/bench.js create mode 100644 scripts/benchmarking/bench.wat diff --git a/scripts/benchmarking/bench.js b/scripts/benchmarking/bench.js new file mode 100644 index 00000000000..d1284a241d8 --- /dev/null +++ b/scripts/benchmarking/bench.js @@ -0,0 +1,159 @@ + +// Benchmarking script. This runs on compiled bench.wat and prints out timings. +// +// Usage: +// +// * wasm-opt scripts/benchmarking/bench.wat -all --inline-functions-with-loops --always-inline-max-function-size=1000 --inlining --precompute-propagate --optimize-instructions --inlining --simplify-locals --coalesce-locals --vacuum --remove-unused-module-elements -o bench.wasm -g +// * Inspect the optimized wasm to see that inlining etc. worked properly +// (we rely on inlining to let us write bench.wat in a short/simple form, and +// we use very specific optimizations in order to not optimize away the +// differences we care about). +// * d8 bench.js -- bench.wasm +// etc. +// + +// Shell integration. +if (typeof console === 'undefined') { + console = { log: print }; +} +var tempRet0; +var binary; +if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) { + var args = process.argv.slice(2); + binary = require('fs').readFileSync(args[0]); + if (!binary.buffer) binary = new Uint8Array(binary); +} else { + var args; + if (typeof scriptArgs != 'undefined') { + args = scriptArgs; + } else if (typeof arguments != 'undefined') { + args = arguments; + } + if (typeof readbuffer === 'function') { + binary = new Uint8Array(readbuffer(args[0])); + } else { + binary = read(args[0], 'binary'); + } +} + +// Create the wasm. +const module = new WebAssembly.Module(binary); +const instance = new WebAssembly.Instance(module, {}); +const exports = instance.exports; + +// Create the benchmarkers. +function makeBenchmarker(name) { + return { + name: name, + func: exports[name], + time: 0, + sum: 0, + iters: 0, + }; +} + +const benchmarkers = [ + makeBenchmarker('len'), + makeBenchmarker('and'), + makeBenchmarker('iff-both'), + makeBenchmarker('or'), + makeBenchmarker('iff-either'), + makeBenchmarker('select'), + makeBenchmarker('iff-nextor'), + makeBenchmarker('select-three'), + makeBenchmarker('iff-three'), +]; + +// We'll call the benchmark functions in random orders. Random orders avoid any +// interaction between the benchmarks from causing bias in the results. +// +// An alternative to randomly ordering the benchmarks in each iteration would be +// to fully benchmark one, then do the next, so there are large amounts of time +// between them, but that also allows them to become more like microbenchmarks +// where the branch predictor etc. might display very favorable behavior. +// Interleaving them makes things slightly more realistic. +// +// If we have too many benchmarks then eventually computing all orders ahead of +// time will not work, but so long as we can, it is faster this way rather than +// to compute random orders on the fly as we go. +function makeOrders(prefix) { + // Given a prefix of an order, like [] or [0, 3], return all the possible + // orders beginning with that prefix. + + // We cannot repeat anything already seen. + const seen = new Set(); + for (var x of prefix) { + seen.add(x); + } + + // Starting from the prefix, extend it by one item in all valid ways. + const extensions = []; + for (var i = 0; i < benchmarkers.length; i++) { + if (!seen.has(i)) { + extensions.push(prefix.concat(i)); + } + } + + if (prefix.length == benchmarkers.length - 1) { + // The extensions are complete orders; stop the recursion. + return extensions; + } + + // Recursively generate the full orders. + const ret = []; + for (var extension of extensions) { + for (var order of makeOrders(extension)) { + ret.push(order); + } + } + return ret; +} + +const orders = makeOrders([]); + +// Params. +const M = 10000000; +const N = 100; + +console.log('iters :', M); +console.log('list len :', N); +console.log('benchmarkers:', benchmarkers.length); +console.log('orderings :', orders.length); + +// Create a long linked list of objects of both type $A and $B. +var list = null; +for (var i = 0; i < N; i++) { + list = Math.random() < 0.5 ? exports.makeA(list) : exports.makeB(list); +} + +console.log('benchmarking...'); + +// Call the benchmark functions. + +for (var i = 0; i < M; i++) { + const order = orders[Math.floor(Math.random() * orders.length)]; + for (var k = 0; k < benchmarkers.length; k++) { + const benchmarker = benchmarkers[order[k]]; + const start = performance.now(); + const result = benchmarker.func(list); + benchmarker.time += performance.now() - start; + benchmarker.sum += result; + benchmarker.iters++; + } +} + +for (var benchmarker of benchmarkers) { + if (benchmarker.iters != M) { + throw 'wat'; + } +} + +console.log(); +for (var benchmarker of benchmarkers) { + console.log(`${benchmarker.name} time: \t${benchmarker.time}`) +} +console.log(); +for (var benchmarker of benchmarkers) { + console.log(`${benchmarker.name} mean sum: \t${benchmarker.sum / M}`) +} + diff --git a/scripts/benchmarking/bench.wat b/scripts/benchmarking/bench.wat new file mode 100644 index 00000000000..87d54b66b4e --- /dev/null +++ b/scripts/benchmarking/bench.wat @@ -0,0 +1,283 @@ +;; See bench.js. + +(module + ;; A chain of three types. Each type has a "next" field, so we can form linked + ;; lists. + (type $A (sub (struct (field $next (ref null $A))))) + (type $B (sub $A (struct (field $next (ref null $A))))) + (type $C (sub $B (struct (field $next (ref null $A))))) + + (type $func (func (param (ref $A)) (result i32))) + + ;; Internal helper to iterate over a linked list and call a function on each + ;; item, and return the sum of those calls' results. + (func $iter (param $list (ref null $A)) (param $func (ref $func)) (result i32) + (local $sum i32) + (loop $loop + (if + (ref.is_null + (local.get $list) + ) + (then + (return + (local.get $sum) + ) + ) + (else + (local.set $sum + (i32.add + (local.get $sum) + (call_ref $func + (ref.as_non_null + (local.get $list) + ) + (local.get $func) + ) + ) + ) + (local.set $list + (struct.get $A $next + (local.get $list) + ) + ) + (br $loop) + ) + ) + ) + ) + + ;; Using the helper, and depending on inlining to optimize this, lets us + ;; write the exports concisely. First, code to compute the length of the list + ;; (for comparison purposes). + (func $len (export "len") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + ;; Add one each time this is called. + (ref.func $one) + ) + ) + (func $one (param $list (ref $A)) (result i32) + (i32.const 1) + ) + + ;; At each point in the linked list, check if both the current and next item + ;; are inputs are $B, using an if to short-circuit when possible. + (func $iff-both (export "iff-both") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-iff-both) + ) + ) + (func $do-iff-both (param $list (ref $A)) (result i32) + (if (result i32) + (ref.test (ref $B) + (struct.get $A $next + (local.get $list) + ) + ) + (then + (ref.test (ref $B) + (local.get $list) + ) + ) + (else + (i32.const 0) + ) + ) + ) + + ;; The same computation, but using an and, so both tests always execute. + (func $and (export "and") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-and) + ) + ) + (func $do-and (param $list (ref $A)) (result i32) + (i32.and + (ref.test (ref $B) + (struct.get $A $next + (local.get $list) + ) + ) + (ref.test (ref $B) + (local.get $list) + ) + ) + ) + + ;; Similar, but return 1 if either test succeeds (using an if). + (func $iff-either (export "iff-either") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-iff-either) + ) + ) + (func $do-iff-either (param $list (ref $A)) (result i32) + (if (result i32) + (ref.test (ref $B) + (struct.get $A $next + (local.get $list) + ) + ) + (then + (i32.const 1) + ) + (else + (ref.test (ref $B) + (local.get $list) + ) + ) + ) + ) + + + ;; The same computation, but using an or, so both tests always execute. + (func $or (export "or") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-or) + ) + ) + (func $do-or (param $list (ref $A)) (result i32) + (i32.or + (ref.test (ref $B) + (struct.get $A $next + (local.get $list) + ) + ) + (ref.test (ref $B) + (local.get $list) + ) + ) + ) + + ;; Use a select to do a test of "is next null ? 0 : test curr". + (func $select (export "select") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-select) + ) + ) + (func $do-select (param $list (ref $A)) (result i32) + (select + (i32.const 0) + (ref.test (ref $B) + (local.get $list) + ) + (ref.is_null + (struct.get $A $next + (local.get $list) + ) + ) + ) + ) + + ;; Use an iff to do the same. + (func $iff-nextor (export "iff-nextor") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-iff-nextor) + ) + ) + (func $do-iff-nextor (param $list (ref $A)) (result i32) + (if (result i32) + (ref.is_null + (struct.get $A $next + (local.get $list) + ) + ) + (then + (i32.const 0) + ) + (else + (ref.test (ref $B) + (local.get $list) + ) + ) + ) + ) + + ;; Use an if over three tests: "test if next is B or C depending on if curr is + ;; B." + (func $iff-three (export "iff-three") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-iff-three) + ) + ) + (func $do-iff-three (param $list (ref $A)) (result i32) + (local $next (ref null $A)) + (local.set $next + (struct.get $A $next + (local.get $list) + ) + ) + (if (result i32) + (ref.test (ref $B) + (local.get $list) + ) + (then + (ref.test (ref $C) + (local.get $next) + ) + ) + (else + (ref.test (ref $B) + (local.get $next) + ) + ) + ) + ) + + ;; Use a select for the same. + (func $select-three (export "select-three") (param $list (ref $A)) (result i32) + (call $iter + (local.get $list) + (ref.func $do-select-three) + ) + ) + (func $do-select-three (param $list (ref $A)) (result i32) + (local $next (ref null $A)) + (local.set $next + (struct.get $A $next + (local.get $list) + ) + ) + (select + (ref.test (ref $C) + (local.get $next) + ) + (ref.test (ref $B) + (local.get $next) + ) + (ref.test (ref $B) + (local.get $list) + ) + ) + ) + + ;; Creation functions. + + (func $makeA (export "makeA") (param $next (ref null $A)) (result anyref) + (struct.new $A + (local.get $next) + ) + ) + + (func $makeB (export "makeB") (param $next (ref null $A)) (result anyref) + (struct.new $B + (local.get $next) + ) + ) + + (func $makeC (export "makeC") (param $next (ref null $A)) (result anyref) + ;; This function is not used in benchmarks yet, but it keeps the type $C + ;; alive, which prevents $B from looking like it could be final, which might + ;; allow the optimizer to simplify more than we want. + (struct.new $C + (local.get $next) + ) + ) +) + diff --git a/src/ir/cost.h b/src/ir/cost.h index 6622561b8e3..38c74a2037c 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -31,11 +31,17 @@ struct CostAnalyzer : public OverriddenVisitor { CostType cost; - // A cost that is extremely high, something that is far, far more expensive - // than a fast operation like an add. This cost is so high it is unacceptable - // to add any more of it, say by an If=>Select operation (which would execute - // both arms; if either arm contains an unacceptable cost, we do not do it). - static const CostType Unacceptable = 100; + // The cost of a "slow" atomic operation like RMW. + static const CostType AtomicCost = 10; + + // The cost of throwing a wasm exception. This does not include the cost of + // catching it (which might be in another function than the one we are + // considering). + static const CostType ThrowCost = 10; + + // The cost of a cast. This can vary depending on the engine and on the type, + // but usually requires some loads and comparisons. + static const CostType CastCost = 5; CostType maybeVisit(Expression* curr) { return curr ? visit(curr) : 0; } @@ -85,26 +91,27 @@ struct CostAnalyzer : public OverriddenVisitor { CostType visitGlobalGet(GlobalGet* curr) { return 1; } CostType visitGlobalSet(GlobalSet* curr) { return 2 + visit(curr->value); } CostType visitLoad(Load* curr) { - return 1 + visit(curr->ptr) + 10 * curr->isAtomic; + return 1 + visit(curr->ptr) + AtomicCost * curr->isAtomic; } CostType visitStore(Store* curr) { - return 2 + visit(curr->ptr) + visit(curr->value) + 10 * curr->isAtomic; + return 2 + visit(curr->ptr) + visit(curr->value) + + AtomicCost * curr->isAtomic; } CostType visitAtomicRMW(AtomicRMW* curr) { - return Unacceptable + visit(curr->ptr) + visit(curr->value); + return AtomicCost + visit(curr->ptr) + visit(curr->value); } CostType visitAtomicCmpxchg(AtomicCmpxchg* curr) { - return Unacceptable + visit(curr->ptr) + visit(curr->expected) + + return AtomicCost + visit(curr->ptr) + visit(curr->expected) + visit(curr->replacement); } CostType visitAtomicWait(AtomicWait* curr) { - return Unacceptable + visit(curr->ptr) + visit(curr->expected) + + return AtomicCost + visit(curr->ptr) + visit(curr->expected) + visit(curr->timeout); } CostType visitAtomicNotify(AtomicNotify* curr) { - return Unacceptable + visit(curr->ptr) + visit(curr->notifyCount); + return AtomicCost + visit(curr->ptr) + visit(curr->notifyCount); } - CostType visitAtomicFence(AtomicFence* curr) { return Unacceptable; } + CostType visitAtomicFence(AtomicFence* curr) { return AtomicCost; } CostType visitConst(Const* curr) { return 1; } CostType visitUnary(Unary* curr) { CostType ret = 0; @@ -516,7 +523,8 @@ struct CostAnalyzer : public OverriddenVisitor { CostType visitReturn(Return* curr) { return maybeVisit(curr->value); } CostType visitMemorySize(MemorySize* curr) { return 1; } CostType visitMemoryGrow(MemoryGrow* curr) { - return Unacceptable + visit(curr->delta); + // TODO: This should perhaps be higher for shared memories. + return 20 + visit(curr->delta); } CostType visitMemoryInit(MemoryInit* curr) { return 6 + visit(curr->dest) + visit(curr->offset) + visit(curr->size); @@ -572,7 +580,7 @@ struct CostAnalyzer : public OverriddenVisitor { } CostType visitTableSize(TableSize* curr) { return 1; } CostType visitTableGrow(TableGrow* curr) { - return Unacceptable + visit(curr->value) + visit(curr->delta); + return 20 + visit(curr->value) + visit(curr->delta); } CostType visitTableFill(TableFill* curr) { return 6 + visit(curr->dest) + visit(curr->value) + visit(curr->size); @@ -589,14 +597,14 @@ struct CostAnalyzer : public OverriddenVisitor { return visit(curr->body); } CostType visitThrow(Throw* curr) { - CostType ret = Unacceptable; + CostType ret = ThrowCost; for (auto* child : curr->operands) { ret += visit(child); } return ret; } - CostType visitRethrow(Rethrow* curr) { return Unacceptable; } - CostType visitThrowRef(ThrowRef* curr) { return Unacceptable; } + CostType visitRethrow(Rethrow* curr) { return ThrowCost; } + CostType visitThrowRef(ThrowRef* curr) { return ThrowCost; } CostType visitTupleMake(TupleMake* curr) { CostType ret = 0; for (auto* child : curr->operands) { @@ -612,19 +620,15 @@ struct CostAnalyzer : public OverriddenVisitor { CostType visitRefI31(RefI31* curr) { return 3 + visit(curr->value); } CostType visitI31Get(I31Get* curr) { return 2 + visit(curr->i31); } CostType visitRefTest(RefTest* curr) { - // Casts have a very high cost because in the VM they end up implemented as - // a combination of loads and branches. Given they contain branches, we do - // not want to add any more such work. - return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref); + return CastCost + nullCheckCost(curr->ref) + visit(curr->ref); } CostType visitRefCast(RefCast* curr) { - return Unacceptable + nullCheckCost(curr->ref) + visit(curr->ref); + return CastCost + nullCheckCost(curr->ref) + visit(curr->ref); } CostType visitBrOn(BrOn* curr) { - // BrOn of a null can be fairly fast, but anything else is a cast check - // basically, and an unacceptable cost. + // BrOn of a null can be fairly fast, but anything else is a cast check. CostType base = - curr->op == BrOnNull || curr->op == BrOnNonNull ? 2 : Unacceptable; + curr->op == BrOnNull || curr->op == BrOnNonNull ? 2 : CastCost; return base + nullCheckCost(curr->ref) + maybeVisit(curr->ref); } CostType visitStructNew(StructNew* curr) { diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 893cf9039bc..fcb4ea56a38 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -88,8 +88,14 @@ static bool canTurnIfIntoBrIf(Expression* ifCondition, // * https://github.com/WebAssembly/binaryen/issues/5983 const Index TooCostlyToRunUnconditionally = 8; -static_assert(TooCostlyToRunUnconditionally < CostAnalyzer::Unacceptable, - "We never run code unconditionally if it has unacceptable cost"); +// Some costs are known to be too high to move from conditional to unconditional +// execution. +static_assert(CostAnalyzer::AtomicCost >= TooCostlyToRunUnconditionally, + "We never run atomics unconditionally"); +static_assert(CostAnalyzer::ThrowCost >= TooCostlyToRunUnconditionally, + "We never run throws unconditionally"); +static_assert(CostAnalyzer::CastCost > TooCostlyToRunUnconditionally / 2, + "We only run casts unconditionally when optimizing for size"); static bool tooCostlyToRunUnconditionally(const PassOptions& passOptions, Index cost) { diff --git a/test/lit/passes/remove-unused-brs_levels.wast b/test/lit/passes/remove-unused-brs_levels.wast index 927cce86781..6e521aa1665 100644 --- a/test/lit/passes/remove-unused-brs_levels.wast +++ b/test/lit/passes/remove-unused-brs_levels.wast @@ -3,9 +3,17 @@ ;; RUN: wasm-opt %s --remove-unused-brs -all -S --shrink-level=1 -o - | filecheck %s --check-prefix=SHRINK_1 ;; RUN: wasm-opt %s --remove-unused-brs -all -S --shrink-level=2 -o - | filecheck %s --check-prefix=SHRINK_2 - (module - ;; SHRINK_0: (func $selectify-division (type $0) (param $x i32) (result i32) + ;; SHRINK_0: (type $struct (sub (struct))) + ;; SHRINK_1: (type $struct (sub (struct))) + ;; SHRINK_2: (type $struct (sub (struct))) + (type $struct (sub (struct))) + ;; SHRINK_0: (type $substruct (sub $struct (struct))) + ;; SHRINK_1: (type $substruct (sub $struct (struct))) + ;; SHRINK_2: (type $substruct (sub $struct (struct))) + (type $substruct (sub $struct (struct))) + + ;; SHRINK_0: (func $selectify-division (type $2) (param $x i32) (result i32) ;; SHRINK_0-NEXT: (if (result i32) ;; SHRINK_0-NEXT: (i32.eq ;; SHRINK_0-NEXT: (local.get $x) @@ -22,7 +30,7 @@ ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) - ;; SHRINK_1: (func $selectify-division (type $0) (param $x i32) (result i32) + ;; SHRINK_1: (func $selectify-division (type $2) (param $x i32) (result i32) ;; SHRINK_1-NEXT: (select ;; SHRINK_1-NEXT: (i32.div_s ;; SHRINK_1-NEXT: (local.get $x) @@ -35,7 +43,7 @@ ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) - ;; SHRINK_2: (func $selectify-division (type $0) (param $x i32) (result i32) + ;; SHRINK_2: (func $selectify-division (type $2) (param $x i32) (result i32) ;; SHRINK_2-NEXT: (select ;; SHRINK_2-NEXT: (i32.div_s ;; SHRINK_2-NEXT: (local.get $x) @@ -68,7 +76,7 @@ ) ) - ;; SHRINK_0: (func $selectify-division2 (type $0) (param $x i32) (result i32) + ;; SHRINK_0: (func $selectify-division2 (type $2) (param $x i32) (result i32) ;; SHRINK_0-NEXT: (if (result i32) ;; SHRINK_0-NEXT: (i32.eq ;; SHRINK_0-NEXT: (local.get $x) @@ -88,7 +96,7 @@ ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) ;; SHRINK_0-NEXT: ) - ;; SHRINK_1: (func $selectify-division2 (type $0) (param $x i32) (result i32) + ;; SHRINK_1: (func $selectify-division2 (type $2) (param $x i32) (result i32) ;; SHRINK_1-NEXT: (if (result i32) ;; SHRINK_1-NEXT: (i32.eq ;; SHRINK_1-NEXT: (local.get $x) @@ -108,7 +116,7 @@ ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) ;; SHRINK_1-NEXT: ) - ;; SHRINK_2: (func $selectify-division2 (type $0) (param $x i32) (result i32) + ;; SHRINK_2: (func $selectify-division2 (type $2) (param $x i32) (result i32) ;; SHRINK_2-NEXT: (select ;; SHRINK_2-NEXT: (i32.div_s ;; SHRINK_2-NEXT: (i32.div_s @@ -146,4 +154,125 @@ ) ) ) + + ;; SHRINK_0: (func $if-tests (type $3) (param $x (ref $struct)) (param $y (ref $struct)) (result i32) + ;; SHRINK_0-NEXT: (if (result i32) + ;; SHRINK_0-NEXT: (ref.test (ref $substruct) + ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: (then + ;; SHRINK_0-NEXT: (ref.test (ref $substruct) + ;; SHRINK_0-NEXT: (local.get $y) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: (else + ;; SHRINK_0-NEXT: (i32.const 0) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_1: (func $if-tests (type $3) (param $x (ref $struct)) (param $y (ref $struct)) (result i32) + ;; SHRINK_1-NEXT: (select + ;; SHRINK_1-NEXT: (ref.test (ref $substruct) + ;; SHRINK_1-NEXT: (local.get $y) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: (i32.const 0) + ;; SHRINK_1-NEXT: (ref.test (ref $substruct) + ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_2: (func $if-tests (type $3) (param $x (ref $struct)) (param $y (ref $struct)) (result i32) + ;; SHRINK_2-NEXT: (select + ;; SHRINK_2-NEXT: (ref.test (ref $substruct) + ;; SHRINK_2-NEXT: (local.get $y) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: (i32.const 0) + ;; SHRINK_2-NEXT: (ref.test (ref $substruct) + ;; SHRINK_2-NEXT: (local.get $x) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: ) + (func $if-tests (param $x (ref $struct)) (param $y (ref $struct)) (result i32) + ;; An If with a test in one arm (and also in a condition). We do not + ;; normally turn this into a Select, as the test is more costly than the If. + ;; But we do so when optimizing for size. + ;; + ;; TODO: Consider optimizing this because the other arm is a 0, which means + ;; the Select can turn into an And later. + (if (result i32) + (ref.test (ref $substruct) + (local.get $x) + ) + (then + (ref.test (ref $substruct) + (local.get $y) + ) + ) + (else + (i32.const 0) + ) + ) + ) + + ;; SHRINK_0: (func $if-tests-arms (type $4) (param $x (ref $struct)) (param $y (ref $struct)) (param $z (ref $struct)) (result i32) + ;; SHRINK_0-NEXT: (if (result i32) + ;; SHRINK_0-NEXT: (ref.test (ref $substruct) + ;; SHRINK_0-NEXT: (local.get $x) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: (then + ;; SHRINK_0-NEXT: (ref.test (ref $substruct) + ;; SHRINK_0-NEXT: (local.get $y) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: (else + ;; SHRINK_0-NEXT: (ref.test (ref $substruct) + ;; SHRINK_0-NEXT: (local.get $z) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_0-NEXT: ) + ;; SHRINK_1: (func $if-tests-arms (type $4) (param $x (ref $struct)) (param $y (ref $struct)) (param $z (ref $struct)) (result i32) + ;; SHRINK_1-NEXT: (select + ;; SHRINK_1-NEXT: (ref.test (ref $substruct) + ;; SHRINK_1-NEXT: (local.get $y) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: (ref.test (ref $substruct) + ;; SHRINK_1-NEXT: (local.get $z) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: (ref.test (ref $substruct) + ;; SHRINK_1-NEXT: (local.get $x) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_1-NEXT: ) + ;; SHRINK_2: (func $if-tests-arms (type $4) (param $x (ref $struct)) (param $y (ref $struct)) (param $z (ref $struct)) (result i32) + ;; SHRINK_2-NEXT: (select + ;; SHRINK_2-NEXT: (ref.test (ref $substruct) + ;; SHRINK_2-NEXT: (local.get $y) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: (ref.test (ref $substruct) + ;; SHRINK_2-NEXT: (local.get $z) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: (ref.test (ref $substruct) + ;; SHRINK_2-NEXT: (local.get $x) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: ) + ;; SHRINK_2-NEXT: ) + (func $if-tests-arms (param $x (ref $struct)) (param $y (ref $struct)) (param $z (ref $struct)) (result i32) + ;; As above but now with a test in both arms. The outcomes are the same. + (if (result i32) + (ref.test (ref $substruct) + (local.get $x) + ) + (then + (ref.test (ref $substruct) + (local.get $y) + ) + ) + (else + (ref.test (ref $substruct) + (local.get $z) + ) + ) + ) + ) ) From f938154a44ae4dd2733537c5683ebe2eeb1989a2 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 26 Jul 2024 15:50:58 -0400 Subject: [PATCH 481/553] [wasm-reduce] Do not crash on non-func element segments (#6778) Generalize the code for simplifying element segments to handle more than just null and funcref elements. --- src/tools/wasm-reduce.cpp | 15 +++++---------- test/reduce/memory_table.wast | 11 ++++++++++- test/reduce/memory_table.wast.txt | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index ac5b7722bd3..c276296ad48 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -854,18 +854,13 @@ struct Reducer reduceByZeroing( segment.get(), first, - [&](Expression* entry) { - if (entry->is()) { - // we don't need to replace a ref.null + [&](Expression* elem) { + if (elem->is()) { + // We don't need to replace a ref.null. return true; - } else if (first->is()) { - return false; - } else { - // Both are ref.func - auto* f = first->cast(); - auto* e = entry->cast(); - return f->func == e->func; } + // Is the element equal to our first "zero" element? + return ExpressionAnalyzer::equal(first, elem); }, 1, shrank); diff --git a/test/reduce/memory_table.wast b/test/reduce/memory_table.wast index 9518f5968ed..25caecb9dad 100644 --- a/test/reduce/memory_table.wast +++ b/test/reduce/memory_table.wast @@ -2,12 +2,16 @@ (type $i (func (result i32))) (memory $0 256 256) (table 481 481 funcref) + (table 354 354 i31ref) (elem (i32.const 0) $f0 $f0 $f1 $f2 $f0 $f3 $f0) + (elem (table 1) (i32.const 0) i31ref + (item (ref.i31 (i32.const 0))) (item (ref.i31 (i32.const 42))) (item (ref.i31 (i32.const 99)))) (data (i32.const 0) "p\0bflkj") (data (i32.const 10960) "1234hello") (export "f1" (func $f1)) (export "f2" (func $f2)) (export "f4" (func $f4)) + (export "f5" (func $f5)) (func $f0 (result i32) (i32.const 1234) ) @@ -27,5 +31,10 @@ (call_indirect (type $i) (i32.const 0)) ) ) + (func $f5 (result i32) + (i32.add + (i31.get_s (table.get 1 (i32.const 0))) + (i31.get_u (table.get 1 (i32.const 1))) + ) + ) ) - diff --git a/test/reduce/memory_table.wast.txt b/test/reduce/memory_table.wast.txt index e56809ade09..ca2fde91414 100644 --- a/test/reduce/memory_table.wast.txt +++ b/test/reduce/memory_table.wast.txt @@ -2,9 +2,16 @@ (type $0 (func (result i32))) (type $1 (func)) (memory $0 256 256) + (table $0 354 354 i31ref) + (elem $0 (table $0) (i32.const 0) i31ref (item (ref.i31 + (i32.const 0) + )) (item (ref.i31 + (i32.const 42) + ))) (export "f1" (func $0)) (export "f2" (func $1)) (export "f4" (func $2)) + (export "f5" (func $3)) (func $0 ) (func $1 (result i32) @@ -22,5 +29,12 @@ (i32.const 1234) ) ) + (func $3 (result i32) + (i31.get_u + (table.get $0 + (i32.const 1) + ) + ) + ) ) From eac08461444da84e20d0641e429db7b03e45a21c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 29 Jul 2024 11:37:55 -0700 Subject: [PATCH 482/553] Generalize Literal::externalize/internalize for strings and shareability (#6784) --- src/wasm/literal.cpp | 30 ++++++++++++------------------ test/lit/ctor-eval/shared-i31.wast | 9 +++++++++ test/lit/exec/strings.wast | 26 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 6e9c3eaf4a1..b3128025eea 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -74,7 +74,8 @@ Literal::Literal(std::shared_ptr gcData, HeapType type) : gcData(gcData), type(type, gcData ? NonNullable : Nullable) { // The type must be a proper type for GC data: either a struct, array, or // string; or an externalized version of the same; or a null. - assert((isData() && gcData) || (type == HeapType::ext && gcData) || + assert((isData() && gcData) || + (type.isMaybeShared(HeapType::ext) && gcData) || (type.isBottom() && !gcData)); } @@ -115,7 +116,7 @@ Literal::Literal(const Literal& other) : type(other.type) { new (&gcData) std::shared_ptr(); return; } - if (other.isData() || other.type.getHeapType() == HeapType::ext) { + if (other.isData() || other.type.getHeapType().isMaybeShared(HeapType::ext)) { new (&gcData) std::shared_ptr(other.gcData); return; } @@ -160,7 +161,7 @@ Literal::~Literal() { if (type.isBasic()) { return; } - if (isNull() || isData() || type.getHeapType() == HeapType::ext) { + if (isNull() || isData() || type.getHeapType().isMaybeShared(HeapType::ext)) { gcData.~shared_ptr(); } } @@ -2684,36 +2685,29 @@ Literal Literal::relaxedFmsF64x2(const Literal& left, } Literal Literal::externalize() const { - assert(Type::isSubType(type, Type(HeapType::any, Nullable)) && + assert(type.isRef() && type.getHeapType().getUnsharedTop() == HeapType::any && "can only externalize internal references"); if (isNull()) { return Literal(std::shared_ptr{}, HeapType::noext); } auto heapType = type.getHeapType(); auto extType = HeapTypes::ext.getBasic(heapType.getShared()); - if (heapType.isBasic()) { - switch (heapType.getBasic(Unshared)) { - case HeapType::i31: { - return Literal(std::make_shared(HeapType::i31, Literals{*this}), - extType); - } - case HeapType::string: - WASM_UNREACHABLE("TODO: string literals"); - default: - WASM_UNREACHABLE("unexpected type"); - } + if (heapType.isMaybeShared(HeapType::i31)) { + return Literal(std::make_shared(heapType, Literals{*this}), + extType); } return Literal(gcData, extType); } Literal Literal::internalize() const { - assert(Type::isSubType(type, Type(HeapType::ext, Nullable)) && + auto extType = HeapTypes::ext.getBasic(type.getHeapType().getShared()); + assert(Type::isSubType(type, Type(extType, Nullable)) && "can only internalize external references"); if (isNull()) { return Literal(std::shared_ptr{}, HeapType::none); } - if (gcData->type == HeapType::i31) { - assert(gcData->values[0].type.getHeapType() == HeapType::i31); + if (gcData->type.isMaybeShared(HeapType::i31)) { + assert(gcData->values[0].type.getHeapType().isMaybeShared(HeapType::i31)); return gcData->values[0]; } return Literal(gcData, gcData->type); diff --git a/test/lit/ctor-eval/shared-i31.wast b/test/lit/ctor-eval/shared-i31.wast index 2c1d8da5929..fe79ce4129e 100644 --- a/test/lit/ctor-eval/shared-i31.wast +++ b/test/lit/ctor-eval/shared-i31.wast @@ -17,6 +17,15 @@ (i32.const 42) ) ) + ;; Also externalizing and internalizing works: this code can be precomputed + ;; and hence removed. + (drop + (any.convert_extern + (extern.convert_any + (global.get $global) + ) + ) + ) (global.get $global) ) diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index f0c659d19e9..f4ba59844d8 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -476,6 +476,24 @@ (string.const "five!") ) ) + + ;; CHECK: [fuzz-exec] calling extern + ;; CHECK-NEXT: [fuzz-exec] note result: extern => string("string") + (func $extern (export "extern") (result externref) + (extern.convert_any + (string.const "string") + ) + ) + + ;; CHECK: [fuzz-exec] calling extern-intern + ;; CHECK-NEXT: [fuzz-exec] note result: extern-intern => string("string") + (func $extern-intern (export "extern-intern") (result anyref) + (any.convert_extern + (extern.convert_any + (string.const "string") + ) + ) + ) ) ;; CHECK: [fuzz-exec] calling new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] note result: new_wtf16_array => string("ello") @@ -604,6 +622,12 @@ ;; CHECK: [fuzz-exec] calling string.measure ;; CHECK-NEXT: [fuzz-exec] note result: string.measure => 5 + +;; CHECK: [fuzz-exec] calling extern +;; CHECK-NEXT: [fuzz-exec] note result: extern => string("string") + +;; CHECK: [fuzz-exec] calling extern-intern +;; CHECK-NEXT: [fuzz-exec] note result: extern-intern => string("string") ;; CHECK-NEXT: [fuzz-exec] comparing compare.1 ;; CHECK-NEXT: [fuzz-exec] comparing compare.10 ;; CHECK-NEXT: [fuzz-exec] comparing compare.2 @@ -624,6 +648,8 @@ ;; CHECK-NEXT: [fuzz-exec] comparing eq.3 ;; CHECK-NEXT: [fuzz-exec] comparing eq.4 ;; CHECK-NEXT: [fuzz-exec] comparing eq.5 +;; CHECK-NEXT: [fuzz-exec] comparing extern +;; CHECK-NEXT: [fuzz-exec] comparing extern-intern ;; CHECK-NEXT: [fuzz-exec] comparing get_codeunit ;; CHECK-NEXT: [fuzz-exec] comparing invalid_code_point ;; CHECK-NEXT: [fuzz-exec] comparing isolated_high_code_point From 6645f0c05b8e9268f35742bb6b0a67e0a9c40795 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 29 Jul 2024 16:27:42 -0700 Subject: [PATCH 483/553] Fix shareability of internalized nulls (#6789) --- src/wasm/literal.cpp | 5 +++-- test/spec/convert_extern.wast | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 test/spec/convert_extern.wast diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index b3128025eea..afbee4435be 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -2700,11 +2700,12 @@ Literal Literal::externalize() const { } Literal Literal::internalize() const { - auto extType = HeapTypes::ext.getBasic(type.getHeapType().getShared()); + auto share = type.getHeapType().getShared(); + auto extType = HeapTypes::ext.getBasic(share); assert(Type::isSubType(type, Type(extType, Nullable)) && "can only internalize external references"); if (isNull()) { - return Literal(std::shared_ptr{}, HeapType::none); + return Literal(std::shared_ptr{}, HeapTypes::none.getBasic(share)); } if (gcData->type.isMaybeShared(HeapType::i31)) { assert(gcData->values[0].type.getHeapType().isMaybeShared(HeapType::i31)); diff --git a/test/spec/convert_extern.wast b/test/spec/convert_extern.wast new file mode 100644 index 00000000000..36254bc4ae5 --- /dev/null +++ b/test/spec/convert_extern.wast @@ -0,0 +1,11 @@ +(module + (func $shared-null (export "shared-null") (result (ref null (shared any))) + ;; The shared null here should remain shared as we internalize it. + (any.convert_extern + (ref.null (shared noextern)) + ) + ) +) + +(assert_return (invoke "shared-null") (ref.null (shared any))) + From e2f666adbae7d5d431e3521ede5d9dd828f0cd97 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 30 Jul 2024 15:11:40 -0400 Subject: [PATCH 484/553] Add a Tarjan's Strongly Connected Component utilty (#6790) Implement a non-recursive version of Tarjan's Strongly Connected Component algorithm that consumes and produces iterators for maximum flexibility. This will be used in an optimization that transforms the heap type graph to use minimal recursion groups, which correspond to the strongly connected components of the type graph. --- src/support/strongly_connected_components.h | 262 +++++++++++++++++ test/gtest/CMakeLists.txt | 1 + test/gtest/scc.cpp | 311 ++++++++++++++++++++ 3 files changed, 574 insertions(+) create mode 100644 src/support/strongly_connected_components.h create mode 100644 test/gtest/scc.cpp diff --git a/src/support/strongly_connected_components.h b/src/support/strongly_connected_components.h new file mode 100644 index 00000000000..d54200ad94d --- /dev/null +++ b/src/support/strongly_connected_components.h @@ -0,0 +1,262 @@ +/* + * Copyright 2024 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. + */ + +#ifndef wasm_support_strongly_connected_components_h +#define wasm_support_strongly_connected_components_h + +#include +#include +#include +#include +#include + +#include + +namespace wasm { + +// A CRTP utility implementing Tarjan's Strongly Connected Component algorithm +// (https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm) +// in terms of iterators. Given the beginning and end iterators over the +// elements in a graph an implementation of `pushChildren` in the CRTP subclass +// that pushes an element's children, provides an iterable over the SCCs, each +// of which is an iterable over the elements in the SCC. All implemented +// iterators are input iterators that mutate the underlying state, so this +// utility can only be used for single-pass algorithms. +template struct SCCs { + SCCs(It inputIt, It inputEnd) : inputIt(inputIt), inputEnd(inputEnd) {} + +private: + using T = typename It::value_type; + + // The iterators over the graph we are calculating the SCCs for. + It inputIt; + It inputEnd; + + // Stack of pending elements to visit, used instead of a recursive visitor. + struct WorkItem { + T item; + std::optional parent = std::nullopt; + bool processedChildren = false; + }; + std::vector workStack; + + // The Tarjan's algorithm stack. Similar to a DFS stack, but elements are only + // popped off once they are committed to a strongly connected component. + // Elements stay on the stack after they are visited iff they have a back edge + // to an element earlier in the stack. + std::vector stack; + + struct ElementInfo { + // Index assigned based on element visitation order. + size_t index; + // The smallest index of the elements reachable from this element. + size_t lowlink; + // Whether this element is still on `stack`. + bool onStack; + }; + std::unordered_map elementInfo; + + // The parent to record when calling into the subclass to push children. + std::optional currParent; + + // The root (i.e. deepest element in the stack) for the current SCC. Empty + // whenever we have yet to find the next SCC. + std::optional currRoot; + + bool stepToNextGroup() { + while (inputIt != inputEnd || !workStack.empty()) { + if (workStack.empty()) { + workStack.push_back({*inputIt++}); + } + while (!workStack.empty()) { + auto& work = workStack.back(); + auto& item = work.item; + + if (!work.processedChildren) { + auto newIndex = elementInfo.size(); + auto [it, inserted] = + elementInfo.insert({item, {newIndex, newIndex, true}}); + if (inserted) { + // This is a new item we have never seen before. We have already + // initialized its associated data. + stack.push_back(item); + + // Leave the element on the work stack because we will have to do + // more work after we have finished processing its children. + work.processedChildren = true; + currParent = item; + static_cast(this)->pushChildren(item); + currParent = std::nullopt; + // Process the pushed children first; we will come back to this item + // later. + continue; + } + + auto& info = it->second; + if (info.onStack) { + assert(work.parent); + // Item is already in the current SCC. Update the parent's lowlink + // if this child has a smaller index than we have seen so far. + auto& parentLowlink = elementInfo[*work.parent].lowlink; + parentLowlink = std::min(parentLowlink, info.index); + } else { + // Item is in an SCC we have already processed, so ignore it + // entirely. + } + // Do not recurse for this item we have seen before. We are done with + // it. + workStack.pop_back(); + continue; + } + + // We have finished processing the children for the current element, so + // we know its final lowlink value. Use it to potentially update the + // parent's lowlink value. + auto& info = elementInfo[item]; + if (work.parent) { + auto& parentLowlink = elementInfo[*work.parent].lowlink; + parentLowlink = std::min(parentLowlink, info.lowlink); + } + + if (info.index == info.lowlink) { + // This element reaches and is reachable by all shallower elements in + // the stack (otherwise they would have already been popped) and does + // not itself reach any deeper elements, so we have found an SCC and + // the current item is its root. + currRoot = item; + workStack.pop_back(); + return true; + } + workStack.pop_back(); + } + } + // We are at the end. + return false; + } + + void stepToNextElem() { + assert(currRoot); + if (stack.back() == *currRoot) { + // This was the last element in the current SCC. We have to find the next + // SCC now. + currRoot = std::nullopt; + } + elementInfo[stack.back()].onStack = false; + stack.pop_back(); + } + + void pushChildren(const T& parent) { + static_assert(&SCCs::pushChildren != &Class::pushChildren, + "SCCs subclass must implement `pushChildren`"); + } + +protected: + // Call this from `Class::pushChildren` to add a child. + void push(const T& item) { + assert(currParent); + workStack.push_back({item, currParent}); + } + +public: + struct SCC { + SCCs* parent; + + // Iterate over the elements in a strongly connected component. + struct Iterator { + using value_type = T; + using difference_type = std::ptrdiff_t; + using reference = T&; + using pointer = T*; + using iterator_category = std::input_iterator_tag; + + SCCs* parent; + std::optional val = std::nullopt; + + bool isEnd() const { return !parent || !parent->currRoot; } + bool operator==(const Iterator& other) const { + return isEnd() == other.isEnd(); + } + bool operator!=(const Iterator& other) const { return !(*this == other); } + T operator*() { return *val; } + T* operator->() { return &*val; } + void setVal() { + if (isEnd()) { + val = std::nullopt; + } else { + val = parent->stack.back(); + } + } + + Iterator& operator++() { + parent->stepToNextElem(); + setVal(); + return *this; + } + Iterator operator++(int) { + auto it = *this; + ++(*this); + return it; + } + }; + + Iterator begin() { + Iterator it = {parent}; + it.setVal(); + return it; + } + Iterator end() { return {nullptr}; } + }; + + // Iterate over the strongly connected components of the graph. + struct Iterator { + using value_type = SCC; + using different_type = std::ptrdiff_t; + using reference = SCC; + using pointer = SCC*; + using iterator_category = std::input_iterator_tag; + + // scc.parent is null iff we are at the end. + SCC scc; + + bool isEnd() const { return !scc.parent; } + bool operator==(const Iterator& other) const { + return isEnd() == other.isEnd(); + } + bool operator!=(const Iterator& other) const { return !(*this == other); } + SCC operator*() { return scc; } + SCC* operator->() { return &scc; } + Iterator& operator++() { + // Skip the rest of the current SCC, if for some reason it was not + // consumed. + for (auto elem : *(*this)) { + (void)elem; + } + if (!scc.parent->stepToNextGroup()) { + // We are at the end, so mark ourselves as such. + scc.parent = nullptr; + } + return *this; + } + void operator++(int) { ++(*this); } + }; + + Iterator begin() { return ++Iterator{this}; } + Iterator end() { return {nullptr}; } +}; + +} // namespace wasm + +#endif // wasm_support_strongly_connected_components_h diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 303e386c642..4604eea77b0 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -8,6 +8,7 @@ set(unittest_SOURCES lattices.cpp possible-contents.cpp printing.cpp + scc.cpp stringify.cpp suffix_tree.cpp type-builder.cpp diff --git a/test/gtest/scc.cpp b/test/gtest/scc.cpp new file mode 100644 index 00000000000..baf509d7f53 --- /dev/null +++ b/test/gtest/scc.cpp @@ -0,0 +1,311 @@ +/* + * Copyright 2024 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 + +#include "support/strongly_connected_components.h" +#include "gtest/gtest.h" + +using namespace wasm; + +struct IntIt { + using value_type = unsigned; + using difference_type = std::ptrdiff_t; + using reference = unsigned&; + using pointer = unsigned*; + using iterator_category = std::input_iterator_tag; + + unsigned i = 0; + + bool operator==(const IntIt& other) const { return i == other.i; } + bool operator!=(const IntIt& other) const { return !(*this == other); } + unsigned operator*() { return i; } + IntIt& operator++() { + ++i; + return *this; + } + IntIt operator++(int) { + IntIt it = *this; + ++(*this); + return it; + } +}; + +struct Graph { + std::vector> graph; + + explicit Graph(unsigned size) : graph(size) {} + + void addEdge(unsigned from, unsigned to) { + assert(from < graph.size()); + assert(to < graph.size()); + graph[from].insert(to); + } + + const std::set& children(unsigned parent) const { + return graph[parent]; + } + + IntIt begin() const { return {}; } + IntIt end() const { return {unsigned(graph.size())}; } +}; + +struct GraphSCCs : SCCs { + const Graph& graph; + GraphSCCs(const Graph& graph) + : SCCs(graph.begin(), graph.end()), graph(graph) {} + + void pushChildren(unsigned parent) { + for (auto child : graph.children(parent)) { + push(child); + } + } +}; + +using SCCSet = std::set>; + +SCCSet getSCCs(const Graph& graph) { + SCCSet set; + for (auto scc : GraphSCCs(graph)) { + set.emplace(scc.begin(), scc.end()); + } + return set; +} + +TEST(SCCTest, Empty) { + Graph graph(0); + GraphSCCs sccs(graph); + auto it = sccs.begin(); + EXPECT_EQ(it, sccs.end()); + + EXPECT_EQ(getSCCs(graph), SCCSet{}); +} + +TEST(SCCTest, Singleton) { + Graph graph(1); + GraphSCCs sccs(graph); + + auto it = sccs.begin(); + ASSERT_NE(it, sccs.end()); + + auto scc = *it; + auto sccIt = scc.begin(); + ASSERT_NE(sccIt, scc.end()); + EXPECT_EQ(*sccIt, 0u); + + ++sccIt; + EXPECT_EQ(sccIt, scc.end()); + ASSERT_NE(it, sccs.end()); + + ++it; + EXPECT_EQ(it, sccs.end()); + + EXPECT_EQ(getSCCs(graph), SCCSet{{0}}); +} + +TEST(SCCTest, SingletonLoop) { + // Same as above, but now there is an edge. The results are the same. + Graph graph(1); + graph.addEdge(0, 0); + GraphSCCs sccs(graph); + + auto it = sccs.begin(); + ASSERT_NE(it, sccs.end()); + + auto scc = *it; + auto sccIt = scc.begin(); + ASSERT_NE(sccIt, scc.end()); + EXPECT_EQ(*sccIt, 0u); + + ++sccIt; + EXPECT_EQ(sccIt, scc.end()); + ASSERT_NE(it, sccs.end()); + + ++it; + EXPECT_EQ(it, sccs.end()); + + EXPECT_EQ(getSCCs(graph), SCCSet{{0}}); +} + +TEST(SCCTest, DerefPostIncrement) { + // Valid input iterators must have *it++ yield the value from before the + // increment. + Graph graph(1); + GraphSCCs sccs(graph); + auto it = sccs.begin()->begin(); + EXPECT_EQ(*it++, 0u); +} + +TEST(SCCTest, Disconnected) { + // There are no edges between the vertices. + Graph graph(3); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0}, {1}, {2}})); +} + +TEST(SCCTest, Chain) { + // 0 -> 1 -> 2 + Graph graph(3); + graph.addEdge(0, 1); + graph.addEdge(1, 2); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0}, {1}, {2}})); +} + +TEST(SCCTest, ChainReverse) { + // 0 <- 1 <- 2 + Graph graph(3); + graph.addEdge(2, 1); + graph.addEdge(1, 0); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0}, {1}, {2}})); +} + +TEST(SCCTest, Loop) { + // 0 -> 1 -> 2 -> 0 + // There is only one SCC here. + Graph graph(3); + graph.addEdge(0, 1); + graph.addEdge(1, 2); + graph.addEdge(2, 0); + EXPECT_EQ(getSCCs(graph), (SCCSet({{0, 1, 2}}))); +} + +TEST(SCCTest, LoopReverse) { + // 0 <- 1 <- 2 <- 0 + // There is only one SCC here. + Graph graph(3); + graph.addEdge(0, 2); + graph.addEdge(2, 1); + graph.addEdge(1, 0); + EXPECT_EQ(getSCCs(graph), (SCCSet({{0, 1, 2}}))); +} + +TEST(SCCTest, Full) { + // Fully connected graph has one SCC. + Graph graph(3); + for (unsigned i = 0; i < 3; ++i) { + for (unsigned j = 0; j < 3; ++j) { + graph.addEdge(i, j); + } + } + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1, 2}})); +} + +TEST(SCCTest, TwoAndOne) { + // 0 <-> 1 -> 2 + Graph graph(3); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + graph.addEdge(1, 2); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1}, {2}})); +} + +TEST(SCCTest, TwoAndOneRedundant) { + // 2 <- 0 <-> 1 -> 2 + Graph graph(3); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + graph.addEdge(1, 2); + // New from previous, doesn't affect result. + graph.addEdge(0, 2); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1}, {2}})); +} + +TEST(SCCTest, OneAndTwo) { + // 0 -> 1 <-> 2 + Graph graph(3); + graph.addEdge(0, 1); + graph.addEdge(1, 2); + graph.addEdge(2, 1); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0}, {1, 2}})); +} + +TEST(SCCTest, TwoAndTwoDisconnected) { + // 0 <-> 1 2 <-> 3 + Graph graph(4); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + graph.addEdge(2, 3); + graph.addEdge(3, 2); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1}, {2, 3}})); +} + +TEST(SCCTest, TwoAndTwo) { + // 0 <-> 1 -> 2 <-> 3 + Graph graph(4); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + graph.addEdge(2, 3); + graph.addEdge(3, 2); + // New from previous, doesn't affect result + graph.addEdge(1, 2); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1}, {2, 3}})); +} + +TEST(SCCTest, DoublyLinkedList) { + // 0 <-> 1 <-> 2 <-> 3 + Graph graph(4); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + graph.addEdge(2, 3); + graph.addEdge(3, 2); + graph.addEdge(1, 2); + // New from previous, combines SCCs. + graph.addEdge(2, 1); + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1, 2, 3}})); +} + +TEST(SCCTest, BigTree) { + // 012 <- 345 -> 678 + Graph graph(9); + graph.addEdge(0, 1); + graph.addEdge(1, 2); + graph.addEdge(2, 0); + + graph.addEdge(3, 4); + graph.addEdge(4, 5); + graph.addEdge(5, 3); + + graph.addEdge(6, 7); + graph.addEdge(7, 8); + graph.addEdge(8, 6); + + graph.addEdge(3, 2); + graph.addEdge(5, 6); + + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}})); +} + +TEST(SCCTest, BigDiamond) { + // 67 <- 01 <- 23 -> 45 -> 67 + Graph graph(8); + graph.addEdge(0, 1); + graph.addEdge(1, 0); + + graph.addEdge(2, 3); + graph.addEdge(3, 2); + + graph.addEdge(4, 5); + graph.addEdge(5, 4); + + graph.addEdge(6, 7); + graph.addEdge(7, 6); + + graph.addEdge(2, 0); + graph.addEdge(2, 4); + graph.addEdge(0, 6); + graph.addEdge(4, 6); + + EXPECT_EQ(getSCCs(graph), (SCCSet{{0, 1}, {2, 3}, {4, 5}, {6, 7}})); +} From 5078d4daffb39edb91785e5fd6d28c5ff92478e4 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 30 Jul 2024 14:29:28 -0700 Subject: [PATCH 485/553] Add a customizable title to Metrics reporting (#6792) Before the PR: $ bin/wasm-opt test/hello_world.wat --metrics total [exports] : 1 [funcs] : 1 [globals] : 0 [imports] : 0 [memories] : 1 [memory-data] : 0 [tables] : 0 [tags] : 0 [total] : 3 [vars] : 0 Binary : 1 LocalGet : 2 After the PR: $ bin/wasm-opt test/hello_world.wat --metrics Metrics total [exports] : 1 [funcs] : 1 ... Note the "Metrics" addition at the top. And the title can be customized: $ bin/wasm-opt test/hello_world.wat --metrics=text Metrics: text total [exports] : 1 [funcs] : 1 The custom title can be helpful when multiple invocations of metrics are used at once, e.g. --metrics=before -O3 --metrics=after. --- CHANGELOG.md | 3 ++ src/passes/Metrics.cpp | 7 +++++ src/passes/pass.cpp | 4 ++- test/lit/help/wasm-metadce.test | 4 ++- test/lit/help/wasm-opt.test | 4 ++- test/lit/help/wasm2js.test | 4 ++- test/lit/passes/metrics.wast | 30 +++++++++++++++++++ test/passes/O3_low-memory-unused_metrics.txt | 1 + test/passes/converge_O3_metrics.bin.txt | 3 ++ test/passes/func-metrics.txt | 6 ++++ test/passes/fuzz_metrics_noprint.bin.txt | 1 + test/passes/metrics_all-features.txt | 2 ++ .../metrics_strip-debug_metrics.bin.txt | 2 ++ .../metrics_strip-producers_metrics.bin.txt | 2 ++ test/passes/print_g_metrics.bin.txt | 1 + test/passes/sparse_matrix_liveness.bin.txt | 2 ++ ...e-to-fuzz_all-features_metrics_noprint.txt | 1 + 17 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 test/lit/passes/metrics.wast diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e301ef3a6..1c4e369c9bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ Current Trunk apply to the most recent --foo pass on the commandline, if foo is a pass (while global pass arguments - that are not the name of a pass - remain, as before, global for all passes). (#6687) + - The Metrics pass now takes an optional argument to use as the title, + `--metrics=text` will show that text before the metrics. Each instance of + Metrics can have unique text, `--metrics=before -O3 --metrics=after`. (#6792) - Add C and JS APIs to control more pass options (trapsNeverHappen, closedWorld, generateStackIR, optimizeStackIR, and the list of skipped passes). (#6713) diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp index 1778eb9bd09..186d7e6956f 100644 --- a/src/passes/Metrics.cpp +++ b/src/passes/Metrics.cpp @@ -45,6 +45,13 @@ struct Metrics } void doWalkModule(Module* module) { + std::string title = getArgumentOrDefault("metrics", ""); + std::cout << "Metrics"; + if (!title.empty()) { + std::cout << ": " << title; + } + std::cout << '\n'; + ImportInfo imports(*module); // global things diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ec6077941d4..3f84ee60464 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -275,7 +275,9 @@ void PassRegistry::registerPasses() { createMergeSimilarFunctionsPass); registerPass( "merge-locals", "merges locals when beneficial", createMergeLocalsPass); - registerPass("metrics", "reports metrics", createMetricsPass); + registerPass("metrics", + "reports metrics (with an optional title, --metrics[=TITLE])", + createMetricsPass); registerPass("minify-imports", "minifies import names (only those, and not export names), and " "emits a mapping to the minified ones", diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index 66013f81aa8..8a2107ca79f 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -251,7 +251,9 @@ ;; CHECK-NEXT: --merge-similar-functions merges similar functions when ;; CHECK-NEXT: benefical ;; CHECK-NEXT: -;; CHECK-NEXT: --metrics reports metrics +;; CHECK-NEXT: --metrics reports metrics (with an +;; CHECK-NEXT: optional title, +;; CHECK-NEXT: --metrics[=TITLE]) ;; CHECK-NEXT: ;; CHECK-NEXT: --minify-imports minifies import names (only ;; CHECK-NEXT: those, and not export names), diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index c89baaf4a73..a48b8e303e4 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -260,7 +260,9 @@ ;; CHECK-NEXT: --merge-similar-functions merges similar functions when ;; CHECK-NEXT: benefical ;; CHECK-NEXT: -;; CHECK-NEXT: --metrics reports metrics +;; CHECK-NEXT: --metrics reports metrics (with an +;; CHECK-NEXT: optional title, +;; CHECK-NEXT: --metrics[=TITLE]) ;; CHECK-NEXT: ;; CHECK-NEXT: --minify-imports minifies import names (only ;; CHECK-NEXT: those, and not export names), diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 45bef7d7383..0b87ad0aa66 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -214,7 +214,9 @@ ;; CHECK-NEXT: --merge-similar-functions merges similar functions when ;; CHECK-NEXT: benefical ;; CHECK-NEXT: -;; CHECK-NEXT: --metrics reports metrics +;; CHECK-NEXT: --metrics reports metrics (with an +;; CHECK-NEXT: optional title, +;; CHECK-NEXT: --metrics[=TITLE]) ;; CHECK-NEXT: ;; CHECK-NEXT: --minify-imports minifies import names (only ;; CHECK-NEXT: those, and not export names), diff --git a/test/lit/passes/metrics.wast b/test/lit/passes/metrics.wast new file mode 100644 index 00000000000..5a210ae6d2e --- /dev/null +++ b/test/lit/passes/metrics.wast @@ -0,0 +1,30 @@ +;; Test that we can pass an optional title to metrics instances. +;; +;; RUN: wasm-opt %s --metrics --metrics=second --remove-unused-module-elements --metrics=third --metrics -q | filecheck %s +;; +;; The number of functions decreases to 0 after --remove-unused-module-elements, +;; showing that we display the proper metrics at each point in time. +;; +;; CHECK: Metrics +;; CHECK-NEXT: total +;; CHECK-NEXT: [exports] : 0 +;; CHECK-NEXT: [funcs] : 1 +;; +;; CHECK: Metrics: second +;; CHECK-NEXT: total +;; CHECK-NEXT: [exports] : 0 +;; CHECK-NEXT: [funcs] : 1 +;; +;; CHECK: Metrics: third +;; CHECK-NEXT: total +;; CHECK-NEXT: [exports] : 0 +;; CHECK-NEXT: [funcs] : 0 -1 +;; +;; CHECK: Metrics +;; CHECK-NEXT: total +;; CHECK-NEXT: [exports] : 0 +;; CHECK-NEXT: [funcs] : 0 + +(module + (func $foo) +) diff --git a/test/passes/O3_low-memory-unused_metrics.txt b/test/passes/O3_low-memory-unused_metrics.txt index fd9245adc2a..8806e9a043c 100644 --- a/test/passes/O3_low-memory-unused_metrics.txt +++ b/test/passes/O3_low-memory-unused_metrics.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 1 [funcs] : 1 diff --git a/test/passes/converge_O3_metrics.bin.txt b/test/passes/converge_O3_metrics.bin.txt index 312e67fe794..712172cc794 100644 --- a/test/passes/converge_O3_metrics.bin.txt +++ b/test/passes/converge_O3_metrics.bin.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 2 [funcs] : 6 @@ -231,6 +232,7 @@ total (i32.const 0) ) ) +Metrics total [exports] : 2 [funcs] : 6 @@ -457,6 +459,7 @@ total (i32.const 0) ) ) +Metrics total [exports] : 2 [funcs] : 6 diff --git a/test/passes/func-metrics.txt b/test/passes/func-metrics.txt index afd6afe0724..b61e8146ec9 100644 --- a/test/passes/func-metrics.txt +++ b/test/passes/func-metrics.txt @@ -1,3 +1,4 @@ +Metrics global [exports] : 0 [funcs] : 3 @@ -106,6 +107,7 @@ func: ifs ) ) ) +Metrics global [exports] : 0 [funcs] : 0 @@ -117,6 +119,7 @@ global [total] : 0 (module ) +Metrics global [exports] : 2 [funcs] : 3 @@ -194,6 +197,7 @@ export: b (func_b) (call $waka) ) ) +Metrics global [exports] : 1 [funcs] : 1 @@ -228,6 +232,7 @@ start: func_a (call $waka) ) ) +Metrics global [exports] : 0 [funcs] : 1 @@ -258,6 +263,7 @@ start: func_a (call $waka) ) ) +Metrics global [exports] : 1 [funcs] : 1 diff --git a/test/passes/fuzz_metrics_noprint.bin.txt b/test/passes/fuzz_metrics_noprint.bin.txt index c5dab17e75b..2f1719633b8 100644 --- a/test/passes/fuzz_metrics_noprint.bin.txt +++ b/test/passes/fuzz_metrics_noprint.bin.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 23 [funcs] : 34 diff --git a/test/passes/metrics_all-features.txt b/test/passes/metrics_all-features.txt index 2fcf292573d..a5e80db455c 100644 --- a/test/passes/metrics_all-features.txt +++ b/test/passes/metrics_all-features.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 0 [funcs] : 1 @@ -80,6 +81,7 @@ total ) ) ) +Metrics total [exports] : 0 [funcs] : 0 diff --git a/test/passes/metrics_strip-debug_metrics.bin.txt b/test/passes/metrics_strip-debug_metrics.bin.txt index ef1b5c01373..848db9e32f6 100644 --- a/test/passes/metrics_strip-debug_metrics.bin.txt +++ b/test/passes/metrics_strip-debug_metrics.bin.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 1 [funcs] : 1 @@ -9,6 +10,7 @@ total [total] : 1 [vars] : 0 Nop : 1 +Metrics total [exports] : 1 [funcs] : 1 diff --git a/test/passes/metrics_strip-producers_metrics.bin.txt b/test/passes/metrics_strip-producers_metrics.bin.txt index a983af3a9f8..65d6bd6a80f 100644 --- a/test/passes/metrics_strip-producers_metrics.bin.txt +++ b/test/passes/metrics_strip-producers_metrics.bin.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 1 [funcs] : 1 @@ -9,6 +10,7 @@ total [total] : 1 [vars] : 0 Nop : 1 +Metrics total [exports] : 1 [funcs] : 1 diff --git a/test/passes/print_g_metrics.bin.txt b/test/passes/print_g_metrics.bin.txt index e5ac1edae13..2acec546f4a 100644 --- a/test/passes/print_g_metrics.bin.txt +++ b/test/passes/print_g_metrics.bin.txt @@ -66,6 +66,7 @@ (nop) ) ) +Metrics total [exports] : 3 [funcs] : 3 diff --git a/test/passes/sparse_matrix_liveness.bin.txt b/test/passes/sparse_matrix_liveness.bin.txt index 7e9429545d0..62f7582c8f6 100644 --- a/test/passes/sparse_matrix_liveness.bin.txt +++ b/test/passes/sparse_matrix_liveness.bin.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 1 [funcs] : 1 @@ -12,6 +13,7 @@ total Const : 1 LocalGet : 1 LocalSet : 1 +Metrics total [exports] : 1 [funcs] : 1 diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index 6db0f908dd4..07afaa7ebf4 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,3 +1,4 @@ +Metrics total [exports] : 5 [funcs] : 9 From e6bbff7846cad9daf178b6917d78abe5cfcd5771 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 30 Jul 2024 14:29:47 -0700 Subject: [PATCH 486/553] Fix shareability of externalized nulls (#6791) --- src/wasm/literal.cpp | 5 +++-- test/spec/convert_extern.wast | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index afbee4435be..7e4aeb8c7f4 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -2687,11 +2687,12 @@ Literal Literal::relaxedFmsF64x2(const Literal& left, Literal Literal::externalize() const { assert(type.isRef() && type.getHeapType().getUnsharedTop() == HeapType::any && "can only externalize internal references"); + auto share = type.getHeapType().getShared(); if (isNull()) { - return Literal(std::shared_ptr{}, HeapType::noext); + return Literal(std::shared_ptr{}, HeapTypes::noext.getBasic(share)); } auto heapType = type.getHeapType(); - auto extType = HeapTypes::ext.getBasic(heapType.getShared()); + auto extType = HeapTypes::ext.getBasic(share); if (heapType.isMaybeShared(HeapType::i31)) { return Literal(std::make_shared(heapType, Literals{*this}), extType); diff --git a/test/spec/convert_extern.wast b/test/spec/convert_extern.wast index 36254bc4ae5..443bc89560f 100644 --- a/test/spec/convert_extern.wast +++ b/test/spec/convert_extern.wast @@ -5,7 +5,15 @@ (ref.null (shared noextern)) ) ) + + (func $shared-null-rev (export "shared-null-rev") (result (ref null (shared extern))) + ;; As before, but the reverse conversion. + (extern.convert_any + (ref.null (shared any)) + ) + ) ) (assert_return (invoke "shared-null") (ref.null (shared any))) +(assert_return (invoke "shared-null-rev") (ref.null (shared extern))) From c68978114ccb12a6cef8ba5651ef3e0deb03f879 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 31 Jul 2024 10:16:36 -0700 Subject: [PATCH 487/553] Use Names::getValidNameGivenExisting in binary reading (#6793) We had a TODO to use it once Names was optimized, which it has been. The Names version is also far faster. When building https://github.com/JetBrains/kotlinconf-app it saves 70 seconds(!). --- src/wasm/wasm-binary.cpp | 11 +++------ test/duplicated_names.wasm | Bin 64 -> 0 bytes test/duplicated_names.wasm.fromBinary | 13 ----------- ...duplicated_names_collision.wasm.fromBinary | 13 ----------- .../binary/duplicated_names_collision.test | 21 ++++++++++++++++++ .../duplicated_names_collision.test.wasm} | Bin ...duplicated_names_collision_underscore.test | 21 ++++++++++++++++++ ...cated_names_collision_underscore.test.wasm | Bin 0 -> 66 bytes test/lit/binary/name-overlap.test | 5 +++-- 9 files changed, 48 insertions(+), 36 deletions(-) delete mode 100644 test/duplicated_names.wasm delete mode 100644 test/duplicated_names.wasm.fromBinary delete mode 100644 test/duplicated_names_collision.wasm.fromBinary create mode 100644 test/lit/binary/duplicated_names_collision.test rename test/{duplicated_names_collision.wasm => lit/binary/duplicated_names_collision.test.wasm} (100%) create mode 100644 test/lit/binary/duplicated_names_collision_underscore.test create mode 100644 test/lit/binary/duplicated_names_collision_underscore.test.wasm diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0a65fbadbf4..3cb3b08dafa 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -19,6 +19,7 @@ #include "ir/eh-utils.h" #include "ir/module-utils.h" +#include "ir/names.h" #include "ir/table-utils.h" #include "ir/type-updating.h" #include "support/bits.h" @@ -3551,14 +3552,8 @@ class NameProcessor { std::unordered_set usedNames; Name deduplicate(Name base) { - // TODO: Consider using Names::getValidNameGivenExisting but that does give - // longer names, and it is very noticeable in this location, so - // perhaps optimize that first. - Name name = base; - // De-duplicate names by appending .1, .2, etc. - for (int i = 1; !usedNames.insert(name).second; ++i) { - name = std::string(base.str) + std::string(".") + std::to_string(i); - } + auto name = Names::getValidNameGivenExisting(base, usedNames); + usedNames.insert(name); return name; } }; diff --git a/test/duplicated_names.wasm b/test/duplicated_names.wasm deleted file mode 100644 index 33dfb229fd3fd4ae986cb99cd4877fc844ee361b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64 zcmZQbEY4+QU|?WmWlUgTtY>Cn26DIrm{}Mc8MuK2BZy$)W)Nq|OUzAW6kujxPRq|{ J1QARi0s!K52Cn26DIrm{}Mc8MuK2BZy$)W{_mbOUzAW6k=vzPRq|{ M1QATEKqB4{0QI5?f&c&j literal 0 HcmV?d00001 diff --git a/test/lit/binary/name-overlap.test b/test/lit/binary/name-overlap.test index 7f531873783..f5c47e50a68 100644 --- a/test/lit/binary/name-overlap.test +++ b/test/lit/binary/name-overlap.test @@ -17,6 +17,7 @@ ;; that we leave the name from the names section as it is, and only adjust the ;; temp name.) -;; CHECK: (global $global$1 i32 (i32.const 1)) -;; CHECK-NEXT: (global $global$1.1 i32 (i32.const 0)) +;; CHECK: (global $global$1 i32 (i32.const 1)) + +;; CHECK: (global $global$1_1 i32 (i32.const 0)) From 705c28d3a33d606c8c938d079dbf82de7e7a6b7d Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 1 Aug 2024 11:56:43 -0700 Subject: [PATCH 488/553] [NFC] Avoid a temp local (#6800) The local was only used once, so it didn't really add much. And, it was causing some compilers to error on "unused variable" (when building without assertions, the use was removed). --- src/wasm/literal.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 7e4aeb8c7f4..f2100ea712e 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -2702,9 +2702,9 @@ Literal Literal::externalize() const { Literal Literal::internalize() const { auto share = type.getHeapType().getShared(); - auto extType = HeapTypes::ext.getBasic(share); - assert(Type::isSubType(type, Type(extType, Nullable)) && - "can only internalize external references"); + assert( + Type::isSubType(type, Type(HeapTypes::ext.getBasic(share), Nullable)) && + "can only internalize external references"); if (isNull()) { return Literal(std::shared_ptr{}, HeapTypes::none.getBasic(share)); } From 2a7c0931edf681076e678a0e8092e170333c6e86 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 1 Aug 2024 15:08:25 -0400 Subject: [PATCH 489/553] Add a disjoint sets (union-find) utility (#6797) This will be used in an upcoming type optimization pass and may be generally useful. --- src/support/disjoint_sets.h | 87 ++++++++++++++++++++++++++++ test/gtest/CMakeLists.txt | 1 + test/gtest/disjoint_sets.cpp | 106 +++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 src/support/disjoint_sets.h create mode 100644 test/gtest/disjoint_sets.cpp diff --git a/src/support/disjoint_sets.h b/src/support/disjoint_sets.h new file mode 100644 index 00000000000..198e5cb67c2 --- /dev/null +++ b/src/support/disjoint_sets.h @@ -0,0 +1,87 @@ +/* + * Copyright 2024 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. + */ + +#ifndef wasm_support_disjoint_sets_h +#define wasm_support_disjoint_sets_h + +#include +#include +#include + +namespace wasm { + +// A disjoint set forest (a.k.a. union-find) implementation. See +// https://en.wikipedia.org/wiki/Disjoint-set_data_structure. +struct DisjointSets { + struct ElemInfo { + // The index of the parent element, or the index of the element itself if it + // has no parent. + size_t parent; + // An upper bound on the height of the tree rooted at this element. + size_t rank; + }; + std::vector info; + + // Add an element and return its index. + size_t addSet() { + size_t ret = info.size(); + info.push_back({ret, 0}); + return ret; + } + + // Get the representative element of the set to which `elem` belongs. + size_t getRoot(size_t elem) { + assert(elem < info.size()); + size_t root = elem; + // Follow parent pointers up to the root. + for (; info[root].parent != root; root = info[root].parent) { + } + // Compress the path to make subsequent getRoots of this set faster. + while (elem != root) { + size_t parent = info[elem].parent; + info[elem].parent = root; + elem = parent; + } + return root; + } + + // Join the sets to which the elements belong and return the representative + // element of the union. + size_t getUnion(size_t elem1, size_t elem2) { + assert(elem1 < info.size() && elem2 < info.size()); + size_t root1 = getRoot(elem1); + size_t root2 = getRoot(elem2); + if (root1 == root2) { + // Already in the same set. + return root1; + } + // Canonicalize so that root1 has the greater rank. + if (info[root1].rank < info[root2].rank) { + std::swap(root1, root2); + } + // Merge the trees, smaller into larger. + info[root2].parent = root1; + // If the ranks were equal, the new root has a larger rank. + if (info[root1].rank == info[root2].rank) { + ++info[root1].rank; + } + return root1; + } +}; + +} // namespace wasm + +#endif // wasm_support_disjoint_sets_h diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 4604eea77b0..538ec1cdc67 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories(../../src/wasm) set(unittest_SOURCES cfg.cpp dfa_minimization.cpp + disjoint_sets.cpp json.cpp lattices.cpp possible-contents.cpp diff --git a/test/gtest/disjoint_sets.cpp b/test/gtest/disjoint_sets.cpp new file mode 100644 index 00000000000..f974957a3ca --- /dev/null +++ b/test/gtest/disjoint_sets.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2024 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 "support/disjoint_sets.h" +#include "gtest/gtest.h" + +using namespace wasm; + +TEST(DisjointSetsTest, NewSets) { + DisjointSets sets; + auto elem1 = sets.addSet(); + auto elem2 = sets.addSet(); + EXPECT_NE(elem1, elem2); + + auto root1 = sets.getRoot(elem1); + EXPECT_EQ(elem1, root1); + + auto root2 = sets.getRoot(elem2); + EXPECT_EQ(elem2, root2); +} + +TEST(DisjointSetsTest, Union) { + DisjointSets sets; + auto elem1 = sets.addSet(); + auto elem2 = sets.addSet(); + auto root = sets.getUnion(elem1, elem2); + EXPECT_TRUE(root == elem1 || root == elem2); + + auto root1 = sets.getRoot(elem1); + auto root2 = sets.getRoot(elem2); + EXPECT_EQ(root1, root); + EXPECT_EQ(root2, root); +} + +TEST(DisjointSetsTest, TwoUnions) { + DisjointSets sets; + auto elem1 = sets.addSet(); + auto elem2 = sets.addSet(); + auto elem3 = sets.addSet(); + auto elem4 = sets.addSet(); + + auto rootA = sets.getUnion(elem1, elem3); + auto rootB = sets.getUnion(elem2, elem4); + EXPECT_EQ(sets.getRoot(elem1), rootA); + EXPECT_EQ(sets.getRoot(elem2), rootB); + EXPECT_EQ(sets.getRoot(elem3), rootA); + EXPECT_EQ(sets.getRoot(elem4), rootB); + EXPECT_NE(rootA, rootB); +} + +TEST(DisjointSetsTest, UnionList) { + constexpr size_t count = 16; + DisjointSets sets; + size_t elems[count]; + for (size_t i = 0; i < count; ++i) { + elems[i] = sets.addSet(); + } + + for (size_t i = 1; i < count; ++i) { + sets.getUnion(elems[i], elems[i - 1]); + } + + auto root = sets.getRoot(elems[0]); + for (size_t rep = 0; rep < 2; ++rep) { + for (size_t i = 0; i < count; ++i) { + auto currRoot = sets.getRoot(elems[i]); + EXPECT_EQ(currRoot, root); + } + } +} + +TEST(DisjointSetsTest, UnionTree) { + constexpr size_t count = 16; + DisjointSets sets; + size_t elems[count]; + for (size_t i = 0; i < count; ++i) { + elems[i] = sets.addSet(); + } + + for (size_t stride = 2; stride <= count; stride *= 2) { + for (size_t i = 0; i < count; i += stride) { + sets.getUnion(elems[i], elems[i + stride / 2]); + } + } + + auto root = sets.getRoot(elems[0]); + for (size_t rep = 0; rep < 2; ++rep) { + for (size_t i = 0; i < count; ++i) { + auto currRoot = sets.getRoot(elems[i]); + EXPECT_EQ(currRoot, root); + } + } +} From 8d2c9ffc6d2cc89d53403986fb330a3953ddf3b8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 1 Aug 2024 12:48:41 -0700 Subject: [PATCH 490/553] Fix shareability handling in TypeSSA collision logic (#6798) --- src/passes/TypeSSA.cpp | 1 + test/lit/passes/type-ssa-shared.wast | 39 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index dcd56f5d605..1d00efb5bff 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -111,6 +111,7 @@ std::vector ensureTypesAreInNewRecGroup(RecGroup recGroup, builder[i].subTypeOf(*super); } builder[i].setOpen(type.isOpen()); + builder[i].setShared(type.getShared()); } // Implement the hash as a struct with "random" fields, and add it. diff --git a/test/lit/passes/type-ssa-shared.wast b/test/lit/passes/type-ssa-shared.wast index d6266f7d9e5..e3e1db2f241 100644 --- a/test/lit/passes/type-ssa-shared.wast +++ b/test/lit/passes/type-ssa-shared.wast @@ -70,3 +70,42 @@ ) ) ) + +;; We end up needing to do some extra work to ensure types are in a new rec +;; group, that is, that it does not overlap with an existing rec group. While +;; doing so we should apply shareability properly and not error. (Specifically, +;; when we create a new subtype of $A, it must differ from $B.) +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $A (sub (shared (array (mut i32))))) + (type $A (sub (shared (array (mut i32))))) + ;; CHECK: (type $B (sub $A (shared (array (mut i32))))) + (type $B (sub $A (shared (array (mut i32))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A_1 (sub $A (shared (array (mut i32))))) + + ;; CHECK: (type $4 (struct (field (mut i32)) (field (mut i32)) (field (mut f64)) (field (mut f64)) (field (mut i32)) (field (mut f64)) (field (mut f64)) (field (mut i32)) (field (mut i32)) (field (mut i32)) (field (mut i32)))) + + ;; CHECK: (func $func (type $0) + ;; CHECK-NEXT: (local $local (ref $B)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (array.new_default $A_1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func + ;; Keep the type $B alive. + (local $local (ref $B)) + + ;; Create an $A, which TypeSSA can specialize. + (drop + (array.new_default $A + (i32.const 0) + ) + ) + ) +) + From 53d54d7e4fca4bb971676c2e93440c8f25ec6a6a Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Mon, 5 Aug 2024 09:21:40 -0700 Subject: [PATCH 491/553] [LegalizeJSInterface] Use explicit names for stub functions (#6806) --- src/passes/LegalizeJSInterface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index bfc7e192b15..01a8c240175 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -275,9 +275,11 @@ struct LegalizeJSInterface : public Pass { legalIm->name = Name(std::string("legalimport$") + im->name.toString()); legalIm->module = im->module; legalIm->base = im->base; + legalIm->hasExplicitName = true; auto stub = std::make_unique(); stub->name = Name(std::string("legalfunc$") + im->name.toString()); stub->type = im->type; + stub->hasExplicitName = true; auto* call = module->allocator.alloc(); call->target = legalIm->name; From 5573cdb80e2ac9aed4cd5f20c3e41dc3138ef426 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 5 Aug 2024 15:27:44 -0400 Subject: [PATCH 492/553] Add a utility for iterating over all topological orders (#6801) Use an extension of Kahn's algorithm for finding topological orders that iteratively makes every possible choice at every step to find all the topological orders. The order being constructed and the set of possible choices are managed in-place in the same buffer, so the algorithm takes linear time and space plus amortized constant time per generated order. This will be used in an upcoming type optimization. --- src/support/CMakeLists.txt | 1 + src/support/strongly_connected_components.h | 4 +- src/support/topological_orders.cpp | 118 ++++++++++++++++++++ src/support/topological_orders.h | 104 +++++++++++++++++ test/gtest/CMakeLists.txt | 1 + test/gtest/topological-orders.cpp | 101 +++++++++++++++++ 6 files changed, 327 insertions(+), 2 deletions(-) create mode 100644 src/support/topological_orders.cpp create mode 100644 src/support/topological_orders.h create mode 100644 test/gtest/topological-orders.cpp diff --git a/src/support/CMakeLists.txt b/src/support/CMakeLists.txt index 54ee7b206e4..20470a3cd7e 100644 --- a/src/support/CMakeLists.txt +++ b/src/support/CMakeLists.txt @@ -14,6 +14,7 @@ set(support_SOURCES safe_integer.cpp string.cpp threads.cpp + topological_orders.cpp utilities.cpp ${support_HEADERS} ) diff --git a/src/support/strongly_connected_components.h b/src/support/strongly_connected_components.h index d54200ad94d..7fcbdf14c8e 100644 --- a/src/support/strongly_connected_components.h +++ b/src/support/strongly_connected_components.h @@ -223,8 +223,8 @@ template struct SCCs { // Iterate over the strongly connected components of the graph. struct Iterator { using value_type = SCC; - using different_type = std::ptrdiff_t; - using reference = SCC; + using difference_type = std::ptrdiff_t; + using reference = SCC&; using pointer = SCC*; using iterator_category = std::input_iterator_tag; diff --git a/src/support/topological_orders.cpp b/src/support/topological_orders.cpp new file mode 100644 index 00000000000..939c76c6e44 --- /dev/null +++ b/src/support/topological_orders.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2024 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 + +#include "topological_orders.h" + +namespace wasm { + +TopologicalOrders::Selector +TopologicalOrders::Selector::select(TopologicalOrders& ctx) { + assert(count >= 1); + assert(start + count <= ctx.buf.size()); + auto selection = ctx.buf[start]; + // The next selector will select the next index and will not be able to choose + // the vertex we just selected. + Selector next = {start + 1, count - 1, 0}; + // Append any child that this selection makes available to the choices for the + // next selector. + for (auto child : ctx.graph[selection]) { + assert(ctx.indegrees[child] > 0); + if (--ctx.indegrees[child] == 0) { + ctx.buf[next.start + next.count++] = child; + } + } + return next; +} + +std::optional +TopologicalOrders::Selector::advance(TopologicalOrders& ctx) { + assert(count >= 1); + // Undo the current selection. Backtrack by incrementing the in-degree for + // each child of the vertex we are unselecting. No need to remove the newly + // unavailable children from the buffer; they will be overwritten with valid + // selections. + auto unselected = ctx.buf[start]; + for (auto child : ctx.graph[unselected]) { + ++ctx.indegrees[child]; + } + if (index == count - 1) { + // We are wrapping back to the original configuration. The current selection + // element needs to go back on the end and everything else needs to be + // shifted back to its original location. This ensures that we leave + // everything how we found it so the previous selector can make its next + // selection without observing anything having changed in the meantime. + for (size_t i = 1; i < count; ++i) { + ctx.buf[start + i - 1] = ctx.buf[start + i]; + } + ctx.buf[start + count - 1] = unselected; + return std::nullopt; + } + // Otherwise, just swap the next selection into the first position and + // finalize the selection. + std::swap(ctx.buf[start], ctx.buf[start + ++index]); + return select(ctx); +} + +TopologicalOrders::TopologicalOrders( + const std::vector>& graph) + : graph(graph), indegrees(graph.size()), buf(graph.size()) { + if (graph.size() == 0) { + return; + } + // Find the in-degree of each vertex. + for (const auto& vertex : graph) { + for (auto child : vertex) { + ++indegrees[child]; + } + } + // Set up the first selector with its possible selections. + selectors.reserve(graph.size()); + selectors.push_back({0, 0, 0}); + auto& first = selectors.back(); + for (size_t i = 0; i < graph.size(); ++i) { + if (indegrees[i] == 0) { + buf[first.count++] = i; + } + } + // Initialize the full stack of selectors. + while (selectors.size() < graph.size()) { + selectors.push_back(selectors.back().select(*this)); + } +} + +void TopologicalOrders::advance() { + // Find the last selector that can be advanced, popping any that cannot. + std::optional next; + while (!selectors.empty() && !(next = selectors.back().advance(*this))) { + selectors.pop_back(); + } + if (!next) { + // No selector could be advanced, so we've seen every possible ordering. + assert(selectors.empty()); + return; + } + // We've advanced the last selector on the stack, so initialize the + // subsequent selectors. + assert(selectors.size() < graph.size()); + selectors.push_back(*next); + while (selectors.size() < graph.size()) { + selectors.push_back(selectors.back().select(*this)); + } +} + +} // namespace wasm diff --git a/src/support/topological_orders.h b/src/support/topological_orders.h new file mode 100644 index 00000000000..acab78ee5f5 --- /dev/null +++ b/src/support/topological_orders.h @@ -0,0 +1,104 @@ +/* + * Copyright 2024 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. + */ + +#ifndef wasm_support_topological_orders_h +#define wasm_support_topological_orders_h + +#include +#include +#include + +namespace wasm { + +// A utility for iterating through all possible topological orders in a graph +// using an extension of Kahn's algorithm (see +// https://en.wikipedia.org/wiki/Topological_sorting) that iteratively makes all +// possible choices for each position of the output order. +struct TopologicalOrders { + // Takes an adjacency list, where the list for each vertex is a sorted list of + // the indices of its children, which will appear after it in the order. + TopologicalOrders(const std::vector>& graph); + + struct Iterator { + using value_type = const std::vector; + using difference_type = std::ptrdiff_t; + using reference = const std::vector&; + using pointer = const std::vector*; + using iterator_category = std::input_iterator_tag; + + TopologicalOrders* parent; + + bool isEnd() const { return !parent || parent->selectors.empty(); } + bool operator==(const Iterator& other) const { + return isEnd() == other.isEnd(); + } + bool operator!=(const Iterator& other) const { return !(*this == other); } + const std::vector& operator*() { return parent->buf; } + const std::vector* operator->() { return &parent->buf; } + Iterator& operator++() { + parent->advance(); + return *this; + } + Iterator operator++(int) { return ++(*this); } + }; + + Iterator begin() { return {this}; } + Iterator end() { return {nullptr}; } + +private: + // The input graph given as an adjacency list with edges from vertices to + // their dependent children. + const std::vector>& graph; + // The current in-degrees for each vertex. When a vertex is appended to our + // permutation, the in-degrees of its children are decremented and those that + // go to zero become available for the next selection. + std::vector indegrees; + // The buffer in which we are constructing a permutation. It contains a + // sequence of selected vertices followed by a sequence of possible choices + // for the next vertex. + std::vector buf; + + // The state for tracking the possible choices for a single vertex in the + // output order. + struct Selector { + // The start index of the sequence of available choices. Also the index + // where we place the current choice. + size_t start; + // The number of choices we have. + size_t count; + // The index of the current choice in the original order. + size_t index; + + // Select the next available vertex, decrement in-degrees, and update the + // sequence of available vertices. Return the Selector for the next vertex. + Selector select(TopologicalOrders& ctx); + + // Undo the current selection, move the next selection into the first + // position and return the new selector for the next position. Returns + // nullopt if advancing wraps back around to the original configuration. + std::optional advance(TopologicalOrders& ctx); + }; + + // A stack of selectors, one for each vertex in a complete topological order. + // Empty if we've already seen every possible ordering. + std::vector selectors; + + void advance(); +}; + +} // namespace wasm + +#endif // wasm_support_topological_orders_h diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index 538ec1cdc67..e8eec3f1d8b 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -12,6 +12,7 @@ set(unittest_SOURCES scc.cpp stringify.cpp suffix_tree.cpp + topological-orders.cpp type-builder.cpp wat-lexer.cpp validator.cpp diff --git a/test/gtest/topological-orders.cpp b/test/gtest/topological-orders.cpp new file mode 100644 index 00000000000..7eeb8fdc237 --- /dev/null +++ b/test/gtest/topological-orders.cpp @@ -0,0 +1,101 @@ +/* + * Copyright 2024 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 +#include +#include + +#include "support/topological_orders.h" +#include "gtest/gtest.h" + +using namespace wasm; + +using Graph = std::vector>; + +TEST(TopologicalOrdersTest, Empty) { + Graph graph; + TopologicalOrders orders(graph); + EXPECT_EQ(orders.begin(), orders.end()); +} + +TEST(TopologicalOrdersTest, Singleton) { + Graph graph(1); + TopologicalOrders orders(graph); + auto it = orders.begin(); + ASSERT_NE(it, orders.end()); + EXPECT_EQ(*it, std::vector{0}); + ++it; + EXPECT_EQ(it, orders.end()); +} + +TEST(TopologicalOrdersTest, Permutations) { + Graph graph(3); + TopologicalOrders orders(graph); + std::set> results(orders.begin(), orders.end()); + std::set> expected{ + {0, 1, 2}, + {0, 2, 1}, + {1, 0, 2}, + {1, 2, 0}, + {2, 0, 1}, + {2, 1, 0}, + }; + EXPECT_EQ(results, expected); +} + +TEST(TopologicalOrdersTest, Chain) { + constexpr size_t n = 10; + Graph graph(n); + for (size_t i = 1; i < n; ++i) { + graph[i].push_back(i - 1); + } + TopologicalOrders orders(graph); + std::set> results(orders.begin(), orders.end()); + std::set> expected{{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}; + EXPECT_EQ(results, expected); +} + +TEST(TopologicalOrdersTest, TwoChains) { + Graph graph(4); + graph[0].push_back(2); + graph[1].push_back(3); + TopologicalOrders orders(graph); + std::set> results(orders.begin(), orders.end()); + std::set> expected{ + {0, 1, 2, 3}, + {0, 1, 3, 2}, + {0, 2, 1, 3}, + {1, 0, 2, 3}, + {1, 0, 3, 2}, + {1, 3, 0, 2}, + }; + EXPECT_EQ(results, expected); +} + +TEST(TopologicalOrdersTest, Diamond) { + Graph graph(4); + graph[0].push_back(1); + graph[0].push_back(2); + graph[1].push_back(3); + graph[2].push_back(3); + TopologicalOrders orders(graph); + std::set> results(orders.begin(), orders.end()); + std::set> expected{ + {0, 1, 2, 3}, + {0, 2, 1, 3}, + }; + EXPECT_EQ(results, expected); +} From d9c44afdca7b2e2da29e4202f0d0a06fb0add115 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 5 Aug 2024 15:30:16 -0400 Subject: [PATCH 493/553] [NFC] Remove unused `isException` type methods (#6802) --- src/wasm-type.h | 2 -- src/wasm/wasm-type.cpp | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/wasm-type.h b/src/wasm-type.h index b3640ff4124..49179b1a689 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -170,7 +170,6 @@ class Type { bool isSignature() const; bool isStruct() const; bool isArray() const; - bool isException() const; bool isString() const; bool isDefaultable() const; @@ -377,7 +376,6 @@ class HeapType { bool isContinuation() const; bool isStruct() const; bool isArray() const; - bool isException() const; bool isString() const; bool isBottom() const; bool isOpen() const; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index bfab4b95538..339eeb0b914 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -814,10 +814,6 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); } bool Type::isArray() const { return isRef() && getHeapType().isArray(); } -bool Type::isException() const { - return isRef() && getHeapType().isException(); -} - bool Type::isString() const { return isRef() && getHeapType().isString(); } bool Type::isDefaultable() const { @@ -1148,8 +1144,6 @@ bool HeapType::isArray() const { } } -bool HeapType::isException() const { return *this == HeapType::exn; } - bool HeapType::isString() const { return *this == HeapType::string; } bool HeapType::isBottom() const { From e2e5b9cf70c8a81492db259e1a17294064a69157 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Mon, 5 Aug 2024 15:20:29 -0700 Subject: [PATCH 494/553] WasmBinaryReader: Use helper function to create names for items. NFC (#6810) As a followup we could probably make these more consistent. For example, we could use a single char prefix for defined functions/tables/globals (e.g. f0/t0/g0) --- src/wasm/wasm-binary.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 3cb3b08dafa..779f1fd6f30 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2239,13 +2239,17 @@ void WasmBinaryReader::readStart() { startIndex = getU32LEB(); } +static Name makeName(std::string prefix, size_t counter) { + return Name(prefix + std::to_string(counter)); +} + void WasmBinaryReader::readMemories() { BYN_TRACE("== readMemories\n"); auto num = getU32LEB(); BYN_TRACE("num: " << num << std::endl); for (size_t i = 0; i < num; i++) { BYN_TRACE("read one\n"); - auto memory = Builder::makeMemory(Name::fromInt(i)); + auto memory = Builder::makeMemory(makeName("", i)); getResizableLimits(memory->initial, memory->max, memory->shared, @@ -2534,7 +2538,7 @@ void WasmBinaryReader::readImports() { // could occur later due to the names section. switch (kind) { case ExternalKind::Function: { - Name name(std::string("fimport$") + std::to_string(functionCounter++)); + Name name = makeName("fimport$", functionCounter++); auto index = getU32LEB(); functionTypes.push_back(getTypeByIndex(index)); auto type = getTypeByIndex(index); @@ -2550,8 +2554,7 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Table: { - Name name(std::string("timport$") + std::to_string(tableCounter++)); - auto table = builder.makeTable(name); + auto table = builder.makeTable(makeName("timport$", tableCounter++)); table->module = module; table->base = base; table->type = getType(); @@ -2570,8 +2573,7 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Memory: { - Name name(std::string("mimport$") + std::to_string(memoryCounter++)); - auto memory = builder.makeMemory(name); + auto memory = builder.makeMemory(makeName("mimport$", memoryCounter++)); memory->module = module; memory->base = base; getResizableLimits(memory->initial, @@ -2583,14 +2585,13 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Global: { - Name name(std::string("gimport$") + std::to_string(globalCounter++)); auto type = getConcreteType(); auto mutable_ = getU32LEB(); if (mutable_ & ~1) { throwError("Global mutability must be 0 or 1"); } auto curr = - builder.makeGlobal(name, + builder.makeGlobal(makeName("gimport$", globalCounter++), type, nullptr, mutable_ ? Builder::Mutable : Builder::Immutable); @@ -2600,7 +2601,7 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Tag: { - Name name(std::string("eimport$") + std::to_string(tagCounter++)); + Name name = makeName("eimport$", tagCounter++); getInt8(); // Reserved 'attribute' field auto index = getU32LEB(); auto curr = builder.makeTag(name, getSignatureByTypeIndex(index)); @@ -2618,7 +2619,7 @@ void WasmBinaryReader::readImports() { Name WasmBinaryReader::getNextLabel() { requireFunctionContext("getting a label"); - return Name("label$" + std::to_string(nextLabel++)); + return makeName("label$", nextLabel++); } void WasmBinaryReader::requireFunctionContext(const char* error) { @@ -2688,7 +2689,7 @@ void WasmBinaryReader::readFunctions() { endOfFunction = pos + size; auto func = std::make_unique(); - func->name = Name::fromInt(i); + func->name = makeName("", i); func->type = getTypeByFunctionIndex(numImports + i); currFunction = func.get(); @@ -3046,7 +3047,7 @@ void WasmBinaryReader::readGlobals() { } auto* init = readExpression(); wasm.addGlobal( - Builder::makeGlobal("global$" + std::to_string(i), + Builder::makeGlobal(makeName("global$", i), type, init, mutable_ ? Builder::Mutable : Builder::Immutable)); @@ -3366,7 +3367,7 @@ void WasmBinaryReader::readTableDeclarations() { if (!elemType.isRef()) { throwError("Table type must be a reference type"); } - auto table = Builder::makeTable(Name::fromInt(i), elemType); + auto table = Builder::makeTable(makeName("", i), elemType); bool is_shared; getResizableLimits(table->initial, table->max, @@ -3466,7 +3467,7 @@ void WasmBinaryReader::readTags() { BYN_TRACE("read one\n"); getInt8(); // Reserved 'attribute' field auto typeIndex = getU32LEB(); - wasm.addTag(Builder::makeTag("tag$" + std::to_string(i), + wasm.addTag(Builder::makeTag(makeName("tag$", i), getSignatureByTypeIndex(typeIndex))); } } From 6fe3d885604bb053979f4e5adad2840ea936fd17 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 6 Aug 2024 10:17:40 -0700 Subject: [PATCH 495/553] Make source parser consistent with binary parser when naming things. NFC (#6813) The `timport$` prefix is already used for tables, so the binary parser currently uses `eimport$` to name tags (I guess because they are normally exception tags?). --- src/parser/context-decls.cpp | 5 +++-- test/lit/basic/tags.wast | 4 ++-- test/lit/validation/extended-const.wast | 2 +- test/lit/wat-kitchen-sink.wast | 14 +++++++------- test/lld/em_asm_main_thread.wat | 4 ++-- test/lld/em_asm_main_thread.wat.out | 8 ++++---- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/parser/context-decls.cpp b/src/parser/context-decls.cpp index c5b21203859..8e9638ae7b3 100644 --- a/src/parser/context-decls.cpp +++ b/src/parser/context-decls.cpp @@ -196,7 +196,8 @@ ParseDeclsCtx::addGlobalDecl(Index pos, Name name, ImportNames* importNames) { } g->setExplicitName(name); } else { - name = (importNames ? "gimport$" : "") + std::to_string(globalCounter++); + name = + (importNames ? "gimport$" : "global$") + std::to_string(globalCounter++); name = Names::getValidGlobalName(wasm, name); g->name = name; } @@ -276,7 +277,7 @@ ParseDeclsCtx::addTagDecl(Index pos, Name name, ImportNames* importNames) { } t->setExplicitName(name); } else { - name = (importNames ? "timport$" : "") + std::to_string(tagCounter++); + name = (importNames ? "eimport$" : "tag$") + std::to_string(tagCounter++); name = Names::getValidTagName(wasm, name); t->name = name; } diff --git a/test/lit/basic/tags.wast b/test/lit/basic/tags.wast index cd0615eab01..7d99816c1d8 100644 --- a/test/lit/basic/tags.wast +++ b/test/lit/basic/tags.wast @@ -25,9 +25,9 @@ ;; CHECK-TEXT: (import "env" "im0" (tag $e-import (param i32))) - ;; CHECK-TEXT: (import "env" "im1" (tag $timport$0 (param i32 f32))) + ;; CHECK-TEXT: (import "env" "im1" (tag $eimport$0 (param i32 f32))) - ;; CHECK-TEXT: (tag $1 (param i32)) + ;; CHECK-TEXT: (tag $tag$1 (param i32)) ;; CHECK-TEXT: (tag $e (param i32 f32)) ;; CHECK-BIN: (type $0 (func (param i32 f32))) diff --git a/test/lit/validation/extended-const.wast b/test/lit/validation/extended-const.wast index 36ffee43017..cd87d4ccb72 100644 --- a/test/lit/validation/extended-const.wast +++ b/test/lit/validation/extended-const.wast @@ -8,7 +8,7 @@ ;; NO-EXTENDED: unexpected false: table segment offset must be constant ;; EXTENDED: (import "env" "global" (global $gimport$0 i32)) -;; EXTENDED: (global $1 i32 (i32.add +;; EXTENDED: (global $global$1 i32 (i32.add ;; EXTENDED: (global.get $gimport$0) ;; EXTENDED: (i32.const 42) ;; EXTENDED: )) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 10f581d21ad..ac8a00cc288 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -302,11 +302,11 @@ ;; CHECK: (import "mod" "t0" (tag $imported (param i32 i64))) - ;; CHECK: (import "mod" "t1" (tag $timport$0)) + ;; CHECK: (import "mod" "t1" (tag $eimport$0)) - ;; CHECK: (import "mod" "imported-tag" (tag $timport$1)) + ;; CHECK: (import "mod" "imported-tag" (tag $eimport$1)) - ;; CHECK: (global $2 (mut i32) (i32.const 0)) + ;; CHECK: (global $global$2 (mut i32) (i32.const 0)) ;; CHECK: (global $i32 i32 (i32.const 42)) (global $i32 i32 i32.const 42) @@ -413,7 +413,7 @@ ;; tags (tag) - ;; CHECK: (tag $2) + ;; CHECK: (tag $tag$2) ;; CHECK: (tag $empty) (tag $empty) @@ -1919,7 +1919,7 @@ ;; CHECK-NEXT: (catch $empty ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (catch $timport$0 + ;; CHECK-NEXT: (catch $eimport$0 ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (catch_all @@ -2228,7 +2228,7 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (catch $timport$0 + ;; CHECK-NEXT: (catch $eimport$0 ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -3710,7 +3710,7 @@ ) ;; CHECK: (func $throw (type $0) - ;; CHECK-NEXT: (throw $timport$1) + ;; CHECK-NEXT: (throw $eimport$1) ;; CHECK-NEXT: (throw $tag-i32 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) diff --git a/test/lld/em_asm_main_thread.wat b/test/lld/em_asm_main_thread.wat index 65f530d699c..90f6e811161 100644 --- a/test/lld/em_asm_main_thread.wat +++ b/test/lld/em_asm_main_thread.wat @@ -12,12 +12,12 @@ (import "env" "emscripten_asm_const_int_sync_on_main_thread" (func $emscripten_asm_const_int_sync_on_main_thread (param i32 i32 i32) (result i32))) (memory $0 2) (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00") - (global (export "__start_em_asm") i32 (i32.const 568)) - (global (export "__stop_em_asm") i32 (i32.const 652)) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66192)) (global $global$1 i32 (i32.const 66192)) (global $global$2 i32 (i32.const 652)) + (global $global$3 (export "__start_em_asm") i32 (i32.const 568)) + (global $global$4 (export "__stop_em_asm") i32 (i32.const 652)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__heap_base" (global $global$1)) diff --git a/test/lld/em_asm_main_thread.wat.out b/test/lld/em_asm_main_thread.wat.out index 5eaa3a826b2..5d817ca8677 100644 --- a/test/lld/em_asm_main_thread.wat.out +++ b/test/lld/em_asm_main_thread.wat.out @@ -7,16 +7,16 @@ (type $5 (func (param i32) (result i32))) (type $6 (func (param i32 i32) (result i32))) (import "env" "emscripten_asm_const_int_sync_on_main_thread" (func $emscripten_asm_const_int_sync_on_main_thread (param i32 i32 i32) (result i32))) - (global $0 i32 (i32.const 568)) - (global $1 i32 (i32.const 652)) (global $global$0 (mut i32) (i32.const 66192)) (global $global$1 i32 (i32.const 66192)) (global $global$2 i32 (i32.const 652)) + (global $global$3 i32 (i32.const 568)) + (global $global$4 i32 (i32.const 652)) (memory $0 2) (data $0 (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00") (table $0 1 1 funcref) - (export "__start_em_asm" (global $0)) - (export "__stop_em_asm" (global $1)) + (export "__start_em_asm" (global $global$3)) + (export "__stop_em_asm" (global $global$4)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__heap_base" (global $global$1)) From bae0da03af8f4f240d659d016b6e4ee998551059 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 6 Aug 2024 13:22:38 -0400 Subject: [PATCH 496/553] [NFC] Add HeapType::getKind returning a new HeapTypeKind enum (#6804) The HeapType API has functions like `isBasic()`, `isStruct()`, `isSignature()`, etc. to test the classification of a heap type. Many users have to call these functions in sequence and handle all or most of the possible classifications. When we add a new kind of heap type, finding and updating all these sites is a manual and error-prone process. To make adding new heap type kinds easier, introduce a new API that returns an enum classifying the heap type. The enum can be used in switch statements and the compiler's exhaustiveness checker will flag use sites that need to be updated when we add a new kind of heap type. This commit uses the new enum internally in the type system, but follow-on commits will add new uses and convert uses of the existing APIs to use `getKind` instead. --- src/literal.h | 8 +- src/passes/Precompute.cpp | 2 +- src/tools/execution-results.h | 7 +- src/tools/fuzzing/fuzzing.cpp | 3 +- src/tools/wasm-ctor-eval.cpp | 3 +- src/wasm-builder.h | 40 ++++---- src/wasm-type.h | 36 ++++--- src/wasm/literal.cpp | 2 +- src/wasm/wasm-type.cpp | 177 ++++++++++++++-------------------- 9 files changed, 134 insertions(+), 144 deletions(-) diff --git a/src/literal.h b/src/literal.h index f7703d9e604..1c1128163ac 100644 --- a/src/literal.h +++ b/src/literal.h @@ -96,7 +96,9 @@ class Literal { // Whether this is GC data, that is, something stored on the heap (aside from // a null or i31). This includes structs, arrays, and also strings. bool isData() const { return type.isData(); } - bool isString() const { return type.isString(); } + bool isString() const { + return type.isRef() && type.getHeapType().isMaybeShared(HeapType::string); + } bool isNull() const { return type.isNull(); } @@ -770,11 +772,11 @@ template<> struct hash { wasm::rehash(digest, a.getFunc()); return digest; } - if (a.type.getHeapType() == wasm::HeapType::i31) { + if (a.type.getHeapType().isMaybeShared(wasm::HeapType::i31)) { wasm::rehash(digest, a.geti31(true)); return digest; } - if (a.type.isString()) { + if (a.type.getHeapType().isMaybeShared(wasm::HeapType::string)) { auto& values = a.getGCData()->values; wasm::rehash(digest, values.size()); for (auto c : values) { diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index ba04a68aa26..48977dd78f6 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -829,7 +829,7 @@ struct Precompute return true; } // We can emit a StringConst for a string constant. - if (type.isString()) { + if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::string)) { return true; } // All other reference types cannot be precomputed. Even an immutable GC diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index d9fa5cd9b89..31c572e655e 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -148,7 +148,8 @@ struct ExecutionResults { // simple and stable internal structures that optimizations will not alter. auto type = value.type; if (type.isRef()) { - if (type.isString() || type.getHeapType() == HeapType::i31) { + if (type.getHeapType().isMaybeShared(HeapType::string) || + type.getHeapType().isMaybeShared(HeapType::i31)) { std::cout << value << '\n'; } else if (value.isNull()) { std::cout << "null\n"; @@ -189,7 +190,9 @@ struct ExecutionResults { // TODO: Once we support optimizing under some form of open-world // assumption, we should be able to check that the types and/or structure of // GC data passed out of the module does not change. - if (a.type.isRef() && !a.type.isString()) { + if (a.type.isRef() && + !a.type.getHeapType().isMaybeShared(HeapType::string) && + !a.type.getHeapType().isMaybeShared(HeapType::i31)) { return true; } if (a != b) { diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 2aff7146e28..13883186067 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2536,7 +2536,8 @@ Expression* TranslateToFuzzReader::makeConst(Type type) { if (type.isNullable() && oneIn(8)) { return builder.makeRefNull(type.getHeapType()); } - if (type.getHeapType().isString()) { + if (type.getHeapType().isMaybeShared(HeapType::string)) { + assert(!type.getHeapType().isShared() && "TODO: shared strings"); return makeStringConst(); } if (type.getHeapType().isBasic()) { diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index df4e7a9bf77..11fee72fb4b 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -841,7 +841,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // externalized i31s) can be handled by the general makeConstantExpression // logic (which knows how to handle externalization, for i31s; and it also // can handle string constants). - if (!value.isData() || value.type.getHeapType().isString()) { + if (!value.isData() || + value.type.getHeapType().isMaybeShared(HeapType::string)) { return builder.makeConstantExpression(original); } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 0ea41989d40..0f9ec7b03c9 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1217,26 +1217,28 @@ class Builder { if (type.isFunction()) { return makeRefFunc(value.getFunc(), type.getHeapType()); } - if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)) { - return makeRefI31(makeConst(value.geti31()), - type.getHeapType().getShared()); - } - if (type.isString()) { - // The string is already WTF-16, but we need to convert from `Literals` to - // actual string. - std::stringstream wtf16; - for (auto c : value.getGCData()->values) { - auto u = c.getInteger(); - assert(u < 0x10000); - wtf16 << uint8_t(u & 0xFF); - wtf16 << uint8_t(u >> 8); + if (type.isRef()) { + if (type.getHeapType().isMaybeShared(HeapType::i31)) { + return makeRefI31(makeConst(value.geti31()), + type.getHeapType().getShared()); + } + if (type.getHeapType().isMaybeShared(HeapType::string)) { + // The string is already WTF-16, but we need to convert from `Literals` + // to actual string. + std::stringstream wtf16; + for (auto c : value.getGCData()->values) { + auto u = c.getInteger(); + assert(u < 0x10000); + wtf16 << uint8_t(u & 0xFF); + wtf16 << uint8_t(u >> 8); + } + // TODO: Use wtf16.view() once we have C++20. + return makeStringConst(wtf16.str()); + } + if (type.getHeapType().isMaybeShared(HeapType::ext)) { + return makeRefAs(ExternConvertAny, + makeConstantExpression(value.internalize())); } - // TODO: Use wtf16.view() once we have C++20. - return makeStringConst(wtf16.str()); - } - if (type.isRef() && type.getHeapType() == HeapType::ext) { - return makeRefAs(ExternConvertAny, - makeConstantExpression(value.internalize())); } TODO_SINGLE_COMPOUND(type); WASM_UNREACHABLE("unsupported constant expression"); diff --git a/src/wasm-type.h b/src/wasm-type.h index 49179b1a689..58655edc78a 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -170,7 +170,6 @@ class Type { bool isSignature() const; bool isStruct() const; bool isArray() const; - bool isString() const; bool isDefaultable() const; Nullability getNullability() const; @@ -311,6 +310,14 @@ class Type { enum Shareability { Shared, Unshared }; +enum class HeapTypeKind { + Basic, + Func, + Struct, + Array, + Cont, +}; + class HeapType { // Unlike `Type`, which represents the types of values on the WebAssembly // stack, `HeapType` is used to describe the structures that reference types @@ -365,18 +372,21 @@ class HeapType { HeapType(Struct&& struct_); HeapType(Array array); + HeapTypeKind getKind() const; + constexpr bool isBasic() const { return id <= _last_basic_type; } - bool isFunction() const; - bool isData() const; - bool isSignature() const; - // Indicates whether the given type was defined to be of the form - // `(cont $ft)`. Returns false for `cont`, the top type of the continuation - // type hierarchy (and all other types). In other words, this is analogous to - // `isSignature`, but for continuation types. - bool isContinuation() const; - bool isStruct() const; - bool isArray() const; - bool isString() const; + bool isFunction() const { + return isMaybeShared(func) || getKind() == HeapTypeKind::Func; + } + bool isData() const { + auto kind = getKind(); + return isMaybeShared(string) || kind == HeapTypeKind::Struct || + kind == HeapTypeKind::Array; + } + bool isSignature() const { return getKind() == HeapTypeKind::Func; } + bool isContinuation() const { return getKind() == HeapTypeKind::Cont; } + bool isStruct() const { return getKind() == HeapTypeKind::Struct; } + bool isArray() const { return getKind() == HeapTypeKind::Array; } bool isBottom() const; bool isOpen() const; bool isShared() const { return getShared() == Shared; } @@ -385,7 +395,7 @@ class HeapType { // Check if the type is a given basic heap type, while ignoring whether it is // shared or not. - bool isMaybeShared(BasicHeapType type) { + bool isMaybeShared(BasicHeapType type) const { return isBasic() && getBasic(Unshared) == type; } diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index f2100ea712e..3dcf9e35092 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -439,7 +439,7 @@ bool Literal::operator==(const Literal& other) const { assert(func.is() && other.func.is()); return func == other.func; } - if (type.isString()) { + if (type.getHeapType().isMaybeShared(HeapType::string)) { return gcData->values == other.gcData->values; } if (type.isData()) { diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 339eeb0b914..aa3847a8b9d 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -93,12 +93,7 @@ struct HeapTypeInfo { // (i.e. contains only this type). RecGroupInfo* recGroup = nullptr; size_t recGroupIndex = 0; - enum Kind { - SignatureKind, - ContinuationKind, - StructKind, - ArrayKind, - } kind; + HeapTypeKind kind; union { Signature signature; Continuation continuation; @@ -106,19 +101,20 @@ struct HeapTypeInfo { Array array; }; - HeapTypeInfo(Signature sig) : kind(SignatureKind), signature(sig) {} + HeapTypeInfo(Signature sig) : kind(HeapTypeKind::Func), signature(sig) {} HeapTypeInfo(Continuation continuation) - : kind(ContinuationKind), continuation(continuation) {} - HeapTypeInfo(const Struct& struct_) : kind(StructKind), struct_(struct_) {} + : kind(HeapTypeKind::Cont), continuation(continuation) {} + HeapTypeInfo(const Struct& struct_) + : kind(HeapTypeKind::Struct), struct_(struct_) {} HeapTypeInfo(Struct&& struct_) - : kind(StructKind), struct_(std::move(struct_)) {} - HeapTypeInfo(Array array) : kind(ArrayKind), array(array) {} + : kind(HeapTypeKind::Struct), struct_(std::move(struct_)) {} + HeapTypeInfo(Array array) : kind(HeapTypeKind::Array), array(array) {} ~HeapTypeInfo(); - constexpr bool isSignature() const { return kind == SignatureKind; } - constexpr bool isContinuation() const { return kind == ContinuationKind; } - constexpr bool isStruct() const { return kind == StructKind; } - constexpr bool isArray() const { return kind == ArrayKind; } + constexpr bool isSignature() const { return kind == HeapTypeKind::Func; } + constexpr bool isContinuation() const { return kind == HeapTypeKind::Cont; } + constexpr bool isStruct() const { return kind == HeapTypeKind::Struct; } + constexpr bool isArray() const { return kind == HeapTypeKind::Array; } constexpr bool isData() const { return isStruct() || isArray(); } }; @@ -440,14 +436,16 @@ HeapType::BasicHeapType getBasicHeapSupertype(HeapType type) { } auto* info = getHeapTypeInfo(type); switch (info->kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: return HeapTypes::func.getBasic(info->share); - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: return HeapTypes::cont.getBasic(info->share); - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: return HeapTypes::struct_.getBasic(info->share); - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: return HeapTypes::array.getBasic(info->share); + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); }; @@ -572,18 +570,20 @@ bool TypeInfo::operator==(const TypeInfo& other) const { HeapTypeInfo::~HeapTypeInfo() { switch (kind) { - case SignatureKind: + case HeapTypeKind::Func: signature.~Signature(); return; - case ContinuationKind: + case HeapTypeKind::Cont: continuation.~Continuation(); return; - case StructKind: + case HeapTypeKind::Struct: struct_.~Struct(); return; - case ArrayKind: + case HeapTypeKind::Array: array.~Array(); return; + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); } @@ -814,8 +814,6 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); } bool Type::isArray() const { return isRef() && getHeapType().isArray(); } -bool Type::isString() const { return isRef() && getHeapType().isString(); } - bool Type::isDefaultable() const { // A variable can get a default value if its type is concrete (unreachable // and none have no values, hence no default), and if it's a reference, it @@ -1096,56 +1094,13 @@ HeapType::HeapType(Array array) { HeapType(globalRecGroupStore.insert(std::make_unique(array))); } -bool HeapType::isFunction() const { - if (isBasic()) { - return id == func; - } else { - return getHeapTypeInfo(*this)->isSignature(); - } -} - -bool HeapType::isData() const { - if (isBasic()) { - return id == struct_ || id == array || id == string; - } else { - return getHeapTypeInfo(*this)->isData(); - } -} - -bool HeapType::isSignature() const { - if (isBasic()) { - return false; - } else { - return getHeapTypeInfo(*this)->isSignature(); - } -} - -bool HeapType::isContinuation() const { +HeapTypeKind HeapType::getKind() const { if (isBasic()) { - return false; - } else { - return getHeapTypeInfo(*this)->isContinuation(); + return HeapTypeKind::Basic; } + return getHeapTypeInfo(*this)->kind; } -bool HeapType::isStruct() const { - if (isBasic()) { - return false; - } else { - return getHeapTypeInfo(*this)->isStruct(); - } -} - -bool HeapType::isArray() const { - if (isBasic()) { - return false; - } else { - return getHeapTypeInfo(*this)->isArray(); - } -} - -bool HeapType::isString() const { return *this == HeapType::string; } - bool HeapType::isBottom() const { if (isBasic()) { switch (getBasic(Unshared)) { @@ -1252,14 +1207,16 @@ std::optional HeapType::getSuperType() const { auto* info = getHeapTypeInfo(*this); switch (info->kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: return HeapType(func).getBasic(share); - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: return HeapType(cont).getBasic(share); - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: return HeapType(struct_).getBasic(share); - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: return HeapType(array).getBasic(share); + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); } @@ -1345,13 +1302,15 @@ HeapType::BasicHeapType HeapType::getUnsharedBottom() const { } auto* info = getHeapTypeInfo(*this); switch (info->kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: return nofunc; - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: return nocont; - case HeapTypeInfo::StructKind: - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Struct: + case HeapTypeKind::Array: return none; + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); } @@ -2181,18 +2140,20 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const { wasm::rehash(digest, info.share); wasm::rehash(digest, info.kind); switch (info.kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: hash_combine(digest, hash(info.signature)); return digest; - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: hash_combine(digest, hash(info.continuation)); return digest; - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: hash_combine(digest, hash(info.struct_)); return digest; - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: hash_combine(digest, hash(info.array)); return digest; + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); } @@ -2322,14 +2283,16 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const { return false; } switch (a.kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: return eq(a.signature, b.signature); - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: return eq(a.continuation, b.continuation); - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: return eq(a.struct_, b.struct_); - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: return eq(a.array, b.array); + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unexpected kind"); } @@ -2436,23 +2399,25 @@ void TypeGraphWalkerBase::scanHeapType(HeapType* ht) { } auto* info = getHeapTypeInfo(*ht); switch (info->kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: taskList.push_back(Task::scan(&info->signature.results)); taskList.push_back(Task::scan(&info->signature.params)); break; - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: taskList.push_back(Task::scan(&info->continuation.type)); break; - case HeapTypeInfo::StructKind: { + case HeapTypeKind::Struct: { auto& fields = info->struct_.fields; for (auto field = fields.rbegin(); field != fields.rend(); ++field) { taskList.push_back(Task::scan(&field->type)); } break; } - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: taskList.push_back(Task::scan(&info->array.element.type)); break; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } @@ -2480,18 +2445,20 @@ struct TypeBuilder::Impl { void set(HeapTypeInfo&& hti) { info->kind = hti.kind; switch (info->kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: info->signature = hti.signature; break; - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: info->continuation = hti.continuation; break; - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: info->struct_ = std::move(hti.struct_); break; - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: info->array = hti.array; break; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } initialized = true; } @@ -2612,14 +2579,16 @@ bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) { } SubTyper typer; switch (sub.kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: return typer.isSubType(sub.signature, super.signature); - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: return typer.isSubType(sub.continuation, super.continuation); - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: return typer.isSubType(sub.struct_, super.struct_); - case HeapTypeInfo::ArrayKind: + case HeapTypeKind::Array: return typer.isSubType(sub.array, super.array); + case HeapTypeKind::Basic: + break; } WASM_UNREACHABLE("unknown kind"); } @@ -2644,28 +2613,30 @@ validateType(HeapTypeInfo& info, std::unordered_set& seenTypes) { } if (info.share == Shared) { switch (info.kind) { - case HeapTypeInfo::SignatureKind: + case HeapTypeKind::Func: // TODO: Figure out and enforce shared function rules. break; - case HeapTypeInfo::ContinuationKind: + case HeapTypeKind::Cont: if (!info.continuation.type.isShared()) { return TypeBuilder::ErrorReason::InvalidFuncType; } break; - case HeapTypeInfo::StructKind: + case HeapTypeKind::Struct: for (auto& field : info.struct_.fields) { if (field.type.isRef() && !field.type.getHeapType().isShared()) { return TypeBuilder::ErrorReason::InvalidUnsharedField; } } break; - case HeapTypeInfo::ArrayKind: { + case HeapTypeKind::Array: { auto elem = info.array.element.type; if (elem.isRef() && !elem.getHeapType().isShared()) { return TypeBuilder::ErrorReason::InvalidUnsharedField; } break; } + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } return std::nullopt; From 1c3578c7e28d9fced48a756546c07a2acb26bdcc Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 6 Aug 2024 13:23:27 -0400 Subject: [PATCH 497/553] Fix sharedness bug in inhabitable type fuzzer (#6807) The code for collecting inhabitable types incorrectly considered shared, non-nullable externrefs to be inhabitable, which disagreed with the code for rewriting types to be inhabitable, which was correct, causing the type fuzzer to report an error. --- src/tools/fuzzing/heap-types.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 7eaf23701f0..e4d54ae07b8 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -1031,7 +1031,8 @@ bool isUninhabitable(Type type, std::unordered_set& visited, std::unordered_set& visiting) { if (type.isRef() && type.isNonNullable()) { - if (type.getHeapType().isBottom() || type.getHeapType() == HeapType::ext) { + if (type.getHeapType().isBottom() || + type.getHeapType().isMaybeShared(HeapType::ext)) { return true; } return isUninhabitable(type.getHeapType(), visited, visiting); From a985e16832f86cbc42eb6488e6f9fc2a9eff7dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Tue, 6 Aug 2024 20:17:23 +0200 Subject: [PATCH 498/553] [Source maps] Handle single-segment entries in source map header decoder (#6794) Single-segment mappings were already handled in readNextDebugLocation, but not in readSourceMapHeader. --- src/wasm/wasm-binary.cpp | 19 +++++++---- test/gtest/CMakeLists.txt | 1 + test/gtest/binary-reader.cpp | 63 ++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 test/gtest/binary-reader.cpp diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 779f1fd6f30..574e13aa2b6 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2941,13 +2941,20 @@ void WasmBinaryReader::readSourceMapHeader() { // investigation (if it does, it will assert in readBase64VLQ, so it // would not be a silent error at least). uint32_t position = readBase64VLQ(*sourceMap); - uint32_t fileIndex = readBase64VLQ(*sourceMap); - uint32_t lineNumber = - readBase64VLQ(*sourceMap) + 1; // adjust zero-based line number - uint32_t columnNumber = readBase64VLQ(*sourceMap); nextDebugPos = position; - nextDebugLocation = {fileIndex, lineNumber, columnNumber}; - nextDebugLocationHasDebugInfo = true; + + auto peek = sourceMap->peek(); + if (peek == ',' || peek == '\"') { + // This is a 1-length entry, so the next location has no debug info. + nextDebugLocationHasDebugInfo = false; + } else { + uint32_t fileIndex = readBase64VLQ(*sourceMap); + uint32_t lineNumber = + readBase64VLQ(*sourceMap) + 1; // adjust zero-based line number + uint32_t columnNumber = readBase64VLQ(*sourceMap); + nextDebugLocation = {fileIndex, lineNumber, columnNumber}; + nextDebugLocationHasDebugInfo = true; + } } void WasmBinaryReader::readNextDebugLocation() { diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt index e8eec3f1d8b..17e880a4efb 100644 --- a/test/gtest/CMakeLists.txt +++ b/test/gtest/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories(../../third_party/googletest/googletest/include) include_directories(../../src/wasm) set(unittest_SOURCES + binary-reader.cpp cfg.cpp dfa_minimization.cpp disjoint_sets.cpp diff --git a/test/gtest/binary-reader.cpp b/test/gtest/binary-reader.cpp new file mode 100644 index 00000000000..b73fe55bda3 --- /dev/null +++ b/test/gtest/binary-reader.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2024 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 "parser/wat-parser.h" +#include "print-test.h" +#include "wasm-binary.h" +#include "gtest/gtest.h" + +using namespace wasm; + +using BinaryReaderTest = PrintTest; + +// Check that debug location parsers can handle single-segment mappings. +TEST_F(BinaryReaderTest, SourceMappingSingleSegment) { + auto moduleText = "(module)"; + Module module; + parseWast(module, moduleText); + + BufferWithRandomAccess buffer; + WasmBinaryWriter(&module, buffer, PassOptions()); + auto moduleBytes = buffer.getAsChars(); + + // A single-segment mapping starting at offset 0. + std::string sourceMap = R"( + { + "version": 3, + "sources": [], + "names": [], + "mappings": "A" + } + )"; + std::stringstream sourceMapStream(sourceMap); + + // Test `readSourceMapHeader` (only check for errors, as there is no mapping + // to print). + { + Module module; + WasmBinaryReader binaryReader(module, FeatureSet::All, moduleBytes); + binaryReader.setDebugLocations(&sourceMapStream); + binaryReader.readSourceMapHeader(); + } + + // Test `readNextDebugLocation`. + { + Module module; + WasmBinaryReader binaryReader(module, FeatureSet::All, moduleBytes); + binaryReader.setDebugLocations(&sourceMapStream); + binaryReader.readNextDebugLocation(); + } +} From d5a5425c0c76cfc08711b81d6ec70c3a2879e405 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 6 Aug 2024 14:25:04 -0400 Subject: [PATCH 499/553] Restore isString type methods (#6815) PR ##6803 proposed removing Type::isString and HeapType::isString in favor of more explicit, verbose callsites. There was no consensus to make this change, but it was accidentally committed as part of #6804. Revert the accidental change, except for the useful, noncontroversial parts, such as fixing the `isString` implementation and a few other locations to correctly handle shared types. --- src/literal.h | 6 ++---- src/passes/Precompute.cpp | 2 +- src/tools/execution-results.h | 6 ++---- src/tools/fuzzing/fuzzing.cpp | 3 +-- src/tools/wasm-ctor-eval.cpp | 3 +-- src/wasm-builder.h | 40 +++++++++++++++++------------------ src/wasm-type.h | 2 ++ src/wasm/literal.cpp | 2 +- src/wasm/wasm-type.cpp | 2 ++ 9 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/literal.h b/src/literal.h index 1c1128163ac..190fe0eeced 100644 --- a/src/literal.h +++ b/src/literal.h @@ -96,9 +96,7 @@ class Literal { // Whether this is GC data, that is, something stored on the heap (aside from // a null or i31). This includes structs, arrays, and also strings. bool isData() const { return type.isData(); } - bool isString() const { - return type.isRef() && type.getHeapType().isMaybeShared(HeapType::string); - } + bool isString() const { return type.isString(); } bool isNull() const { return type.isNull(); } @@ -776,7 +774,7 @@ template<> struct hash { wasm::rehash(digest, a.geti31(true)); return digest; } - if (a.type.getHeapType().isMaybeShared(wasm::HeapType::string)) { + if (a.type.isString()) { auto& values = a.getGCData()->values; wasm::rehash(digest, values.size()); for (auto c : values) { diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 48977dd78f6..ba04a68aa26 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -829,7 +829,7 @@ struct Precompute return true; } // We can emit a StringConst for a string constant. - if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::string)) { + if (type.isString()) { return true; } // All other reference types cannot be precomputed. Even an immutable GC diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 31c572e655e..920bb200ac6 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -148,8 +148,7 @@ struct ExecutionResults { // simple and stable internal structures that optimizations will not alter. auto type = value.type; if (type.isRef()) { - if (type.getHeapType().isMaybeShared(HeapType::string) || - type.getHeapType().isMaybeShared(HeapType::i31)) { + if (type.isString() || type.getHeapType().isMaybeShared(HeapType::i31)) { std::cout << value << '\n'; } else if (value.isNull()) { std::cout << "null\n"; @@ -190,8 +189,7 @@ struct ExecutionResults { // TODO: Once we support optimizing under some form of open-world // assumption, we should be able to check that the types and/or structure of // GC data passed out of the module does not change. - if (a.type.isRef() && - !a.type.getHeapType().isMaybeShared(HeapType::string) && + if (a.type.isRef() && !a.type.isString() && !a.type.getHeapType().isMaybeShared(HeapType::i31)) { return true; } diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 13883186067..2aff7146e28 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2536,8 +2536,7 @@ Expression* TranslateToFuzzReader::makeConst(Type type) { if (type.isNullable() && oneIn(8)) { return builder.makeRefNull(type.getHeapType()); } - if (type.getHeapType().isMaybeShared(HeapType::string)) { - assert(!type.getHeapType().isShared() && "TODO: shared strings"); + if (type.getHeapType().isString()) { return makeStringConst(); } if (type.getHeapType().isBasic()) { diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 11fee72fb4b..22e666a52e3 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -841,8 +841,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // externalized i31s) can be handled by the general makeConstantExpression // logic (which knows how to handle externalization, for i31s; and it also // can handle string constants). - if (!value.isData() || - value.type.getHeapType().isMaybeShared(HeapType::string)) { + if (!value.isData() || value.isString()) { return builder.makeConstantExpression(original); } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 0f9ec7b03c9..a4f1c5cf915 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1217,28 +1217,26 @@ class Builder { if (type.isFunction()) { return makeRefFunc(value.getFunc(), type.getHeapType()); } - if (type.isRef()) { - if (type.getHeapType().isMaybeShared(HeapType::i31)) { - return makeRefI31(makeConst(value.geti31()), - type.getHeapType().getShared()); - } - if (type.getHeapType().isMaybeShared(HeapType::string)) { - // The string is already WTF-16, but we need to convert from `Literals` - // to actual string. - std::stringstream wtf16; - for (auto c : value.getGCData()->values) { - auto u = c.getInteger(); - assert(u < 0x10000); - wtf16 << uint8_t(u & 0xFF); - wtf16 << uint8_t(u >> 8); - } - // TODO: Use wtf16.view() once we have C++20. - return makeStringConst(wtf16.str()); - } - if (type.getHeapType().isMaybeShared(HeapType::ext)) { - return makeRefAs(ExternConvertAny, - makeConstantExpression(value.internalize())); + if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)) { + return makeRefI31(makeConst(value.geti31()), + type.getHeapType().getShared()); + } + if (type.isString()) { + // The string is already WTF-16, but we need to convert from `Literals` to + // actual string. + std::stringstream wtf16; + for (auto c : value.getGCData()->values) { + auto u = c.getInteger(); + assert(u < 0x10000); + wtf16 << uint8_t(u & 0xFF); + wtf16 << uint8_t(u >> 8); } + // TODO: Use wtf16.view() once we have C++20. + return makeStringConst(wtf16.str()); + } + if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::ext)) { + return makeRefAs(ExternConvertAny, + makeConstantExpression(value.internalize())); } TODO_SINGLE_COMPOUND(type); WASM_UNREACHABLE("unsupported constant expression"); diff --git a/src/wasm-type.h b/src/wasm-type.h index 58655edc78a..88590cc17b8 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -170,6 +170,7 @@ class Type { bool isSignature() const; bool isStruct() const; bool isArray() const; + bool isString() const; bool isDefaultable() const; Nullability getNullability() const; @@ -387,6 +388,7 @@ class HeapType { bool isContinuation() const { return getKind() == HeapTypeKind::Cont; } bool isStruct() const { return getKind() == HeapTypeKind::Struct; } bool isArray() const { return getKind() == HeapTypeKind::Array; } + bool isString() const { return isMaybeShared(HeapType::string); } bool isBottom() const; bool isOpen() const; bool isShared() const { return getShared() == Shared; } diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 3dcf9e35092..f2100ea712e 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -439,7 +439,7 @@ bool Literal::operator==(const Literal& other) const { assert(func.is() && other.func.is()); return func == other.func; } - if (type.getHeapType().isMaybeShared(HeapType::string)) { + if (type.isString()) { return gcData->values == other.gcData->values; } if (type.isData()) { diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index aa3847a8b9d..173e4b8c3fe 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -814,6 +814,8 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); } bool Type::isArray() const { return isRef() && getHeapType().isArray(); } +bool Type::isString() const { return isRef() && getHeapType().isString(); } + bool Type::isDefaultable() const { // A variable can get a default value if its type is concrete (unreachable // and none have no values, hence no default), and if it's a reference, it From 0c269482097ae9da62a690b0ace406e2d2109c48 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 6 Aug 2024 14:15:58 -0700 Subject: [PATCH 500/553] [FP16] Implement load and store instructions. (#6796) Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md --- CMakeLists.txt | 1 + LICENSE | 5 + scripts/gen-s-parser.py | 2 + src/gen-s-parser.inc | 42 +- src/passes/Print.cpp | 16 +- src/wasm-binary.h | 12 +- src/wasm-interpreter.h | 37 +- src/wasm/wasm-binary.cpp | 65 ++- src/wasm/wasm-stack.cpp | 30 +- src/wasm/wasm-validator.cpp | 5 +- test/lit/basic/f16.wast | 79 ++++ test/spec/f16.wast | 15 + third_party/FP16/LICENSE | 11 + third_party/FP16/include/fp16.h | 7 + third_party/FP16/include/fp16/bitcasts.h | 92 ++++ third_party/FP16/include/fp16/fp16.h | 515 +++++++++++++++++++++++ third_party/FP16/include/fp16/macros.h | 46 ++ third_party/FP16/readme.txt | 13 + 18 files changed, 952 insertions(+), 41 deletions(-) create mode 100644 test/lit/basic/f16.wast create mode 100644 test/spec/f16.wast create mode 100644 third_party/FP16/LICENSE create mode 100644 third_party/FP16/include/fp16.h create mode 100644 third_party/FP16/include/fp16/bitcasts.h create mode 100644 third_party/FP16/include/fp16/fp16.h create mode 100644 third_party/FP16/include/fp16/macros.h create mode 100644 third_party/FP16/readme.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b38f0baa49..94224299c51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,6 +175,7 @@ endif() # Compiler setup. include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/FP16/include) if(BUILD_LLVM_DWARF) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/llvm-project/include) endif() diff --git a/LICENSE b/LICENSE index 8dada3edaf5..cf8e1b79926 100644 --- a/LICENSE +++ b/LICENSE @@ -199,3 +199,8 @@ 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. + +============================================================================== + +The FP16 project is used in this repo, and it has the MIT license, see +third_party/FP16/LICENSE. diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index e1bfe3f3d9b..f3510964482 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -46,6 +46,7 @@ ("i32.load", "makeLoad(Type::i32, /*signed=*/false, 4, /*isAtomic=*/false)"), ("i64.load", "makeLoad(Type::i64, /*signed=*/false, 8, /*isAtomic=*/false)"), ("f32.load", "makeLoad(Type::f32, /*signed=*/false, 4, /*isAtomic=*/false)"), + ("f32.load_f16", "makeLoad(Type::f32, /*signed=*/false, 2, /*isAtomic=*/false)"), ("f64.load", "makeLoad(Type::f64, /*signed=*/false, 8, /*isAtomic=*/false)"), ("i32.load8_s", "makeLoad(Type::i32, /*signed=*/true, 1, /*isAtomic=*/false)"), ("i32.load8_u", "makeLoad(Type::i32, /*signed=*/false, 1, /*isAtomic=*/false)"), @@ -60,6 +61,7 @@ ("i32.store", "makeStore(Type::i32, 4, /*isAtomic=*/false)"), ("i64.store", "makeStore(Type::i64, 8, /*isAtomic=*/false)"), ("f32.store", "makeStore(Type::f32, 4, /*isAtomic=*/false)"), + ("f32.store_f16", "makeStore(Type::f32, 2, /*isAtomic=*/false)"), ("f64.store", "makeStore(Type::f64, 8, /*isAtomic=*/false)"), ("i32.store8", "makeStore(Type::i32, 1, /*isAtomic=*/false)"), ("i32.store16", "makeStore(Type::i32, 2, /*isAtomic=*/false)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 98f5b7831ea..c54a0de54b1 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -454,12 +454,23 @@ switch (buf[0]) { return Ok{}; } goto parse_error; - case 'o': - if (op == "f32.load"sv) { - CHECK_ERR(makeLoad(ctx, pos, annotations, Type::f32, /*signed=*/false, 4, /*isAtomic=*/false)); - return Ok{}; + case 'o': { + switch (buf[8]) { + case '\0': + if (op == "f32.load"sv) { + CHECK_ERR(makeLoad(ctx, pos, annotations, Type::f32, /*signed=*/false, 4, /*isAtomic=*/false)); + return Ok{}; + } + goto parse_error; + case '_': + if (op == "f32.load_f16"sv) { + CHECK_ERR(makeLoad(ctx, pos, annotations, Type::f32, /*signed=*/false, 2, /*isAtomic=*/false)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 't': if (op == "f32.lt"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::LtFloat32)); @@ -529,12 +540,23 @@ switch (buf[0]) { return Ok{}; } goto parse_error; - case 't': - if (op == "f32.store"sv) { - CHECK_ERR(makeStore(ctx, pos, annotations, Type::f32, 4, /*isAtomic=*/false)); - return Ok{}; + case 't': { + switch (buf[9]) { + case '\0': + if (op == "f32.store"sv) { + CHECK_ERR(makeStore(ctx, pos, annotations, Type::f32, 4, /*isAtomic=*/false)); + return Ok{}; + } + goto parse_error; + case '_': + if (op == "f32.store_f16"sv) { + CHECK_ERR(makeStore(ctx, pos, annotations, Type::f32, 2, /*isAtomic=*/false)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 'u': if (op == "f32.sub"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::SubFloat32)); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index ede49ab3801..aca43924d34 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -548,13 +548,19 @@ struct PrintExpressionContents if (curr->bytes == 1) { o << '8'; } else if (curr->bytes == 2) { - o << "16"; + if (curr->type == Type::f32) { + o << "_f16"; + } else { + o << "16"; + } } else if (curr->bytes == 4) { o << "32"; } else { abort(); } - o << (curr->signed_ ? "_s" : "_u"); + if (curr->type != Type::f32) { + o << (curr->signed_ ? "_s" : "_u"); + } } restoreNormalColor(o); printMemoryName(curr->memory, o, wasm); @@ -575,7 +581,11 @@ struct PrintExpressionContents if (curr->bytes == 1) { o << '8'; } else if (curr->bytes == 2) { - o << "16"; + if (curr->valueType == Type::f32) { + o << "_f16"; + } else { + o << "16"; + } } else if (curr->bytes == 4) { o << "32"; } else { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 8a6f825fffa..5fae1b64d7b 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1051,6 +1051,10 @@ enum ASTNodes { I16x8DotI8x16I7x16S = 0x112, I32x4DotI8x16I7x16AddS = 0x113, + // half precision opcodes + F32_F16LoadMem = 0x30, + F32_F16StoreMem = 0x31, + // bulk memory opcodes MemoryInit = 0x08, @@ -1703,8 +1707,12 @@ class WasmBinaryReader { void visitLocalSet(LocalSet* curr, uint8_t code); void visitGlobalGet(GlobalGet* curr); void visitGlobalSet(GlobalSet* curr); - bool maybeVisitLoad(Expression*& out, uint8_t code, bool isAtomic); - bool maybeVisitStore(Expression*& out, uint8_t code, bool isAtomic); + bool maybeVisitLoad(Expression*& out, + uint8_t code, + std::optional prefix); + bool maybeVisitStore(Expression*& out, + uint8_t code, + std::optional prefix); bool maybeVisitNontrappingTrunc(Expression*& out, uint32_t code); bool maybeVisitAtomicRMW(Expression*& out, uint8_t code); bool maybeVisitAtomicCmpxchg(Expression*& out, uint8_t code); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 9bdf0e72c1a..3e62d53354a 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -28,6 +28,7 @@ #include #include +#include "fp16.h" #include "ir/intrinsics.h" #include "ir/module-utils.h" #include "support/bits.h" @@ -2540,8 +2541,22 @@ class ModuleRunnerBase : public ExpressionRunner { } break; } - case Type::f32: - return Literal(load32u(addr, memory)).castToF32(); + case Type::f32: { + switch (load->bytes) { + case 2: { + // Convert the float16 to float32 and store the binary + // representation. + return Literal(bit_cast( + fp16_ieee_to_fp32_value(load16u(addr, memory)))) + .castToF32(); + } + case 4: + return Literal(load32u(addr, memory)).castToF32(); + default: + WASM_UNREACHABLE("invalid size"); + } + break; + } case Type::f64: return Literal(load64u(addr, memory)).castToF64(); case Type::v128: @@ -2590,9 +2605,23 @@ class ModuleRunnerBase : public ExpressionRunner { break; } // write floats carefully, ensuring all bits reach memory - case Type::f32: - store32(addr, value.reinterpreti32(), memory); + case Type::f32: { + switch (store->bytes) { + case 2: { + float f32 = bit_cast(value.reinterpreti32()); + // Convert the float32 to float16 and store the binary + // representation. + store16(addr, fp16_ieee_from_fp32_value(f32), memory); + break; + } + case 4: + store32(addr, value.reinterpreti32(), memory); + break; + default: + WASM_UNREACHABLE("invalid store size"); + } break; + } case Type::f64: store64(addr, value.reinterpreti64(), memory); break; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 574e13aa2b6..b9645ab8fec 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4145,10 +4145,10 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { } case BinaryConsts::AtomicPrefix: { code = static_cast(getU32LEB()); - if (maybeVisitLoad(curr, code, /*isAtomic=*/true)) { + if (maybeVisitLoad(curr, code, BinaryConsts::AtomicPrefix)) { break; } - if (maybeVisitStore(curr, code, /*isAtomic=*/true)) { + if (maybeVisitStore(curr, code, BinaryConsts::AtomicPrefix)) { break; } if (maybeVisitAtomicRMW(curr, code)) { @@ -4198,6 +4198,12 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { if (maybeVisitTableCopy(curr, opcode)) { break; } + if (maybeVisitLoad(curr, opcode, BinaryConsts::MiscPrefix)) { + break; + } + if (maybeVisitStore(curr, opcode, BinaryConsts::MiscPrefix)) { + break; + } throwError("invalid code after misc prefix: " + std::to_string(opcode)); break; } @@ -4338,10 +4344,10 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { if (maybeVisitConst(curr, code)) { break; } - if (maybeVisitLoad(curr, code, /*isAtomic=*/false)) { + if (maybeVisitLoad(curr, code, /*prefix=*/std::nullopt)) { break; } - if (maybeVisitStore(curr, code, /*isAtomic=*/false)) { + if (maybeVisitStore(curr, code, /*prefix=*/std::nullopt)) { break; } throwError("bad node code " + std::to_string(code)); @@ -4717,14 +4723,15 @@ Index WasmBinaryReader::readMemoryAccess(Address& alignment, Address& offset) { return memIdx; } -bool WasmBinaryReader::maybeVisitLoad(Expression*& out, - uint8_t code, - bool isAtomic) { +bool WasmBinaryReader::maybeVisitLoad( + Expression*& out, + uint8_t code, + std::optional prefix) { Load* curr; auto allocate = [&]() { curr = allocator.alloc(); }; - if (!isAtomic) { + if (!prefix) { switch (code) { case BinaryConsts::I32LoadMem8S: allocate(); @@ -4805,7 +4812,7 @@ bool WasmBinaryReader::maybeVisitLoad(Expression*& out, return false; } BYN_TRACE("zz node: Load\n"); - } else { + } else if (prefix == BinaryConsts::AtomicPrefix) { switch (code) { case BinaryConsts::I32AtomicLoad8U: allocate(); @@ -4846,9 +4853,22 @@ bool WasmBinaryReader::maybeVisitLoad(Expression*& out, return false; } BYN_TRACE("zz node: AtomicLoad\n"); + } else if (prefix == BinaryConsts::MiscPrefix) { + switch (code) { + case BinaryConsts::F32_F16LoadMem: + allocate(); + curr->bytes = 2; + curr->type = Type::f32; + break; + default: + return false; + } + BYN_TRACE("zz node: Load\n"); + } else { + return false; } - curr->isAtomic = isAtomic; + curr->isAtomic = prefix == BinaryConsts::AtomicPrefix; Index memIdx = readMemoryAccess(curr->align, curr->offset); memoryRefs[memIdx].push_back(&curr->memory); curr->ptr = popNonVoidExpression(); @@ -4857,11 +4877,12 @@ bool WasmBinaryReader::maybeVisitLoad(Expression*& out, return true; } -bool WasmBinaryReader::maybeVisitStore(Expression*& out, - uint8_t code, - bool isAtomic) { +bool WasmBinaryReader::maybeVisitStore( + Expression*& out, + uint8_t code, + std::optional prefix) { Store* curr; - if (!isAtomic) { + if (!prefix) { switch (code) { case BinaryConsts::I32StoreMem8: curr = allocator.alloc(); @@ -4911,7 +4932,7 @@ bool WasmBinaryReader::maybeVisitStore(Expression*& out, default: return false; } - } else { + } else if (prefix == BinaryConsts::AtomicPrefix) { switch (code) { case BinaryConsts::I32AtomicStore8: curr = allocator.alloc(); @@ -4951,9 +4972,21 @@ bool WasmBinaryReader::maybeVisitStore(Expression*& out, default: return false; } + } else if (prefix == BinaryConsts::MiscPrefix) { + switch (code) { + case BinaryConsts::F32_F16StoreMem: + curr = allocator.alloc(); + curr->bytes = 2; + curr->valueType = Type::f32; + break; + default: + return false; + } + } else { + return false; } - curr->isAtomic = isAtomic; + curr->isAtomic = prefix == BinaryConsts::AtomicPrefix; BYN_TRACE("zz node: Store\n"); Index memIdx = readMemoryAccess(curr->align, curr->offset); memoryRefs[memIdx].push_back(&curr->memory); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index cd0a9928e1a..35db3b32250 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -258,9 +258,20 @@ void BinaryInstWriter::visitLoad(Load* curr) { } break; } - case Type::f32: - o << int8_t(BinaryConsts::F32LoadMem); + case Type::f32: { + switch (curr->bytes) { + case 2: + o << int8_t(BinaryConsts::MiscPrefix) + << U32LEB(BinaryConsts::F32_F16LoadMem); + break; + case 4: + o << int8_t(BinaryConsts::F32LoadMem); + break; + default: + WASM_UNREACHABLE("invalid load size"); + } break; + } case Type::f64: o << int8_t(BinaryConsts::F64LoadMem); break; @@ -359,9 +370,20 @@ void BinaryInstWriter::visitStore(Store* curr) { } break; } - case Type::f32: - o << int8_t(BinaryConsts::F32StoreMem); + case Type::f32: { + switch (curr->bytes) { + case 2: + o << int8_t(BinaryConsts::MiscPrefix) + << U32LEB(BinaryConsts::F32_F16StoreMem); + break; + case 4: + o << int8_t(BinaryConsts::F32StoreMem); + break; + default: + WASM_UNREACHABLE("invalid store size"); + } break; + } case Type::f64: o << int8_t(BinaryConsts::F64StoreMem); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index ce7d0df3c22..b3291743225 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1579,8 +1579,9 @@ void FunctionValidator::validateMemBytes(uint8_t bytes, "expected i64 operation to touch 1, 2, 4, or 8 bytes"); break; case Type::f32: - shouldBeEqual( - bytes, uint8_t(4), curr, "expected f32 operation to touch 4 bytes"); + shouldBeTrue(bytes == 2 || bytes == 4, + curr, + "expected f32 operation to touch 2 or 4 bytes"); break; case Type::f64: shouldBeEqual( diff --git a/test/lit/basic/f16.wast b/test/lit/basic/f16.wast new file mode 100644 index 00000000000..c68b0306f96 --- /dev/null +++ b/test/lit/basic/f16.wast @@ -0,0 +1,79 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -all -o %t.text.wast -g -S +;; RUN: wasm-as %s -all -g -o %t.wasm +;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast +;; RUN: wasm-as %s -all -o %t.nodebug.wasm +;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast +;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT +;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN +;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG + +(module + (memory 1 1) + + + ;; CHECK-TEXT: (type $0 (func (param i32) (result f32))) + + ;; CHECK-TEXT: (type $1 (func (param i32 f32))) + + ;; CHECK-TEXT: (memory $0 1 1) + + ;; CHECK-TEXT: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) + ;; CHECK-TEXT-NEXT: (f32.load_f16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (type $0 (func (param i32) (result f32))) + + ;; CHECK-BIN: (type $1 (func (param i32 f32))) + + ;; CHECK-BIN: (memory $0 1 1) + + ;; CHECK-BIN: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) + ;; CHECK-BIN-NEXT: (f32.load_f16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32.load_f16 (param $0 i32) (result f32) + (f32.load_f16 + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f32.store_f16 (type $1) (param $0 i32) (param $1 f32) + ;; CHECK-TEXT-NEXT: (f32.store_f16 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f32.store_f16 (type $1) (param $0 i32) (param $1 f32) + ;; CHECK-BIN-NEXT: (f32.store_f16 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f32.store_f16 (param $0 i32) (param $1 f32) + (f32.store_f16 + (local.get $0) + (local.get $1) + ) + ) +) +;; CHECK-BIN-NODEBUG: (type $0 (func (param i32) (result f32))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f32))) + +;; CHECK-BIN-NODEBUG: (memory $0 1 1) + +;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (f32.load_f16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i32) (param $1 f32) +;; CHECK-BIN-NODEBUG-NEXT: (f32.store_f16 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/spec/f16.wast b/test/spec/f16.wast new file mode 100644 index 00000000000..19bad175674 --- /dev/null +++ b/test/spec/f16.wast @@ -0,0 +1,15 @@ +;; Test float 16 operations. + +(module + (memory (data "\40\51\AD\DE")) + + (func (export "f32.load_f16") (result f32) (f32.load_f16 (i32.const 0))) + (func (export "f32.store_f16") (f32.store_f16 (i32.const 0) (f32.const 100.5))) + (func (export "i32.load16_u") (result i32) (i32.load16_u (i32.const 2))) +) + +(assert_return (invoke "f32.load_f16") (f32.const 42.0)) +(invoke "f32.store_f16") +(assert_return (invoke "f32.load_f16") (f32.const 100.5)) +;; Ensure that the above operations didn't write to memory they shouldn't have. +(assert_return (invoke "i32.load16_u") (i32.const 0xDEAD)) diff --git a/third_party/FP16/LICENSE b/third_party/FP16/LICENSE new file mode 100644 index 00000000000..eabec6c86a3 --- /dev/null +++ b/third_party/FP16/LICENSE @@ -0,0 +1,11 @@ +The MIT License (MIT) + +Copyright (c) 2017 Facebook Inc. +Copyright (c) 2017 Georgia Institute of Technology +Copyright 2019 Google LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/FP16/include/fp16.h b/third_party/FP16/include/fp16.h new file mode 100644 index 00000000000..adbcb961c0b --- /dev/null +++ b/third_party/FP16/include/fp16.h @@ -0,0 +1,7 @@ +#pragma once +#ifndef FP16_H +#define FP16_H + +#include + +#endif /* FP16_H */ diff --git a/third_party/FP16/include/fp16/bitcasts.h b/third_party/FP16/include/fp16/bitcasts.h new file mode 100644 index 00000000000..ae68843259c --- /dev/null +++ b/third_party/FP16/include/fp16/bitcasts.h @@ -0,0 +1,92 @@ +#pragma once +#ifndef FP16_BITCASTS_H +#define FP16_BITCASTS_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include +#elif !defined(__OPENCL_VERSION__) + #include +#endif + +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) + #include +#endif + +#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) + #include +#endif + + +static inline float fp32_from_bits(uint32_t w) { +#if defined(__OPENCL_VERSION__) + return as_float(w); +#elif defined(__CUDA_ARCH__) + return __uint_as_float((unsigned int) w); +#elif defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) + return _castu32_f32(w); +#elif defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) + return _CopyFloatFromInt32((__int32) w); +#else + union { + uint32_t as_bits; + float as_value; + } fp32 = { w }; + return fp32.as_value; +#endif +} + +static inline uint32_t fp32_to_bits(float f) { +#if defined(__OPENCL_VERSION__) + return as_uint(f); +#elif defined(__CUDA_ARCH__) + return (uint32_t) __float_as_uint(f); +#elif defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) + return _castf32_u32(f); +#elif defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) + return (uint32_t) _CopyInt32FromFloat(f); +#else + union { + float as_value; + uint32_t as_bits; + } fp32 = { f }; + return fp32.as_bits; +#endif +} + +static inline double fp64_from_bits(uint64_t w) { +#if defined(__OPENCL_VERSION__) + return as_double(w); +#elif defined(__CUDA_ARCH__) + return __longlong_as_double((long long) w); +#elif defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) + return _castu64_f64(w); +#elif defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) + return _CopyDoubleFromInt64((__int64) w); +#else + union { + uint64_t as_bits; + double as_value; + } fp64 = { w }; + return fp64.as_value; +#endif +} + +static inline uint64_t fp64_to_bits(double f) { +#if defined(__OPENCL_VERSION__) + return as_ulong(f); +#elif defined(__CUDA_ARCH__) + return (uint64_t) __double_as_longlong(f); +#elif defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) + return _castf64_u64(f); +#elif defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) + return (uint64_t) _CopyInt64FromDouble(f); +#else + union { + double as_value; + uint64_t as_bits; + } fp64 = { f }; + return fp64.as_bits; +#endif +} + +#endif /* FP16_BITCASTS_H */ diff --git a/third_party/FP16/include/fp16/fp16.h b/third_party/FP16/include/fp16/fp16.h new file mode 100644 index 00000000000..95fa0c2de8c --- /dev/null +++ b/third_party/FP16/include/fp16/fp16.h @@ -0,0 +1,515 @@ +#pragma once +#ifndef FP16_FP16_H +#define FP16_FP16_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include + #include +#elif !defined(__OPENCL_VERSION__) + #include + #include +#endif + +#include +#include + +#if defined(_MSC_VER) + #include +#endif +#if defined(__F16C__) && FP16_USE_NATIVE_CONVERSION && !FP16_USE_FLOAT16_TYPE && !FP16_USE_FP16_TYPE + #include +#endif +#if (defined(__aarch64__) || defined(_M_ARM64)) && FP16_USE_NATIVE_CONVERSION && !FP16_USE_FLOAT16_TYPE && !FP16_USE_FP16_TYPE + #include +#endif + + +/* + * Convert a 16-bit floating-point number in IEEE half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format, in bit representation. + * + * @note The implementation doesn't use any floating-point operations. + */ +static inline uint32_t fp16_ieee_to_fp32_bits(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the bits 0-30 of the 32-bit word: + * + * +---+-----+------------+-------------------+ + * | 0 |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 30 27-31 17-26 0-16 + */ + const uint32_t nonsign = w & UINT32_C(0x7FFFFFFF); + /* + * Renorm shift is the number of bits to shift mantissa left to make the half-precision number normalized. + * If the initial number is normalized, some of its high 6 bits (sign == 0 and 5-bit exponent) equals one. + * In this case renorm_shift == 0. If the number is denormalize, renorm_shift > 0. Note that if we shift + * denormalized nonsign by renorm_shift, the unit bit of mantissa will shift into exponent, turning the + * biased exponent into 1, and making mantissa normalized (i.e. without leading 1). + */ +#ifdef _MSC_VER + unsigned long nonsign_bsr; + _BitScanReverse(&nonsign_bsr, (unsigned long) nonsign); + uint32_t renorm_shift = (uint32_t) nonsign_bsr ^ 31; +#else + uint32_t renorm_shift = __builtin_clz(nonsign); +#endif + renorm_shift = renorm_shift > 5 ? renorm_shift - 5 : 0; + /* + * Iff half-precision number has exponent of 15, the addition overflows it into bit 31, + * and the subsequent shift turns the high 9 bits into 1. Thus + * inf_nan_mask == + * 0x7F800000 if the half-precision number had exponent of 15 (i.e. was NaN or infinity) + * 0x00000000 otherwise + */ + const int32_t inf_nan_mask = ((int32_t) (nonsign + 0x04000000) >> 8) & INT32_C(0x7F800000); + /* + * Iff nonsign is 0, it overflows into 0xFFFFFFFF, turning bit 31 into 1. Otherwise, bit 31 remains 0. + * The signed shift right by 31 broadcasts bit 31 into all bits of the zero_mask. Thus + * zero_mask == + * 0xFFFFFFFF if the half-precision number was zero (+0.0h or -0.0h) + * 0x00000000 otherwise + */ + const int32_t zero_mask = (int32_t) (nonsign - 1) >> 31; + /* + * 1. Shift nonsign left by renorm_shift to normalize it (if the input was denormal) + * 2. Shift nonsign right by 3 so the exponent (5 bits originally) becomes an 8-bit field and 10-bit mantissa + * shifts into the 10 high bits of the 23-bit mantissa of IEEE single-precision number. + * 3. Add 0x70 to the exponent (starting at bit 23) to compensate the different in exponent bias + * (0x7F for single-precision number less 0xF for half-precision number). + * 4. Subtract renorm_shift from the exponent (starting at bit 23) to account for renormalization. As renorm_shift + * is less than 0x70, this can be combined with step 3. + * 5. Binary OR with inf_nan_mask to turn the exponent into 0xFF if the input was NaN or infinity. + * 6. Binary ANDNOT with zero_mask to turn the mantissa and exponent into zero if the input was zero. + * 7. Combine with the sign of the input number. + */ + return sign | ((((nonsign << renorm_shift >> 3) + ((0x70 - renorm_shift) << 23)) | inf_nan_mask) & ~zero_mask); +} + +/* + * Convert a 16-bit floating-point number in IEEE half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline float fp16_ieee_to_fp32_value(uint16_t h) { +#if FP16_USE_NATIVE_CONVERSION + #if FP16_USE_FLOAT16_TYPE + union { + uint16_t as_bits; + _Float16 as_value; + } fp16 = { h }; + return (float) fp16.as_value; + #elif FP16_USE_FP16_TYPE + union { + uint16_t as_bits; + __fp16 as_value; + } fp16 = { h }; + return (float) fp16.as_value; + #else + #if (defined(__INTEL_COMPILER) || defined(__GNUC__)) && defined(__F16C__) + return _cvtsh_ss((unsigned short) h); + #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && defined(__AVX2__) + return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128((int) (unsigned int) h))); + #elif defined(_M_ARM64) || defined(__aarch64__) + return vgetq_lane_f32(vcvt_f32_f16(vreinterpret_f16_u16(vdup_n_u16(h))), 0); + #else + #error "Archtecture- or compiler-specific implementation required" + #endif + #endif +#else + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the high bits of the 32-bit word: + * + * +-----+------------+---------------------+ + * |EEEEE|MM MMMM MMMM|0 0000 0000 0000 0000| + * +-----+------------+---------------------+ + * Bits 27-31 17-26 0-16 + */ + const uint32_t two_w = w + w; + + /* + * Shift mantissa and exponent into bits 23-28 and bits 13-22 so they become mantissa and exponent + * of a single-precision floating-point number: + * + * S|Exponent | Mantissa + * +-+---+-----+------------+----------------+ + * |0|000|EEEEE|MM MMMM MMMM|0 0000 0000 0000| + * +-+---+-----+------------+----------------+ + * Bits | 23-31 | 0-22 + * + * Next, there are some adjustments to the exponent: + * - The exponent needs to be corrected by the difference in exponent bias between single-precision and half-precision + * formats (0x7F - 0xF = 0x70) + * - Inf and NaN values in the inputs should become Inf and NaN values after conversion to the single-precision number. + * Therefore, if the biased exponent of the half-precision input was 0x1F (max possible value), the biased exponent + * of the single-precision output must be 0xFF (max possible value). We do this correction in two steps: + * - First, we adjust the exponent by (0xFF - 0x1F) = 0xE0 (see exp_offset below) rather than by 0x70 suggested + * by the difference in the exponent bias (see above). + * - Then we multiply the single-precision result of exponent adjustment by 2**(-112) to reverse the effect of + * exponent adjustment by 0xE0 less the necessary exponent adjustment by 0x70 due to difference in exponent bias. + * The floating-point multiplication hardware would ensure than Inf and NaN would retain their value on at least + * partially IEEE754-compliant implementations. + * + * Note that the above operations do not handle denormal inputs (where biased exponent == 0). However, they also do not + * operate on denormal inputs, and do not produce denormal results. + */ + const uint32_t exp_offset = UINT32_C(0xE0) << 23; +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float exp_scale = 0x1.0p-112f; +#else + const float exp_scale = fp32_from_bits(UINT32_C(0x7800000)); +#endif + const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset) * exp_scale; + + /* + * Convert denormalized half-precision inputs into single-precision results (always normalized). + * Zero inputs are also handled here. + * + * In a denormalized number the biased exponent is zero, and mantissa has on-zero bits. + * First, we shift mantissa into bits 0-9 of the 32-bit word. + * + * zeros | mantissa + * +---------------------------+------------+ + * |0000 0000 0000 0000 0000 00|MM MMMM MMMM| + * +---------------------------+------------+ + * Bits 10-31 0-9 + * + * Now, remember that denormalized half-precision numbers are represented as: + * FP16 = mantissa * 2**(-24). + * The trick is to construct a normalized single-precision number with the same mantissa and thehalf-precision input + * and with an exponent which would scale the corresponding mantissa bits to 2**(-24). + * A normalized single-precision floating-point number is represented as: + * FP32 = (1 + mantissa * 2**(-23)) * 2**(exponent - 127) + * Therefore, when the biased exponent is 126, a unit change in the mantissa of the input denormalized half-precision + * number causes a change of the constructud single-precision number by 2**(-24), i.e. the same ammount. + * + * The last step is to adjust the bias of the constructed single-precision number. When the input half-precision number + * is zero, the constructed single-precision number has the value of + * FP32 = 1 * 2**(126 - 127) = 2**(-1) = 0.5 + * Therefore, we need to subtract 0.5 from the constructed single-precision number to get the numerical equivalent of + * the input half-precision number. + */ + const uint32_t magic_mask = UINT32_C(126) << 23; + const float magic_bias = 0.5f; + const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias; + + /* + * - Choose either results of conversion of input as a normalized number, or as a denormalized number, depending on the + * input exponent. The variable two_w contains input exponent in bits 27-31, therefore if its smaller than 2**27, the + * input is either a denormal number, or zero. + * - Combine the result of conversion of exponent and mantissa with the sign of the input number. + */ + const uint32_t denormalized_cutoff = UINT32_C(1) << 27; + const uint32_t result = sign | + (two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value)); + return fp32_from_bits(result); +#endif +} + +/* + * Convert a 32-bit floating-point number in IEEE single-precision format to a 16-bit floating-point number in + * IEEE half-precision format, in bit representation. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline uint16_t fp16_ieee_from_fp32_value(float f) { +#if FP16_USE_NATIVE_CONVERSION + #if FP16_USE_FLOAT16_TYPE + union { + _Float16 as_value; + uint16_t as_bits; + } fp16 = { (_Float16) f }; + return fp16.as_bits; + #elif FP16_USE_FP16_TYPE + union { + __fp16 as_value; + uint16_t as_bits; + } fp16 = { (__fp16) f }; + return fp16.as_bits; + #else + #if (defined(__INTEL_COMPILER) || defined(__GNUC__)) && defined(__F16C__) + return _cvtss_sh(f, _MM_FROUND_CUR_DIRECTION); + #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && defined(__AVX2__) + return (uint16_t) _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(f), _MM_FROUND_CUR_DIRECTION)); + #elif defined(_M_ARM64) || defined(__aarch64__) + return vget_lane_u16(vcvt_f16_f32(vdupq_n_f32(f)), 0); + #else + #error "Archtecture- or compiler-specific implementation required" + #endif + #endif +#else +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float scale_to_inf = 0x1.0p+112f; + const float scale_to_zero = 0x1.0p-110f; +#else + const float scale_to_inf = fp32_from_bits(UINT32_C(0x77800000)); + const float scale_to_zero = fp32_from_bits(UINT32_C(0x08800000)); +#endif +#if defined(_MSC_VER) && defined(_M_IX86_FP) && (_M_IX86_FP == 0) || defined(__GNUC__) && defined(__FLT_EVAL_METHOD__) && (__FLT_EVAL_METHOD__ != 0) + const volatile float saturated_f = fabsf(f) * scale_to_inf; +#else + const float saturated_f = fabsf(f) * scale_to_inf; +#endif + float base = saturated_f * scale_to_zero; + + const uint32_t w = fp32_to_bits(f); + const uint32_t shl1_w = w + w; + const uint32_t sign = w & UINT32_C(0x80000000); + uint32_t bias = shl1_w & UINT32_C(0xFF000000); + if (bias < UINT32_C(0x71000000)) { + bias = UINT32_C(0x71000000); + } + + base = fp32_from_bits((bias >> 1) + UINT32_C(0x07800000)) + base; + const uint32_t bits = fp32_to_bits(base); + const uint32_t exp_bits = (bits >> 13) & UINT32_C(0x00007C00); + const uint32_t mantissa_bits = bits & UINT32_C(0x00000FFF); + const uint32_t nonsign = exp_bits + mantissa_bits; + return (sign >> 16) | (shl1_w > UINT32_C(0xFF000000) ? UINT16_C(0x7E00) : nonsign); +#endif +} + +/* + * Convert a 16-bit floating-point number in ARM alternative half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format, in bit representation. + * + * @note The implementation doesn't use any floating-point operations. + */ +static inline uint32_t fp16_alt_to_fp32_bits(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the bits 0-30 of the 32-bit word: + * + * +---+-----+------------+-------------------+ + * | 0 |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 30 27-31 17-26 0-16 + */ + const uint32_t nonsign = w & UINT32_C(0x7FFFFFFF); + /* + * Renorm shift is the number of bits to shift mantissa left to make the half-precision number normalized. + * If the initial number is normalized, some of its high 6 bits (sign == 0 and 5-bit exponent) equals one. + * In this case renorm_shift == 0. If the number is denormalize, renorm_shift > 0. Note that if we shift + * denormalized nonsign by renorm_shift, the unit bit of mantissa will shift into exponent, turning the + * biased exponent into 1, and making mantissa normalized (i.e. without leading 1). + */ +#ifdef _MSC_VER + unsigned long nonsign_bsr; + _BitScanReverse(&nonsign_bsr, (unsigned long) nonsign); + uint32_t renorm_shift = (uint32_t) nonsign_bsr ^ 31; +#else + uint32_t renorm_shift = __builtin_clz(nonsign); +#endif + renorm_shift = renorm_shift > 5 ? renorm_shift - 5 : 0; + /* + * Iff nonsign is 0, it overflows into 0xFFFFFFFF, turning bit 31 into 1. Otherwise, bit 31 remains 0. + * The signed shift right by 31 broadcasts bit 31 into all bits of the zero_mask. Thus + * zero_mask == + * 0xFFFFFFFF if the half-precision number was zero (+0.0h or -0.0h) + * 0x00000000 otherwise + */ + const int32_t zero_mask = (int32_t) (nonsign - 1) >> 31; + /* + * 1. Shift nonsign left by renorm_shift to normalize it (if the input was denormal) + * 2. Shift nonsign right by 3 so the exponent (5 bits originally) becomes an 8-bit field and 10-bit mantissa + * shifts into the 10 high bits of the 23-bit mantissa of IEEE single-precision number. + * 3. Add 0x70 to the exponent (starting at bit 23) to compensate the different in exponent bias + * (0x7F for single-precision number less 0xF for half-precision number). + * 4. Subtract renorm_shift from the exponent (starting at bit 23) to account for renormalization. As renorm_shift + * is less than 0x70, this can be combined with step 3. + * 5. Binary ANDNOT with zero_mask to turn the mantissa and exponent into zero if the input was zero. + * 6. Combine with the sign of the input number. + */ + return sign | (((nonsign << renorm_shift >> 3) + ((0x70 - renorm_shift) << 23)) & ~zero_mask); +} + +/* + * Convert a 16-bit floating-point number in ARM alternative half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline float fp16_alt_to_fp32_value(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the high bits of the 32-bit word: + * + * +-----+------------+---------------------+ + * |EEEEE|MM MMMM MMMM|0 0000 0000 0000 0000| + * +-----+------------+---------------------+ + * Bits 27-31 17-26 0-16 + */ + const uint32_t two_w = w + w; + + /* + * Shift mantissa and exponent into bits 23-28 and bits 13-22 so they become mantissa and exponent + * of a single-precision floating-point number: + * + * S|Exponent | Mantissa + * +-+---+-----+------------+----------------+ + * |0|000|EEEEE|MM MMMM MMMM|0 0000 0000 0000| + * +-+---+-----+------------+----------------+ + * Bits | 23-31 | 0-22 + * + * Next, the exponent is adjusted for the difference in exponent bias between single-precision and half-precision + * formats (0x7F - 0xF = 0x70). This operation never overflows or generates non-finite values, as the largest + * half-precision exponent is 0x1F and after the adjustment is can not exceed 0x8F < 0xFE (largest single-precision + * exponent for non-finite values). + * + * Note that this operation does not handle denormal inputs (where biased exponent == 0). However, they also do not + * operate on denormal inputs, and do not produce denormal results. + */ + const uint32_t exp_offset = UINT32_C(0x70) << 23; + const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset); + + /* + * Convert denormalized half-precision inputs into single-precision results (always normalized). + * Zero inputs are also handled here. + * + * In a denormalized number the biased exponent is zero, and mantissa has on-zero bits. + * First, we shift mantissa into bits 0-9 of the 32-bit word. + * + * zeros | mantissa + * +---------------------------+------------+ + * |0000 0000 0000 0000 0000 00|MM MMMM MMMM| + * +---------------------------+------------+ + * Bits 10-31 0-9 + * + * Now, remember that denormalized half-precision numbers are represented as: + * FP16 = mantissa * 2**(-24). + * The trick is to construct a normalized single-precision number with the same mantissa and thehalf-precision input + * and with an exponent which would scale the corresponding mantissa bits to 2**(-24). + * A normalized single-precision floating-point number is represented as: + * FP32 = (1 + mantissa * 2**(-23)) * 2**(exponent - 127) + * Therefore, when the biased exponent is 126, a unit change in the mantissa of the input denormalized half-precision + * number causes a change of the constructud single-precision number by 2**(-24), i.e. the same ammount. + * + * The last step is to adjust the bias of the constructed single-precision number. When the input half-precision number + * is zero, the constructed single-precision number has the value of + * FP32 = 1 * 2**(126 - 127) = 2**(-1) = 0.5 + * Therefore, we need to subtract 0.5 from the constructed single-precision number to get the numerical equivalent of + * the input half-precision number. + */ + const uint32_t magic_mask = UINT32_C(126) << 23; + const float magic_bias = 0.5f; + const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias; + + /* + * - Choose either results of conversion of input as a normalized number, or as a denormalized number, depending on the + * input exponent. The variable two_w contains input exponent in bits 27-31, therefore if its smaller than 2**27, the + * input is either a denormal number, or zero. + * - Combine the result of conversion of exponent and mantissa with the sign of the input number. + */ + const uint32_t denormalized_cutoff = UINT32_C(1) << 27; + const uint32_t result = sign | + (two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value)); + return fp32_from_bits(result); +} + +/* + * Convert a 32-bit floating-point number in IEEE single-precision format to a 16-bit floating-point number in + * ARM alternative half-precision format, in bit representation. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline uint16_t fp16_alt_from_fp32_value(float f) { + const uint32_t w = fp32_to_bits(f); + const uint32_t sign = w & UINT32_C(0x80000000); + const uint32_t shl1_w = w + w; + + const uint32_t shl1_max_fp16_fp32 = UINT32_C(0x8FFFC000); + const uint32_t shl1_base = shl1_w > shl1_max_fp16_fp32 ? shl1_max_fp16_fp32 : shl1_w; + uint32_t shl1_bias = shl1_base & UINT32_C(0xFF000000); + const uint32_t exp_difference = 23 - 10; + const uint32_t shl1_bias_min = (127 - 1 - exp_difference) << 24; + if (shl1_bias < shl1_bias_min) { + shl1_bias = shl1_bias_min; + } + + const float bias = fp32_from_bits((shl1_bias >> 1) + ((exp_difference + 2) << 23)); + const float base = fp32_from_bits((shl1_base >> 1) + (2 << 23)) + bias; + + const uint32_t exp_f = fp32_to_bits(base) >> 13; + return (sign >> 16) | ((exp_f & UINT32_C(0x00007C00)) + (fp32_to_bits(base) & UINT32_C(0x00000FFF))); +} + +#endif /* FP16_FP16_H */ diff --git a/third_party/FP16/include/fp16/macros.h b/third_party/FP16/include/fp16/macros.h new file mode 100644 index 00000000000..4018b0c9d0f --- /dev/null +++ b/third_party/FP16/include/fp16/macros.h @@ -0,0 +1,46 @@ +#pragma once +#ifndef FP16_MACROS_H +#define FP16_MACROS_H + +#ifndef FP16_USE_NATIVE_CONVERSION + #if (defined(__INTEL_COMPILER) || defined(__GNUC__)) && defined(__F16C__) + #define FP16_USE_NATIVE_CONVERSION 1 + #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && defined(__AVX2__) + #define FP16_USE_NATIVE_CONVERSION 1 + #elif defined(_MSC_VER) && defined(_M_ARM64) + #define FP16_USE_NATIVE_CONVERSION 1 + #elif defined(__GNUC__) && defined(__aarch64__) + #define FP16_USE_NATIVE_CONVERSION 1 + #endif + #if !defined(FP16_USE_NATIVE_CONVERSION) + #define FP16_USE_NATIVE_CONVERSION 0 + #endif // !defined(FP16_USE_NATIVE_CONVERSION) +#endif // !define(FP16_USE_NATIVE_CONVERSION) + +#ifndef FP16_USE_FLOAT16_TYPE + #if !defined(__clang__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ >= 12) + #if defined(__F16C__) + #define FP16_USE_FLOAT16_TYPE 1 + #endif + #endif + #if !defined(FP16_USE_FLOAT16_TYPE) + #define FP16_USE_FLOAT16_TYPE 0 + #endif // !defined(FP16_USE_FLOAT16_TYPE) +#endif // !defined(FP16_USE_FLOAT16_TYPE) + +#ifndef FP16_USE_FP16_TYPE + #if defined(__clang__) + #if defined(__F16C__) || defined(__aarch64__) + #define FP16_USE_FP16_TYPE 1 + #endif + #elif defined(__GNUC__) + #if defined(__aarch64__) + #define FP16_USE_FP16_TYPE 1 + #endif + #endif + #if !defined(FP16_USE_FP16_TYPE) + #define FP16_USE_FP16_TYPE 0 + #endif // !defined(FP16_USE_FP16_TYPE) +#endif // !defined(FP16_USE_FP16_TYPE) + +#endif /* FP16_MACROS_H */ diff --git a/third_party/FP16/readme.txt b/third_party/FP16/readme.txt new file mode 100644 index 00000000000..9a09e623d4b --- /dev/null +++ b/third_party/FP16/readme.txt @@ -0,0 +1,13 @@ +This folder contains files from FP16. See LICENSE.TXT for their license. + +These files were synced from + +commit 98b0a46bce017382a6351a19577ec43a715b6835 (HEAD -> master, origin/master, origin/HEAD) +Author: Marat Dukhan +Date: Wed Jun 19 23:11:08 2024 -0700 + + Support native conversions without __fp16/_Float16 types + +and also contain the patch from + +https://github.com/Maratyszcza/FP16/pull/31 616ad91f449a03d0b48a8a124f4d1baa94f869b2 From 23a1a1aacc0dd14767ca8c53a034b7c6bb4acf52 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 6 Aug 2024 20:01:54 -0400 Subject: [PATCH 501/553] [parser] Fix bug when printing type builder errors (#6817) The type index from the TypeBuilder error was mapped to a file location incorrectly, resulting in an assertion failure. Fixes #6816. --- src/parser/parse-2-typedefs.cpp | 2 +- test/lit/parse-bad-supertype-8616.wast | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/lit/parse-bad-supertype-8616.wast diff --git a/src/parser/parse-2-typedefs.cpp b/src/parser/parse-2-typedefs.cpp index 90a84941d89..97ba247bdc4 100644 --- a/src/parser/parse-2-typedefs.cpp +++ b/src/parser/parse-2-typedefs.cpp @@ -34,7 +34,7 @@ Result<> parseTypeDefs( if (auto* err = built.getError()) { std::stringstream msg; msg << "invalid type: " << err->reason; - return ctx.in.err(decls.typeDefs[err->index].pos, msg.str()); + return ctx.in.err(decls.subtypeDefs[err->index].pos, msg.str()); } types = *built; // Record type names on the module and in typeNames. diff --git a/test/lit/parse-bad-supertype-8616.wast b/test/lit/parse-bad-supertype-8616.wast new file mode 100644 index 00000000000..c7c3dc957d7 --- /dev/null +++ b/test/lit/parse-bad-supertype-8616.wast @@ -0,0 +1,11 @@ +;; RUN: not wasm-opt %s 2>&1 | filecheck %s + +;; CHECK: Fatal: 9:2: error: invalid type: Heap type has an undeclared supertype + +;; Regression test for a parser bug that caused an assertion failure in this case. +(module + (rec + (type $A (sub (struct (field i32)))) + (type $B (sub $B (struct (field i32) (field i32)))) + ) +) \ No newline at end of file From 9163e0d155a85cc57883257b8cca6fcbb22fe7b6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 7 Aug 2024 13:45:16 -0400 Subject: [PATCH 502/553] [NFC][parser] Rename deftype and subtype (#6819) Match the current spec and clarify terminology by renaming the old `deftype` to `rectype` and renaming the old `subtype` to `typedef`. Also split the parser for actual `subtype` out of the parser for the newly named `typedef`. --- src/parser/contexts.h | 14 ++++----- src/parser/parse-2-typedefs.cpp | 10 +++---- src/parser/parsers.h | 53 +++++++++++++++++++-------------- src/parser/wat-parser.cpp | 2 +- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 96a70663d15..5acb842d67b 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -885,8 +885,8 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { Module& wasm; // The module element definitions we are parsing in this phase. + std::vector recTypeDefs; std::vector typeDefs; - std::vector subtypeDefs; std::vector funcDefs; std::vector tableDefs; std::vector memoryDefs; @@ -939,15 +939,15 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { void setOpen() {} void setShared() {} Result<> addSubtype(HeapTypeT) { return Ok{}; } - void finishSubtype(Name name, Index pos) { + void finishTypeDef(Name name, Index pos) { // TODO: type annotations - subtypeDefs.push_back({name, pos, Index(subtypeDefs.size()), {}}); + typeDefs.push_back({name, pos, Index(typeDefs.size()), {}}); } size_t getRecGroupStartIndex() { return 0; } void addRecGroup(Index, size_t) {} - void finishDeftype(Index pos) { + void finishRectype(Index pos) { // TODO: type annotations - typeDefs.push_back({{}, pos, Index(typeDefs.size()), {}}); + recTypeDefs.push_back({{}, pos, Index(recTypeDefs.size()), {}}); } Limits makeLimits(uint64_t n, std::optional m) { @@ -1115,7 +1115,7 @@ struct ParseTypeDefsCtx : TypeParserCtx { return Ok{}; } - void finishSubtype(Name name, Index pos) { names[index++].name = name; } + void finishTypeDef(Name name, Index pos) { names[index++].name = name; } size_t getRecGroupStartIndex() { return index; } @@ -1123,7 +1123,7 @@ struct ParseTypeDefsCtx : TypeParserCtx { builder.createRecGroup(start, len); } - void finishDeftype(Index) {} + void finishRectype(Index) {} }; // Phase 3: Parse type uses to find implicitly defined types. diff --git a/src/parser/parse-2-typedefs.cpp b/src/parser/parse-2-typedefs.cpp index 97ba247bdc4..83e10ec5b8a 100644 --- a/src/parser/parse-2-typedefs.cpp +++ b/src/parser/parse-2-typedefs.cpp @@ -24,17 +24,17 @@ Result<> parseTypeDefs( IndexMap& typeIndices, std::vector& types, std::unordered_map>& typeNames) { - TypeBuilder builder(decls.subtypeDefs.size()); + TypeBuilder builder(decls.typeDefs.size()); ParseTypeDefsCtx ctx(input, builder, typeIndices); - for (auto& typeDef : decls.typeDefs) { - WithPosition with(ctx, typeDef.pos); - CHECK_ERR(deftype(ctx)); + for (auto& recType : decls.recTypeDefs) { + WithPosition with(ctx, recType.pos); + CHECK_ERR(rectype(ctx)); } auto built = builder.build(); if (auto* err = built.getError()) { std::stringstream msg; msg << "invalid type: " << err->reason; - return ctx.in.err(decls.subtypeDefs[err->index].pos, msg.str()); + return ctx.in.err(decls.typeDefs[err->index].pos, msg.str()); } types = *built; // Record type names on the module and in typeNames. diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 2c3916fa38a..e3434d1e653 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -338,8 +338,9 @@ MaybeResult inlineImport(Lexer&); Result> inlineExports(Lexer&); template Result<> comptype(Ctx&); template Result<> sharecomptype(Ctx&); -template MaybeResult subtype(Ctx&); -template MaybeResult<> deftype(Ctx&); +template Result<> subtype(Ctx&); +template MaybeResult<> typedef_(Ctx&); +template MaybeResult<> rectype(Ctx&); template MaybeResult locals(Ctx&); template MaybeResult<> import_(Ctx&); template MaybeResult<> func(Ctx&); @@ -2780,20 +2781,8 @@ template Result<> sharecomptype(Ctx& ctx) { return Ok{}; } -// subtype ::= '(' 'type' id? '(' 'sub' typeidx? sharecomptype ')' ')' -// | '(' 'type' id? sharecomptype ')' -template MaybeResult<> subtype(Ctx& ctx) { - auto pos = ctx.in.getPos(); - - if (!ctx.in.takeSExprStart("type"sv)) { - return {}; - } - - Name name; - if (auto id = ctx.in.takeID()) { - name = *id; - } - +// subtype ::= '(' 'sub' typeidx? sharecomptype ')' | sharecomptype +template Result<> subtype(Ctx& ctx) { if (ctx.in.takeSExprStart("sub"sv)) { if (!ctx.in.takeKeyword("final"sv)) { ctx.setOpen(); @@ -2811,24 +2800,42 @@ template MaybeResult<> subtype(Ctx& ctx) { } else { CHECK_ERR(sharecomptype(ctx)); } + return Ok{}; +} + +// typedef ::= '(' 'type' id? subtype ')' +template MaybeResult<> typedef_(Ctx& ctx) { + auto pos = ctx.in.getPos(); + + if (!ctx.in.takeSExprStart("type"sv)) { + return {}; + } + + Name name; + if (auto id = ctx.in.takeID()) { + name = *id; + } + + auto sub = subtype(ctx); + CHECK_ERR(sub); if (!ctx.in.takeRParen()) { return ctx.in.err("expected end of type definition"); } - ctx.finishSubtype(name, pos); + ctx.finishTypeDef(name, pos); return Ok{}; } -// deftype ::= '(' 'rec' subtype* ')' +// rectype ::= '(' 'rec' subtype* ')' // | subtype -template MaybeResult<> deftype(Ctx& ctx) { +template MaybeResult<> rectype(Ctx& ctx) { auto pos = ctx.in.getPos(); if (ctx.in.takeSExprStart("rec"sv)) { size_t startIndex = ctx.getRecGroupStartIndex(); size_t groupLen = 0; - while (auto type = subtype(ctx)) { + while (auto type = typedef_(ctx)) { CHECK_ERR(type); ++groupLen; } @@ -2836,13 +2843,13 @@ template MaybeResult<> deftype(Ctx& ctx) { return ctx.in.err("expected type definition or end of recursion group"); } ctx.addRecGroup(startIndex, groupLen); - } else if (auto type = subtype(ctx)) { + } else if (auto type = typedef_(ctx)) { CHECK_ERR(type); } else { return {}; } - ctx.finishDeftype(pos); + ctx.finishRectype(pos); return Ok{}; } @@ -3464,7 +3471,7 @@ template MaybeResult<> modulefield(Ctx& ctx) { if (ctx.in.empty() || ctx.in.peekRParen()) { return {}; } - if (auto res = deftype(ctx)) { + if (auto res = rectype(ctx)) { CHECK_ERR(res); return Ok{}; } diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp index 975cbd3c35b..0a40decd5ef 100644 --- a/src/parser/wat-parser.cpp +++ b/src/parser/wat-parser.cpp @@ -97,7 +97,7 @@ Result<> doParseModule(Module& wasm, Lexer& input, bool allowExtra) { return decls.in.err("Unexpected tokens after module"); } - auto typeIndices = createIndexMap(decls.in, decls.subtypeDefs); + auto typeIndices = createIndexMap(decls.in, decls.typeDefs); CHECK_ERR(typeIndices); std::vector types; From dc87572a2d24f7dd42bec3af3005f09bc2c26af3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 7 Aug 2024 11:34:25 -0700 Subject: [PATCH 503/553] GTO: Remove minor optimization of avoiding ChildLocalizer sometimes (#6818) The optimization is to only use ChildLocalizer, which moves children to locals, if we actually have a reason to use it. It is simple enough to see if we are removing fields with side effects here, and only call ChildLocalizer if we are not. However, this will become much more complicated in a subsequent PR which will reorder fields, which allows removing yet more of them (without reordering, we can only remove fields at the end, if any subtype needs the field). This is a pretty minor optimization, as it avoids adding a few locals in the rare case of struct.new operands having side effects. We run --gto at the start of the pipeline, so later opts will clean that up anyhow. (Though, this might make us a little less efficient, but the following PR will justify this regression.) --- src/passes/GlobalTypeOptimization.cpp | 28 +++++++-------------------- test/lit/passes/gto-removals.wast | 16 ++++++++++----- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index e5cd4e410a6..5362135616e 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -22,7 +22,6 @@ // * Fields that are never read from can be removed entirely. // -#include "ir/effects.h" #include "ir/localize.h" #include "ir/ordering.h" #include "ir/struct-utils.h" @@ -348,26 +347,11 @@ struct GlobalTypeOptimization : public Pass { auto& operands = curr->operands; assert(indexesAfterRemoval.size() == operands.size()); - // Check for side effects in removed fields. If there are any, we must - // use locals to save the values (while keeping them in order). - bool useLocals = false; - for (Index i = 0; i < operands.size(); i++) { - auto newIndex = indexesAfterRemoval[i]; - if (newIndex == RemovedField && - EffectAnalyzer(getPassOptions(), *getModule(), operands[i]) - .hasUnremovableSideEffects()) { - useLocals = true; - break; - } - } - if (useLocals) { - auto* func = getFunction(); - if (!func) { - Fatal() << "TODO: side effects in removed fields in globals\n"; - } - ChildLocalizer localizer(curr, func, *getModule(), getPassOptions()); - replaceCurrent(localizer.getReplacement()); - } + // Localize things so that we can simply remove the operands we no + // longer need. + ChildLocalizer localizer( + curr, getFunction(), *getModule(), getPassOptions()); + replaceCurrent(localizer.getReplacement()); // Remove the unneeded operands. Index removed = 0; @@ -381,6 +365,8 @@ struct GlobalTypeOptimization : public Pass { } } operands.resize(operands.size() - removed); + // We should only get here if we did actual work. + assert(removed > 0); } void visitStructSet(StructSet* curr) { diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 1d662f0ac7e..c5e148afaff 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -589,17 +589,23 @@ ) ;; CHECK: (func $new-side-effect-in-kept (type $3) (param $any (ref any)) + ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.new $struct - ;; CHECK-NEXT: (call $helper0 - ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block (result (ref $struct)) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (call $helper0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.new $struct + ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $new-side-effect-in-kept (param $any (ref any)) - ;; Side effects appear in fields that we do *not* remove. In that case, - ;; we do not need to use locals. + ;; Side effects appear in fields that we do *not* remove. We do not need to + ;; use locals here, but for simplicity we do, and rely on later opts. (drop (struct.new $struct (call $helper0 (i32.const 0)) From fb6ead80296471276f4cee05f920e6fe8aba67c5 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 7 Aug 2024 14:59:17 -0700 Subject: [PATCH 504/553] [FP16] Disable float 16 fuzzing for now. (#6822) --- scripts/fuzz_opt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 77fc664c94a..a4adb7b7910 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -294,6 +294,8 @@ def is_git_repo(): INITIAL_CONTENTS_IGNORE = [ + # Float16 is still experimental. + 'f16.wast', # not all relaxed SIMD instructions are implemented in the interpreter 'relaxed-simd.wast', # TODO: fuzzer and interpreter support for strings From 2397f2af4512c31e1e54c0e0168302ab1ee06d58 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 7 Aug 2024 20:49:55 -0400 Subject: [PATCH 505/553] Add a utility for comparing and hashing rec group shapes (#6808) This is very similar to the internal utilities for canonicalizing rec groups in the type system implementation, except that the new utility also supports ordered comparison of rec groups, and of course the new utility only uses the public type API. A follow-up PR will replace the internal implementation of rec group comparison and hashing in the type system with this one. Another follow-up PR will use this new utility in a type optimization. --- src/tools/wasm-fuzz-types.cpp | 94 +++++++++ src/wasm-type-shape.h | 74 ++++++++ src/wasm-type.h | 2 + src/wasm/CMakeLists.txt | 1 + src/wasm/wasm-type-shape.cpp | 348 ++++++++++++++++++++++++++++++++++ 5 files changed, 519 insertions(+) create mode 100644 src/wasm-type-shape.h create mode 100644 src/wasm/wasm-type-shape.cpp diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp index ecd8883b118..074d235c90f 100644 --- a/src/tools/wasm-fuzz-types.cpp +++ b/src/tools/wasm-fuzz-types.cpp @@ -23,6 +23,7 @@ #include "tools/fuzzing/heap-types.h" #include "tools/fuzzing/random.h" #include "wasm-type-printing.h" +#include "wasm-type-shape.h" namespace wasm { @@ -54,6 +55,7 @@ struct Fuzzer { void checkLUBs() const; void checkCanonicalization(); void checkInhabitable(); + void checkRecGroupShapes(); }; void Fuzzer::run(uint64_t seed) { @@ -88,6 +90,7 @@ void Fuzzer::run(uint64_t seed) { checkLUBs(); checkCanonicalization(); checkInhabitable(); + checkRecGroupShapes(); } void Fuzzer::printTypes(const std::vector& types) { @@ -509,6 +512,97 @@ void Fuzzer::checkInhabitable() { } } +void Fuzzer::checkRecGroupShapes() { + using ShapeHash = std::hash; + + // Collect the groups and order types by index. + std::vector> groups; + std::unordered_map typeIndices; + for (auto type : types) { + typeIndices.insert({type, typeIndices.size()}); + // We know we are at the beginning of a new rec group when we see a type + // that is at index zero of its rec group. + if (type.getRecGroupIndex() == 0) { + groups.push_back({type}); + } else { + assert(!groups.empty()); + groups.back().push_back(type); + } + } + + auto less = [&typeIndices](HeapType a, HeapType b) { + return typeIndices.at(a) < typeIndices.at(b); + }; + + for (size_t i = 0; i < groups.size(); ++i) { + ComparableRecGroupShape shape(groups[i], less); + // A rec group should compare equal to itself. + if (shape != shape) { + Fatal() << "Rec group shape " << i << " not equal to itself"; + } + + // Its hash should be deterministic + auto hash = ShapeHash{}(shape); + if (hash != ShapeHash{}(shape)) { + Fatal() << "Rec group shape " << i << " has non-deterministic hash"; + } + + // Check how it compares to other groups. + for (size_t j = i + 1; j < groups.size(); ++j) { + ComparableRecGroupShape other(groups[j], less); + bool isLess = shape < other; + bool isEq = shape == other; + bool isGreater = shape > other; + if (isLess + isEq + isGreater == 0) { + Fatal() << "Rec groups " << i << " and " << j + << " do not have comparable shapes"; + } + if (isLess + isEq + isGreater > 1) { + std::string comparisons; + auto append = [&](std::string comp) { + comparisons = comparisons == "" ? comp : comparisons + ", " + comp; + }; + if (isLess) { + append("<"); + } + if (isEq) { + append("=="); + } + if (isGreater) { + append(">"); + } + Fatal() << "Rec groups " << i << " and " << j << " compare " + << comparisons; + } + + auto otherHash = ShapeHash{}(other); + if (isEq) { + if (hash != otherHash) { + Fatal() << "Equivalent rec groups " << i << " and " << j + << " do not have equivalent hashes"; + } + } else { + // Hash collisions are technically possible, but should be rare enough + // that we can consider them bugs if the fuzzer finds them. + if (hash == otherHash) { + Fatal() << "Hash collision between rec groups " << i << " and " << j; + } + } + + if (j + 1 < groups.size()) { + // Check transitivity. + RecGroupShape third(groups[j + 1]); + if ((isLess && other <= third && shape >= third) || + (isEq && other == third && shape != third) || + (isGreater && other >= third && shape <= third)) { + Fatal() << "Comparison between rec groups " << i << ", " << j + << ", and " << (j + 1) << " is not transitive"; + } + } + } + } +} + } // namespace wasm int main(int argc, const char* argv[]) { diff --git a/src/wasm-type-shape.h b/src/wasm-type-shape.h new file mode 100644 index 00000000000..5eb4250f0df --- /dev/null +++ b/src/wasm-type-shape.h @@ -0,0 +1,74 @@ +/* + * Copyright 2024 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. + */ + +#ifndef wasm_wasm_type_shape_h +#define wasm_wasm_type_shape_h + +#include +#include + +#include "wasm-type.h" + +namespace wasm { + +// Provides hashing and equality comparison for a sequence of types. The hashing +// and equality differentiate the top-level structure of each type in the +// sequence and the equality of referenced heap types that are not in the +// recursion group, but for references to types that are in the recursion group, +// it considers only the index of the referenced type within the group. That +// means that recursion groups containing different types can compare and hash +// as equal as long as their internal structure and external references are the +// same. +struct RecGroupShape { + const std::vector& types; + + RecGroupShape(const std::vector& types) : types(types) {} + + bool operator==(const RecGroupShape& other) const; + bool operator!=(const RecGroupShape& other) const { + return !(*this == other); + } +}; + +// Extends `RecGroupShape` with ordered comparison of rec group structures. +// Requires the user to supply a global ordering on heap types to be able to +// compare differing references to external types. +// TODO: This can all be upgraded to use C++20 three-way comparisons. +struct ComparableRecGroupShape : RecGroupShape { + std::function less; + + ComparableRecGroupShape(const std::vector& types, + std::function less) + : RecGroupShape(types), less(less) {} + + bool operator<(const RecGroupShape& other) const; + bool operator>(const RecGroupShape& other) const; + bool operator<=(const RecGroupShape& other) const { return !(*this > other); } + bool operator>=(const RecGroupShape& other) const { return !(*this < other); } +}; + +} // namespace wasm + +namespace std { + +template<> class hash { +public: + size_t operator()(const wasm::RecGroupShape& shape) const; +}; + +} // namespace std + +#endif // wasm_wasm_type_shape_h diff --git a/src/wasm-type.h b/src/wasm-type.h index 88590cc17b8..e2eec5f3523 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -434,6 +434,8 @@ class HeapType { // Get the recursion group for this non-basic type. RecGroup getRecGroup() const; + + // Get the index of this non-basic type within its recursion group. size_t getRecGroupIndex() const; constexpr TypeID getID() const { return id; } diff --git a/src/wasm/CMakeLists.txt b/src/wasm/CMakeLists.txt index 16b6d8aed2a..7a7b26eaddc 100644 --- a/src/wasm/CMakeLists.txt +++ b/src/wasm/CMakeLists.txt @@ -12,6 +12,7 @@ set(wasm_SOURCES wasm-stack.cpp wasm-stack-opts.cpp wasm-type.cpp + wasm-type-shape.cpp wasm-validator.cpp ${wasm_HEADERS} ) diff --git a/src/wasm/wasm-type-shape.cpp b/src/wasm/wasm-type-shape.cpp new file mode 100644 index 00000000000..99398bb7b71 --- /dev/null +++ b/src/wasm/wasm-type-shape.cpp @@ -0,0 +1,348 @@ +/* + * Copyright 2024 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-type-shape.h" +#include "support/hash.h" +#include "wasm-type.h" + +namespace wasm { + +namespace { + +enum Comparison { EQ, LT, GT }; + +template struct RecGroupComparator { + std::unordered_map indicesA; + std::unordered_map indicesB; + CompareTypes compareTypes; + + RecGroupComparator(CompareTypes compareTypes) : compareTypes(compareTypes) {} + + Comparison compare(const RecGroupShape& a, const RecGroupShape& b) { + if (a.types.size() != b.types.size()) { + return a.types.size() < b.types.size() ? LT : GT; + } + // Initialize index maps. + for (auto type : a.types) { + indicesA.insert({type, indicesA.size()}); + } + for (auto type : b.types) { + indicesB.insert({type, indicesB.size()}); + } + // Compare types until we find a difference. + for (size_t i = 0; i < a.types.size(); ++i) { + auto cmp = compareDefinition(a.types[i], b.types[i]); + if (cmp == EQ) { + continue; + } + return cmp; + } + // Never found a difference. + return EQ; + } + + Comparison compareDefinition(HeapType a, HeapType b) { + if (a.isShared() != b.isShared()) { + return a.isShared() < b.isShared() ? LT : GT; + } + if (a.isOpen() != b.isOpen()) { + return a.isOpen() < b.isOpen() ? LT : GT; + } + auto aSuper = a.getDeclaredSuperType(); + auto bSuper = b.getDeclaredSuperType(); + if (aSuper.has_value() != bSuper.has_value()) { + return aSuper.has_value() < bSuper.has_value() ? LT : GT; + } + if (aSuper) { + if (auto cmp = compare(*aSuper, *bSuper); cmp != EQ) { + return cmp; + } + } + auto aKind = a.getKind(); + auto bKind = b.getKind(); + if (aKind != bKind) { + return aKind < bKind ? LT : GT; + } + switch (aKind) { + case HeapTypeKind::Func: + return compare(a.getSignature(), b.getSignature()); + case HeapTypeKind::Struct: + return compare(a.getStruct(), b.getStruct()); + case HeapTypeKind::Array: + return compare(a.getArray(), b.getArray()); + case HeapTypeKind::Cont: + return compare(a.getContinuation(), b.getContinuation()); + case HeapTypeKind::Basic: + break; + } + WASM_UNREACHABLE("unexpected kind"); + } + + Comparison compare(Signature a, Signature b) { + if (auto cmp = compare(a.params, b.params); cmp != EQ) { + return cmp; + } + return compare(a.results, b.results); + } + + Comparison compare(const Struct& a, const Struct& b) { + if (a.fields.size() != b.fields.size()) { + return a.fields.size() < b.fields.size() ? LT : GT; + } + for (size_t i = 0; i < a.fields.size(); ++i) { + if (auto cmp = compare(a.fields[i], b.fields[i]); cmp != EQ) { + return cmp; + } + } + return EQ; + } + + Comparison compare(Array a, Array b) { return compare(a.element, b.element); } + + Comparison compare(Continuation a, Continuation b) { + return compare(a.type, b.type); + } + + Comparison compare(Field a, Field b) { + if (a.mutable_ != b.mutable_) { + return a.mutable_ < b.mutable_ ? LT : GT; + } + if (a.isPacked() != b.isPacked()) { + return b.isPacked() < a.isPacked() ? LT : GT; + } + if (a.packedType != b.packedType) { + return a.packedType < b.packedType ? LT : GT; + } + return compare(a.type, b.type); + } + + Comparison compare(Type a, Type b) { + if (a.isBasic() != b.isBasic()) { + return b.isBasic() < a.isBasic() ? LT : GT; + } + if (a.isBasic()) { + if (a.getBasic() != b.getBasic()) { + return a.getBasic() < b.getBasic() ? LT : GT; + } + return EQ; + } + if (a.isTuple() != b.isTuple()) { + return a.isTuple() < b.isTuple() ? LT : GT; + } + if (a.isTuple()) { + return compare(a.getTuple(), b.getTuple()); + } + assert(a.isRef() && b.isRef()); + if (a.isNullable() != b.isNullable()) { + return a.isNullable() < b.isNullable() ? LT : GT; + } + return compare(a.getHeapType(), b.getHeapType()); + } + + Comparison compare(const Tuple& a, const Tuple& b) { + if (a.size() != b.size()) { + return a.size() < b.size() ? LT : GT; + } + for (size_t i = 0; i < a.size(); ++i) { + if (auto cmp = compare(a[i], b[i]); cmp != EQ) { + return cmp; + } + } + return EQ; + } + + Comparison compare(HeapType a, HeapType b) { + if (a.isBasic() != b.isBasic()) { + return b.isBasic() < a.isBasic() ? LT : GT; + } + if (a.isBasic()) { + if (a.getID() != b.getID()) { + return a.getID() < b.getID() ? LT : GT; + } + return EQ; + } + auto itA = indicesA.find(a); + auto itB = indicesB.find(b); + bool foundA = itA != indicesA.end(); + bool foundB = itB != indicesB.end(); + if (foundA != foundB) { + return foundB < foundA ? LT : GT; + } + if (foundA) { + auto indexA = itA->second; + auto indexB = itB->second; + if (indexA != indexB) { + return indexA < indexB ? LT : GT; + } + } + // These types are external to the group, so fall back to the provided + // comparator. + return compareTypes(a, b); + } +}; + +// Deduction guide to satisfy -Wctad-maybe-unsupported. +template +RecGroupComparator(CompareTypes) -> RecGroupComparator; + +struct RecGroupHasher { + std::unordered_map typeIndices; + + size_t hash(const RecGroupShape& shape) { + for (auto type : shape.types) { + typeIndices.insert({type, typeIndices.size()}); + } + size_t digest = wasm::hash(shape.types.size()); + for (auto type : shape.types) { + hash_combine(digest, hashDefinition(type)); + } + return digest; + } + + size_t hashDefinition(HeapType type) { + size_t digest = wasm::hash(type.isShared()); + wasm::rehash(digest, type.isOpen()); + auto super = type.getDeclaredSuperType(); + wasm::rehash(digest, super.has_value()); + if (super) { + hash_combine(digest, hash(*super)); + } + auto kind = type.getKind(); + // Mix in very random numbers to differentiate the kinds. + switch (kind) { + case HeapTypeKind::Func: + wasm::rehash(digest, 1904683903); + hash_combine(digest, hash(type.getSignature())); + return digest; + case HeapTypeKind::Struct: + wasm::rehash(digest, 3273309159); + hash_combine(digest, hash(type.getStruct())); + return digest; + case HeapTypeKind::Array: + wasm::rehash(digest, 4254688366); + hash_combine(digest, hash(type.getArray())); + return digest; + case HeapTypeKind::Cont: + wasm::rehash(digest, 2381496927); + hash_combine(digest, hash(type.getContinuation())); + return digest; + case HeapTypeKind::Basic: + break; + } + WASM_UNREACHABLE("unexpected kind"); + } + + size_t hash(Signature sig) { + size_t digest = hash(sig.params); + hash_combine(digest, hash(sig.results)); + return digest; + } + + size_t hash(const Struct& struct_) { + size_t digest = wasm::hash(struct_.fields.size()); + for (auto field : struct_.fields) { + hash_combine(digest, hash(field)); + } + return digest; + } + + size_t hash(Array array) { return hash(array.element); } + + size_t hash(Continuation cont) { return hash(cont.type); } + + size_t hash(Field field) { + size_t digest = wasm::hash(field.mutable_); + wasm::rehash(digest, field.packedType); + hash_combine(digest, hash(field.type)); + return digest; + } + + size_t hash(Type type) { + size_t digest = wasm::hash(type.isBasic()); + if (type.isBasic()) { + wasm::rehash(digest, type.getBasic()); + return digest; + } + wasm::rehash(digest, type.isTuple()); + if (type.isTuple()) { + hash_combine(digest, hash(type.getTuple())); + return digest; + } + assert(type.isRef()); + wasm::rehash(digest, type.isNullable()); + hash_combine(digest, hash(type.getHeapType())); + return digest; + } + + size_t hash(const Tuple& tuple) { + size_t digest = wasm::hash(tuple.size()); + for (auto type : tuple) { + hash_combine(digest, hash(type)); + } + return digest; + } + + size_t hash(HeapType type) { + size_t digest = wasm::hash(type.isBasic()); + if (type.isBasic()) { + wasm::rehash(digest, type.getID()); + return digest; + } + auto it = typeIndices.find(type); + wasm::rehash(digest, it != typeIndices.end()); + if (it != typeIndices.end()) { + wasm::rehash(digest, it->second); + return digest; + } + wasm::rehash(digest, type.getID()); + return digest; + } +}; + +Comparison compareComparable(const ComparableRecGroupShape& a, + const RecGroupShape& b) { + return RecGroupComparator{[&](HeapType ht1, HeapType ht2) { + return a.less(ht1, ht2) ? LT : a.less(ht2, ht1) ? GT : EQ; + }} + .compare(a, b); +} + +} // anonymous namespace + +bool RecGroupShape::operator==(const RecGroupShape& other) const { + return EQ == RecGroupComparator{[](HeapType a, HeapType b) { + return a == b ? EQ : LT; + }}.compare(*this, other); +} + +bool ComparableRecGroupShape::operator<(const RecGroupShape& other) const { + return LT == compareComparable(*this, other); +} + +bool ComparableRecGroupShape::operator>(const RecGroupShape& other) const { + return GT == compareComparable(*this, other); +} + +} // namespace wasm + +namespace std { + +size_t +hash::operator()(const wasm::RecGroupShape& shape) const { + return wasm::RecGroupHasher{}.hash(shape); +} + +} // namespace std From c9fd92c25a74a70c9730f1b39b49ef3d91a1a7f1 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 7 Aug 2024 21:45:34 -0400 Subject: [PATCH 506/553] Simplify TopologicalOrders (#6811) Make `TopologicalOrders` its own iterator rather than having a separate iterator class that wraps a pointer to `TopologicalOrders`. This simplifies usage in cases where an iterator needs to be persistently stored. Notably, all of the tests continue working as they are. --- src/support/topological_orders.cpp | 6 ++-- src/support/topological_orders.h | 44 ++++++++++++------------------ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/support/topological_orders.cpp b/src/support/topological_orders.cpp index 939c76c6e44..145ba30043d 100644 --- a/src/support/topological_orders.cpp +++ b/src/support/topological_orders.cpp @@ -95,7 +95,7 @@ TopologicalOrders::TopologicalOrders( } } -void TopologicalOrders::advance() { +TopologicalOrders& TopologicalOrders::operator++() { // Find the last selector that can be advanced, popping any that cannot. std::optional next; while (!selectors.empty() && !(next = selectors.back().advance(*this))) { @@ -104,7 +104,7 @@ void TopologicalOrders::advance() { if (!next) { // No selector could be advanced, so we've seen every possible ordering. assert(selectors.empty()); - return; + return *this; } // We've advanced the last selector on the stack, so initialize the // subsequent selectors. @@ -113,6 +113,8 @@ void TopologicalOrders::advance() { while (selectors.size() < graph.size()) { selectors.push_back(selectors.back().select(*this)); } + + return *this; } } // namespace wasm diff --git a/src/support/topological_orders.h b/src/support/topological_orders.h index acab78ee5f5..48941c02133 100644 --- a/src/support/topological_orders.h +++ b/src/support/topological_orders.h @@ -28,35 +28,29 @@ namespace wasm { // https://en.wikipedia.org/wiki/Topological_sorting) that iteratively makes all // possible choices for each position of the output order. struct TopologicalOrders { + using value_type = const std::vector; + using difference_type = std::ptrdiff_t; + using reference = const std::vector&; + using pointer = const std::vector*; + using iterator_category = std::input_iterator_tag; + // Takes an adjacency list, where the list for each vertex is a sorted list of // the indices of its children, which will appear after it in the order. TopologicalOrders(const std::vector>& graph); - struct Iterator { - using value_type = const std::vector; - using difference_type = std::ptrdiff_t; - using reference = const std::vector&; - using pointer = const std::vector*; - using iterator_category = std::input_iterator_tag; - - TopologicalOrders* parent; + TopologicalOrders begin() { return TopologicalOrders(graph); } + TopologicalOrders end() { return TopologicalOrders({}); } - bool isEnd() const { return !parent || parent->selectors.empty(); } - bool operator==(const Iterator& other) const { - return isEnd() == other.isEnd(); - } - bool operator!=(const Iterator& other) const { return !(*this == other); } - const std::vector& operator*() { return parent->buf; } - const std::vector* operator->() { return &parent->buf; } - Iterator& operator++() { - parent->advance(); - return *this; - } - Iterator operator++(int) { return ++(*this); } - }; - - Iterator begin() { return {this}; } - Iterator end() { return {nullptr}; } + bool operator==(const TopologicalOrders& other) const { + return selectors.empty() == other.selectors.empty(); + } + bool operator!=(const TopologicalOrders& other) const { + return !(*this == other); + } + const std::vector& operator*() { return buf; } + const std::vector* operator->() { return &buf; } + TopologicalOrders& operator++(); + TopologicalOrders operator++(int) { return ++(*this); } private: // The input graph given as an adjacency list with edges from vertices to @@ -95,8 +89,6 @@ struct TopologicalOrders { // A stack of selectors, one for each vertex in a complete topological order. // Empty if we've already seen every possible ordering. std::vector selectors; - - void advance(); }; } // namespace wasm From d945aa489a1ad62c130e04ceea8492c7a728ab57 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Thu, 8 Aug 2024 10:22:51 -0700 Subject: [PATCH 507/553] [FP16] Implement lane access instructions. (#6821) Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md --- scripts/gen-s-parser.py | 3 ++ src/gen-s-parser.inc | 23 +++++++++ src/ir/child-typer.h | 2 + src/ir/cost.h | 1 + src/literal.h | 4 ++ src/passes/Print.cpp | 9 ++++ src/tools/fuzzing/fuzzing.cpp | 1 + src/wasm-binary.h | 3 ++ src/wasm-interpreter.h | 6 +++ src/wasm.h | 5 ++ src/wasm/literal.cpp | 19 ++++++++ src/wasm/wasm-binary.cpp | 14 ++++++ src/wasm/wasm-stack.cpp | 9 ++++ src/wasm/wasm-validator.cpp | 9 ++++ src/wasm/wasm.cpp | 2 + test/lit/basic/f16.wast | 89 +++++++++++++++++++++++++++++++++++ test/spec/f16.wast | 12 +++++ 17 files changed, 211 insertions(+) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index f3510964482..9519ad4eeae 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -298,6 +298,9 @@ ("i64x2.splat", "makeUnary(UnaryOp::SplatVecI64x2)"), ("i64x2.extract_lane", "makeSIMDExtract(SIMDExtractOp::ExtractLaneVecI64x2, 2)"), ("i64x2.replace_lane", "makeSIMDReplace(SIMDReplaceOp::ReplaceLaneVecI64x2, 2)"), + ("f16x8.splat", "makeUnary(UnaryOp::SplatVecF16x8)"), + ("f16x8.extract_lane", "makeSIMDExtract(SIMDExtractOp::ExtractLaneVecF16x8, 8)"), + ("f16x8.replace_lane", "makeSIMDReplace(SIMDReplaceOp::ReplaceLaneVecF16x8, 8)"), ("f32x4.splat", "makeUnary(UnaryOp::SplatVecF32x4)"), ("f32x4.extract_lane", "makeSIMDExtract(SIMDExtractOp::ExtractLaneVecF32x4, 4)"), ("f32x4.replace_lane", "makeSIMDReplace(SIMDReplaceOp::ReplaceLaneVecF32x4, 4)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index c54a0de54b1..33cddcb26b7 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -307,6 +307,29 @@ switch (buf[0]) { } case 'f': { switch (buf[1]) { + case '1': { + switch (buf[6]) { + case 'e': + if (op == "f16x8.extract_lane"sv) { + CHECK_ERR(makeSIMDExtract(ctx, pos, annotations, SIMDExtractOp::ExtractLaneVecF16x8, 8)); + return Ok{}; + } + goto parse_error; + case 'r': + if (op == "f16x8.replace_lane"sv) { + CHECK_ERR(makeSIMDReplace(ctx, pos, annotations, SIMDReplaceOp::ReplaceLaneVecF16x8, 8)); + return Ok{}; + } + goto parse_error; + case 's': + if (op == "f16x8.splat"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SplatVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } case '3': { switch (buf[3]) { case '.': { diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 5e2dc237dfc..17717a32c14 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -228,6 +228,7 @@ template struct ChildTyper : OverriddenVisitor { case ReplaceLaneVecI64x2: note(&curr->value, Type::i64); break; + case ReplaceLaneVecF16x8: case ReplaceLaneVecF32x4: note(&curr->value, Type::f32); break; @@ -337,6 +338,7 @@ template struct ChildTyper : OverriddenVisitor { case TruncSatUFloat32ToInt64: case ReinterpretFloat32: case PromoteFloat32: + case SplatVecF16x8: case SplatVecF32x4: note(&curr->value, Type::f32); break; diff --git a/src/ir/cost.h b/src/ir/cost.h index 38c74a2037c..06512d656de 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -184,6 +184,7 @@ struct CostAnalyzer : public OverriddenVisitor { case SplatVecI16x8: case SplatVecI32x4: case SplatVecI64x2: + case SplatVecF16x8: case SplatVecF32x4: case SplatVecF64x2: case NotVec128: diff --git a/src/literal.h b/src/literal.h index 190fe0eeced..63bbf6e7481 100644 --- a/src/literal.h +++ b/src/literal.h @@ -444,6 +444,7 @@ class Literal { std::array getLanesUI16x8() const; std::array getLanesI32x4() const; std::array getLanesI64x2() const; + std::array getLanesF16x8() const; std::array getLanesF32x4() const; std::array getLanesF64x2() const; @@ -463,6 +464,9 @@ class Literal { Literal splatI64x2() const; Literal extractLaneI64x2(uint8_t index) const; Literal replaceLaneI64x2(const Literal& other, uint8_t index) const; + Literal splatF16x8() const; + Literal extractLaneF16x8(uint8_t index) const; + Literal replaceLaneF16x8(const Literal& other, uint8_t index) const; Literal splatF32x4() const; Literal extractLaneF32x4(uint8_t index) const; Literal replaceLaneF32x4(const Literal& other, uint8_t index) const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index aca43924d34..fd22f1b716f 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -703,6 +703,9 @@ struct PrintExpressionContents case ExtractLaneVecI64x2: o << "i64x2.extract_lane"; break; + case ExtractLaneVecF16x8: + o << "f16x8.extract_lane"; + break; case ExtractLaneVecF32x4: o << "f32x4.extract_lane"; break; @@ -728,6 +731,9 @@ struct PrintExpressionContents case ReplaceLaneVecI64x2: o << "i64x2.replace_lane"; break; + case ReplaceLaneVecF16x8: + o << "f16x8.replace_lane"; + break; case ReplaceLaneVecF32x4: o << "f32x4.replace_lane"; break; @@ -1137,6 +1143,9 @@ struct PrintExpressionContents case SplatVecI64x2: o << "i64x2.splat"; break; + case SplatVecF16x8: + o << "f16x8.splat"; + break; case SplatVecF32x4: o << "f32x4.splat"; break; diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 2aff7146e28..fd0dfb26c25 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -3579,6 +3579,7 @@ Expression* TranslateToFuzzReader::makeSIMDExtract(Type type) { break; case ExtractLaneSVecI16x8: case ExtractLaneUVecI16x8: + case ExtractLaneVecF16x8: index = upTo(8); break; case ExtractLaneVecI32x4: diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 5fae1b64d7b..38bf5d475a4 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1054,6 +1054,9 @@ enum ASTNodes { // half precision opcodes F32_F16LoadMem = 0x30, F32_F16StoreMem = 0x31, + F16x8Splat = 0x120, + F16x8ExtractLane = 0x121, + F16x8ReplaceLane = 0x122, // bulk memory opcodes diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 3e62d53354a..f59a005b645 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -479,6 +479,8 @@ class ExpressionRunner : public OverriddenVisitor { return value.splatI32x4(); case SplatVecI64x2: return value.splatI64x2(); + case SplatVecF16x8: + return value.splatF16x8(); case SplatVecF32x4: return value.splatF32x4(); case SplatVecF64x2: @@ -1070,6 +1072,8 @@ class ExpressionRunner : public OverriddenVisitor { return vec.extractLaneI32x4(curr->index); case ExtractLaneVecI64x2: return vec.extractLaneI64x2(curr->index); + case ExtractLaneVecF16x8: + return vec.extractLaneF16x8(curr->index); case ExtractLaneVecF32x4: return vec.extractLaneF32x4(curr->index); case ExtractLaneVecF64x2: @@ -1098,6 +1102,8 @@ class ExpressionRunner : public OverriddenVisitor { return vec.replaceLaneI32x4(value, curr->index); case ReplaceLaneVecI64x2: return vec.replaceLaneI64x2(value, curr->index); + case ReplaceLaneVecF16x8: + return vec.replaceLaneF16x8(value, curr->index); case ReplaceLaneVecF32x4: return vec.replaceLaneF32x4(value, curr->index); case ReplaceLaneVecF64x2: diff --git a/src/wasm.h b/src/wasm.h index 4a4ed561f91..56e94fef78b 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -229,6 +229,9 @@ enum UnaryOp { RelaxedTruncZeroSVecF64x2ToVecI32x4, RelaxedTruncZeroUVecF64x2ToVecI32x4, + // Half precision SIMD + SplatVecF16x8, + InvalidUnary }; @@ -490,6 +493,7 @@ enum SIMDExtractOp { ExtractLaneUVecI16x8, ExtractLaneVecI32x4, ExtractLaneVecI64x2, + ExtractLaneVecF16x8, ExtractLaneVecF32x4, ExtractLaneVecF64x2 }; @@ -499,6 +503,7 @@ enum SIMDReplaceOp { ReplaceLaneVecI16x8, ReplaceLaneVecI32x4, ReplaceLaneVecI64x2, + ReplaceLaneVecF16x8, ReplaceLaneVecF32x4, ReplaceLaneVecF64x2, }; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index f2100ea712e..a532b92d002 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -20,6 +20,7 @@ #include #include "emscripten-optimizer/simple_ast.h" +#include "fp16.h" #include "ir/bits.h" #include "pretty_printing.h" #include "support/bits.h" @@ -1729,6 +1730,13 @@ LaneArray<4> Literal::getLanesI32x4() const { LaneArray<2> Literal::getLanesI64x2() const { return getLanes(*this); } +LaneArray<8> Literal::getLanesF16x8() const { + auto lanes = getLanesUI16x8(); + for (size_t i = 0; i < lanes.size(); ++i) { + lanes[i] = Literal(fp16_ieee_to_fp32_value(lanes[i].geti32())); + } + return lanes; +} LaneArray<4> Literal::getLanesF32x4() const { auto lanes = getLanesI32x4(); for (size_t i = 0; i < lanes.size(); ++i) { @@ -1766,6 +1774,10 @@ Literal Literal::splatI8x16() const { return splat(*this); } Literal Literal::splatI16x8() const { return splat(*this); } Literal Literal::splatI32x4() const { return splat(*this); } Literal Literal::splatI64x2() const { return splat(*this); } +Literal Literal::splatF16x8() const { + uint16_t f16 = fp16_ieee_from_fp32_value(getf32()); + return splat(Literal(f16)); +} Literal Literal::splatF32x4() const { return splat(*this); } Literal Literal::splatF64x2() const { return splat(*this); } @@ -1787,6 +1799,9 @@ Literal Literal::extractLaneI32x4(uint8_t index) const { Literal Literal::extractLaneI64x2(uint8_t index) const { return getLanesI64x2().at(index); } +Literal Literal::extractLaneF16x8(uint8_t index) const { + return getLanesF16x8().at(index); +} Literal Literal::extractLaneF32x4(uint8_t index) const { return getLanesF32x4().at(index); } @@ -1815,6 +1830,10 @@ Literal Literal::replaceLaneI32x4(const Literal& other, uint8_t index) const { Literal Literal::replaceLaneI64x2(const Literal& other, uint8_t index) const { return replace<2, &Literal::getLanesI64x2>(*this, other, index); } +Literal Literal::replaceLaneF16x8(const Literal& other, uint8_t index) const { + return replace<8, &Literal::getLanesF16x8>( + *this, Literal(fp16_ieee_from_fp32_value(other.getf32())), index); +} Literal Literal::replaceLaneF32x4(const Literal& other, uint8_t index) const { return replace<4, &Literal::getLanesF32x4>(*this, other, index); } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b9645ab8fec..5eaa8451510 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6239,6 +6239,10 @@ bool WasmBinaryReader::maybeVisitSIMDUnary(Expression*& out, uint32_t code) { curr = allocator.alloc(); curr->op = SplatVecI64x2; break; + case BinaryConsts::F16x8Splat: + curr = allocator.alloc(); + curr->op = SplatVecF16x8; + break; case BinaryConsts::F32x4Splat: curr = allocator.alloc(); curr->op = SplatVecF32x4; @@ -6569,6 +6573,11 @@ bool WasmBinaryReader::maybeVisitSIMDExtract(Expression*& out, uint32_t code) { curr->op = ExtractLaneVecI64x2; curr->index = getLaneIndex(2); break; + case BinaryConsts::F16x8ExtractLane: + curr = allocator.alloc(); + curr->op = ExtractLaneVecF16x8; + curr->index = getLaneIndex(8); + break; case BinaryConsts::F32x4ExtractLane: curr = allocator.alloc(); curr->op = ExtractLaneVecF32x4; @@ -6611,6 +6620,11 @@ bool WasmBinaryReader::maybeVisitSIMDReplace(Expression*& out, uint32_t code) { curr->op = ReplaceLaneVecI64x2; curr->index = getLaneIndex(2); break; + case BinaryConsts::F16x8ReplaceLane: + curr = allocator.alloc(); + curr->op = ReplaceLaneVecF16x8; + curr->index = getLaneIndex(8); + break; case BinaryConsts::F32x4ReplaceLane: curr = allocator.alloc(); curr->op = ReplaceLaneVecF32x4; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 35db3b32250..19b98769b56 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -590,6 +590,9 @@ void BinaryInstWriter::visitSIMDExtract(SIMDExtract* curr) { case ExtractLaneVecI64x2: o << U32LEB(BinaryConsts::I64x2ExtractLane); break; + case ExtractLaneVecF16x8: + o << U32LEB(BinaryConsts::F16x8ExtractLane); + break; case ExtractLaneVecF32x4: o << U32LEB(BinaryConsts::F32x4ExtractLane); break; @@ -615,6 +618,9 @@ void BinaryInstWriter::visitSIMDReplace(SIMDReplace* curr) { case ReplaceLaneVecI64x2: o << U32LEB(BinaryConsts::I64x2ReplaceLane); break; + case ReplaceLaneVecF16x8: + o << U32LEB(BinaryConsts::F16x8ReplaceLane); + break; case ReplaceLaneVecF32x4: o << U32LEB(BinaryConsts::F32x4ReplaceLane); break; @@ -1050,6 +1056,9 @@ void BinaryInstWriter::visitUnary(Unary* curr) { case SplatVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Splat); break; + case SplatVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Splat); + break; case SplatVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Splat); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index b3291743225..6e59ce8d81b 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1272,6 +1272,10 @@ void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) { lane_t = Type::i64; lanes = 2; break; + case ExtractLaneVecF16x8: + lane_t = Type::f32; + lanes = 8; + break; case ExtractLaneVecF32x4: lane_t = Type::f32; lanes = 4; @@ -1318,6 +1322,10 @@ void FunctionValidator::visitSIMDReplace(SIMDReplace* curr) { lane_t = Type::i64; lanes = 2; break; + case ReplaceLaneVecF16x8: + lane_t = Type::f32; + lanes = 8; + break; case ReplaceLaneVecF32x4: lane_t = Type::f32; lanes = 4; @@ -2036,6 +2044,7 @@ void FunctionValidator::visitUnary(Unary* curr) { shouldBeEqual( curr->value->type, Type(Type::i64), curr, "expected i64 splat value"); break; + case SplatVecF16x8: case SplatVecF32x4: shouldBeEqual( curr->type, Type(Type::v128), curr, "expected splat to have v128 type"); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index b17250e6c6c..ae70e4a2238 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -386,6 +386,7 @@ void SIMDExtract::finalize() { case ExtractLaneVecI64x2: type = Type::i64; break; + case ExtractLaneVecF16x8: case ExtractLaneVecF32x4: type = Type::f32; break; @@ -636,6 +637,7 @@ void Unary::finalize() { case SplatVecI16x8: case SplatVecI32x4: case SplatVecI64x2: + case SplatVecF16x8: case SplatVecF32x4: case SplatVecF64x2: case NotVec128: diff --git a/test/lit/basic/f16.wast b/test/lit/basic/f16.wast index c68b0306f96..1dceb807525 100644 --- a/test/lit/basic/f16.wast +++ b/test/lit/basic/f16.wast @@ -17,6 +17,12 @@ ;; CHECK-TEXT: (type $1 (func (param i32 f32))) + ;; CHECK-TEXT: (type $2 (func (param f32) (result v128))) + + ;; CHECK-TEXT: (type $3 (func (param v128) (result f32))) + + ;; CHECK-TEXT: (type $4 (func (param v128 f32) (result v128))) + ;; CHECK-TEXT: (memory $0 1 1) ;; CHECK-TEXT: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) @@ -28,6 +34,12 @@ ;; CHECK-BIN: (type $1 (func (param i32 f32))) + ;; CHECK-BIN: (type $2 (func (param f32) (result v128))) + + ;; CHECK-BIN: (type $3 (func (param v128) (result f32))) + + ;; CHECK-BIN: (type $4 (func (param v128 f32) (result v128))) + ;; CHECK-BIN: (memory $0 1 1) ;; CHECK-BIN: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) @@ -58,11 +70,69 @@ (local.get $1) ) ) + + ;; CHECK-TEXT: (func $f16x8.splat (type $2) (param $0 f32) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.splat + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.splat (type $2) (param $0 f32) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.splat + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.splat (param $0 f32) (result v128) + (f16x8.splat + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f16x8.extract_lane (type $3) (param $0 v128) (result f32) + ;; CHECK-TEXT-NEXT: (f16x8.extract_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.extract_lane (type $3) (param $0 v128) (result f32) + ;; CHECK-BIN-NEXT: (f16x8.extract_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.extract_lane (param $0 v128) (result f32) + (f16x8.extract_lane 0 + (local.get $0) + ) + ) + + ;; CHECK-TEXT: (func $f16x8.replace_lane (type $4) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.replace_lane 0 + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.replace_lane (type $4) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.replace_lane 0 + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.replace_lane (param $0 v128) (param $1 f32) (result v128) + (f16x8.replace_lane 0 + (local.get $0) + (local.get $1) + ) + ) + ) ;; CHECK-BIN-NODEBUG: (type $0 (func (param i32) (result f32))) ;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f32))) +;; CHECK-BIN-NODEBUG: (type $2 (func (param f32) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $3 (func (param v128) (result f32))) + +;; CHECK-BIN-NODEBUG: (type $4 (func (param v128 f32) (result v128))) + ;; CHECK-BIN-NODEBUG: (memory $0 1 1) ;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (result f32) @@ -77,3 +147,22 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $2 (type $2) (param $0 f32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.splat +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $3 (type $3) (param $0 v128) (result f32) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.extract_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $4 (type $4) (param $0 v128) (param $1 f32) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.replace_lane 0 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/spec/f16.wast b/test/spec/f16.wast index 19bad175674..ef32b2ab545 100644 --- a/test/spec/f16.wast +++ b/test/spec/f16.wast @@ -6,6 +6,11 @@ (func (export "f32.load_f16") (result f32) (f32.load_f16 (i32.const 0))) (func (export "f32.store_f16") (f32.store_f16 (i32.const 0) (f32.const 100.5))) (func (export "i32.load16_u") (result i32) (i32.load16_u (i32.const 2))) + (func (export "f16x8.splat") (param $0 f32) (result v128) (f16x8.splat (local.get $0))) + (func (export "f16x8.extract_lane_first") (param $0 v128) (result f32) (f16x8.extract_lane 0 (local.get $0))) + (func (export "f16x8.extract_lane_last") (param $0 v128) (result f32) (f16x8.extract_lane 7 (local.get $0))) + (func (export "f16x8.replace_lane_first") (param $0 v128) (param $1 f32) (result v128) (f16x8.replace_lane 0 (local.get $0) (local.get $1))) + (func (export "f16x8.replace_lane_last") (param $0 v128) (param $1 f32) (result v128) (f16x8.replace_lane 7 (local.get $0) (local.get $1))) ) (assert_return (invoke "f32.load_f16") (f32.const 42.0)) @@ -13,3 +18,10 @@ (assert_return (invoke "f32.load_f16") (f32.const 100.5)) ;; Ensure that the above operations didn't write to memory they shouldn't have. (assert_return (invoke "i32.load16_u") (i32.const 0xDEAD)) + +;; lane accesses +(assert_return (invoke "f16x8.splat" (f32.const 100.5)) (v128.const i16x8 0x5648 0x5648 0x5648 0x5648 0x5648 0x5648 0x5648 0x5648)) +(assert_return (invoke "f16x8.extract_lane_first" (v128.const i16x8 0x5648 0 0 0 0 0 0 0)) (f32.const 100.5)) +(assert_return (invoke "f16x8.extract_lane_last" (v128.const i16x8 0 0 0 0 0 0 0 0xc500)) (f32.const -5)) +(assert_return (invoke "f16x8.replace_lane_first" (v128.const i64x2 0 0) (f32.const 100.5)) (v128.const i16x8 0x5648 0 0 0 0 0 0 0)) +(assert_return (invoke "f16x8.replace_lane_last" (v128.const i64x2 0 0) (f32.const 100.5)) (v128.const i16x8 0 0 0 0 0 0 0 0x5648)) From b3e22d29451fbf52521d59ea34e8a5d735c4149c Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 9 Aug 2024 09:13:33 -0700 Subject: [PATCH 508/553] [FP16] Implement relation operations. (#6825) Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md --- scripts/gen-s-parser.py | 6 + src/gen-s-parser.inc | 57 ++++++++- src/ir/child-typer.h | 6 + src/ir/cost.h | 6 + src/literal.h | 6 + src/passes/Print.cpp | 18 +++ src/tools/fuzzing/fuzzing.cpp | 7 ++ src/wasm-binary.h | 6 + src/wasm-interpreter.h | 12 ++ src/wasm.h | 6 + src/wasm/literal.cpp | 18 +++ src/wasm/wasm-binary.cpp | 24 ++++ src/wasm/wasm-stack.cpp | 18 +++ src/wasm/wasm-validator.cpp | 6 + test/lit/basic/f16.wast | 216 +++++++++++++++++++++++++++++----- test/spec/f16.wast | 56 +++++++++ 16 files changed, 435 insertions(+), 33 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 9519ad4eeae..3b2eb9d01b4 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -343,6 +343,12 @@ ("i64x2.gt_s", "makeBinary(BinaryOp::GtSVecI64x2)"), ("i64x2.le_s", "makeBinary(BinaryOp::LeSVecI64x2)"), ("i64x2.ge_s", "makeBinary(BinaryOp::GeSVecI64x2)"), + ("f16x8.eq", "makeBinary(BinaryOp::EqVecF16x8)"), + ("f16x8.ne", "makeBinary(BinaryOp::NeVecF16x8)"), + ("f16x8.lt", "makeBinary(BinaryOp::LtVecF16x8)"), + ("f16x8.gt", "makeBinary(BinaryOp::GtVecF16x8)"), + ("f16x8.le", "makeBinary(BinaryOp::LeVecF16x8)"), + ("f16x8.ge", "makeBinary(BinaryOp::GeVecF16x8)"), ("f32x4.eq", "makeBinary(BinaryOp::EqVecF32x4)"), ("f32x4.ne", "makeBinary(BinaryOp::NeVecF32x4)"), ("f32x4.lt", "makeBinary(BinaryOp::LtVecF32x4)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 33cddcb26b7..d6eaf851db9 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -309,9 +309,60 @@ switch (buf[0]) { switch (buf[1]) { case '1': { switch (buf[6]) { - case 'e': - if (op == "f16x8.extract_lane"sv) { - CHECK_ERR(makeSIMDExtract(ctx, pos, annotations, SIMDExtractOp::ExtractLaneVecF16x8, 8)); + case 'e': { + switch (buf[7]) { + case 'q': + if (op == "f16x8.eq"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::EqVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'x': + if (op == "f16x8.extract_lane"sv) { + CHECK_ERR(makeSIMDExtract(ctx, pos, annotations, SIMDExtractOp::ExtractLaneVecF16x8, 8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } + case 'g': { + switch (buf[7]) { + case 'e': + if (op == "f16x8.ge"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::GeVecF16x8)); + return Ok{}; + } + goto parse_error; + case 't': + if (op == "f16x8.gt"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::GtVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } + case 'l': { + switch (buf[7]) { + case 'e': + if (op == "f16x8.le"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::LeVecF16x8)); + return Ok{}; + } + goto parse_error; + case 't': + if (op == "f16x8.lt"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::LtVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } + case 'n': + if (op == "f16x8.ne"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::NeVecF16x8)); return Ok{}; } goto parse_error; diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 17717a32c14..2bfaefafff2 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -558,6 +558,12 @@ template struct ChildTyper : OverriddenVisitor { case LeSVecI64x2: case GtSVecI64x2: case GeSVecI64x2: + case EqVecF16x8: + case NeVecF16x8: + case LtVecF16x8: + case LeVecF16x8: + case GtVecF16x8: + case GeVecF16x8: case EqVecF32x4: case NeVecF32x4: case LtVecF32x4: diff --git a/src/ir/cost.h b/src/ir/cost.h index 06512d656de..ab8ae90ae43 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -398,6 +398,12 @@ struct CostAnalyzer : public OverriddenVisitor { case LeSVecI64x2: case GtSVecI64x2: case GeSVecI64x2: + case EqVecF16x8: + case NeVecF16x8: + case LtVecF16x8: + case LeVecF16x8: + case GtVecF16x8: + case GeVecF16x8: case EqVecF32x4: case NeVecF32x4: case LtVecF32x4: diff --git a/src/literal.h b/src/literal.h index 63bbf6e7481..d247b0c845a 100644 --- a/src/literal.h +++ b/src/literal.h @@ -509,6 +509,12 @@ class Literal { Literal gtSI64x2(const Literal& other) const; Literal leSI64x2(const Literal& other) const; Literal geSI64x2(const Literal& other) const; + Literal eqF16x8(const Literal& other) const; + Literal neF16x8(const Literal& other) const; + Literal ltF16x8(const Literal& other) const; + Literal gtF16x8(const Literal& other) const; + Literal leF16x8(const Literal& other) const; + Literal geF16x8(const Literal& other) const; Literal eqF32x4(const Literal& other) const; Literal neF32x4(const Literal& other) const; Literal ltF32x4(const Literal& other) const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index fd22f1b716f..5c83e89f19f 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1689,6 +1689,24 @@ struct PrintExpressionContents case GeSVecI64x2: o << "i64x2.ge_s"; break; + case EqVecF16x8: + o << "f16x8.eq"; + break; + case NeVecF16x8: + o << "f16x8.ne"; + break; + case LtVecF16x8: + o << "f16x8.lt"; + break; + case GtVecF16x8: + o << "f16x8.gt"; + break; + case LeVecF16x8: + o << "f16x8.le"; + break; + case GeVecF16x8: + o << "f16x8.ge"; + break; case EqVecF32x4: o << "f32x4.eq"; break; diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index fd0dfb26c25..64780696b8f 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -3288,6 +3288,13 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) { LeUVecI32x4, GeSVecI32x4, GeUVecI32x4, + EqVecF16x8, + EqVecF16x8, + NeVecF16x8, + LtVecF16x8, + GtVecF16x8, + LeVecF16x8, + GeVecF16x8, EqVecF32x4, NeVecF32x4, LtVecF32x4, diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 38bf5d475a4..d568abd6c4a 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1057,6 +1057,12 @@ enum ASTNodes { F16x8Splat = 0x120, F16x8ExtractLane = 0x121, F16x8ReplaceLane = 0x122, + F16x8Eq = 0x137, + F16x8Ne = 0x138, + F16x8Lt = 0x139, + F16x8Gt = 0x13a, + F16x8Le = 0x13b, + F16x8Ge = 0x13c, // bulk memory opcodes diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index f59a005b645..7fd5b3cd32a 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -864,6 +864,18 @@ class ExpressionRunner : public OverriddenVisitor { return left.leSI64x2(right); case GeSVecI64x2: return left.geSI64x2(right); + case EqVecF16x8: + return left.eqF16x8(right); + case NeVecF16x8: + return left.neF16x8(right); + case LtVecF16x8: + return left.ltF16x8(right); + case GtVecF16x8: + return left.gtF16x8(right); + case LeVecF16x8: + return left.leF16x8(right); + case GeVecF16x8: + return left.geF16x8(right); case EqVecF32x4: return left.eqF32x4(right); case NeVecF32x4: diff --git a/src/wasm.h b/src/wasm.h index 56e94fef78b..e47b7c6edff 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -381,6 +381,12 @@ enum BinaryOp { GtSVecI64x2, LeSVecI64x2, GeSVecI64x2, + EqVecF16x8, + NeVecF16x8, + LtVecF16x8, + GtVecF16x8, + LeVecF16x8, + GeVecF16x8, EqVecF32x4, NeVecF32x4, LtVecF32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index a532b92d002..b0dcf5177b2 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -2209,6 +2209,24 @@ Literal Literal::geSI64x2(const Literal& other) const { return compare<2, &Literal::getLanesI64x2, &Literal::geS, int64_t>(*this, other); } +Literal Literal::eqF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::eq>(*this, other); +} +Literal Literal::neF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::ne>(*this, other); +} +Literal Literal::ltF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::lt>(*this, other); +} +Literal Literal::gtF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::gt>(*this, other); +} +Literal Literal::leF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::le>(*this, other); +} +Literal Literal::geF16x8(const Literal& other) const { + return compare<8, &Literal::getLanesF16x8, &Literal::ge>(*this, other); +} Literal Literal::eqF32x4(const Literal& other) const { return compare<4, &Literal::getLanesF32x4, &Literal::eq>(*this, other); } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 5eaa8451510..d9985212fe2 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -5846,6 +5846,30 @@ bool WasmBinaryReader::maybeVisitSIMDBinary(Expression*& out, uint32_t code) { curr = allocator.alloc(); curr->op = GeSVecI64x2; break; + case BinaryConsts::F16x8Eq: + curr = allocator.alloc(); + curr->op = EqVecF16x8; + break; + case BinaryConsts::F16x8Ne: + curr = allocator.alloc(); + curr->op = NeVecF16x8; + break; + case BinaryConsts::F16x8Lt: + curr = allocator.alloc(); + curr->op = LtVecF16x8; + break; + case BinaryConsts::F16x8Gt: + curr = allocator.alloc(); + curr->op = GtVecF16x8; + break; + case BinaryConsts::F16x8Le: + curr = allocator.alloc(); + curr->op = LeVecF16x8; + break; + case BinaryConsts::F16x8Ge: + curr = allocator.alloc(); + curr->op = GeVecF16x8; + break; case BinaryConsts::F32x4Eq: curr = allocator.alloc(); curr->op = EqVecF32x4; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 19b98769b56..a9b582f43ed 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1643,6 +1643,24 @@ void BinaryInstWriter::visitBinary(Binary* curr) { case GeSVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2GeS); break; + case EqVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Eq); + break; + case NeVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Ne); + break; + case LtVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Lt); + break; + case GtVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Gt); + break; + case LeVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Le); + break; + case GeVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Ge); + break; case EqVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Eq); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 6e59ce8d81b..b35d1b3bed7 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1743,6 +1743,12 @@ void FunctionValidator::visitBinary(Binary* curr) { case LeSVecI64x2: case GtSVecI64x2: case GeSVecI64x2: + case EqVecF16x8: + case NeVecF16x8: + case LtVecF16x8: + case LeVecF16x8: + case GtVecF16x8: + case GeVecF16x8: case EqVecF32x4: case NeVecF32x4: case LtVecF32x4: diff --git a/test/lit/basic/f16.wast b/test/lit/basic/f16.wast index 1dceb807525..21c9fc100c5 100644 --- a/test/lit/basic/f16.wast +++ b/test/lit/basic/f16.wast @@ -13,36 +13,40 @@ (memory 1 1) - ;; CHECK-TEXT: (type $0 (func (param i32) (result f32))) + ;; CHECK-TEXT: (type $0 (func (param v128 v128) (result v128))) - ;; CHECK-TEXT: (type $1 (func (param i32 f32))) + ;; CHECK-TEXT: (type $1 (func (param i32) (result f32))) - ;; CHECK-TEXT: (type $2 (func (param f32) (result v128))) + ;; CHECK-TEXT: (type $2 (func (param i32 f32))) - ;; CHECK-TEXT: (type $3 (func (param v128) (result f32))) + ;; CHECK-TEXT: (type $3 (func (param f32) (result v128))) - ;; CHECK-TEXT: (type $4 (func (param v128 f32) (result v128))) + ;; CHECK-TEXT: (type $4 (func (param v128) (result f32))) + + ;; CHECK-TEXT: (type $5 (func (param v128 f32) (result v128))) ;; CHECK-TEXT: (memory $0 1 1) - ;; CHECK-TEXT: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) + ;; CHECK-TEXT: (func $f32.load_f16 (type $1) (param $0 i32) (result f32) ;; CHECK-TEXT-NEXT: (f32.load_f16 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (type $0 (func (param i32) (result f32))) + ;; CHECK-BIN: (type $0 (func (param v128 v128) (result v128))) + + ;; CHECK-BIN: (type $1 (func (param i32) (result f32))) - ;; CHECK-BIN: (type $1 (func (param i32 f32))) + ;; CHECK-BIN: (type $2 (func (param i32 f32))) - ;; CHECK-BIN: (type $2 (func (param f32) (result v128))) + ;; CHECK-BIN: (type $3 (func (param f32) (result v128))) - ;; CHECK-BIN: (type $3 (func (param v128) (result f32))) + ;; CHECK-BIN: (type $4 (func (param v128) (result f32))) - ;; CHECK-BIN: (type $4 (func (param v128 f32) (result v128))) + ;; CHECK-BIN: (type $5 (func (param v128 f32) (result v128))) ;; CHECK-BIN: (memory $0 1 1) - ;; CHECK-BIN: (func $f32.load_f16 (type $0) (param $0 i32) (result f32) + ;; CHECK-BIN: (func $f32.load_f16 (type $1) (param $0 i32) (result f32) ;; CHECK-BIN-NEXT: (f32.load_f16 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -52,13 +56,13 @@ (local.get $0) ) ) - ;; CHECK-TEXT: (func $f32.store_f16 (type $1) (param $0 i32) (param $1 f32) + ;; CHECK-TEXT: (func $f32.store_f16 (type $2) (param $0 i32) (param $1 f32) ;; CHECK-TEXT-NEXT: (f32.store_f16 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f32.store_f16 (type $1) (param $0 i32) (param $1 f32) + ;; CHECK-BIN: (func $f32.store_f16 (type $2) (param $0 i32) (param $1 f32) ;; CHECK-BIN-NEXT: (f32.store_f16 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) @@ -71,12 +75,12 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.splat (type $2) (param $0 f32) (result v128) + ;; CHECK-TEXT: (func $f16x8.splat (type $3) (param $0 f32) (result v128) ;; CHECK-TEXT-NEXT: (f16x8.splat ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.splat (type $2) (param $0 f32) (result v128) + ;; CHECK-BIN: (func $f16x8.splat (type $3) (param $0 f32) (result v128) ;; CHECK-BIN-NEXT: (f16x8.splat ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -87,12 +91,12 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.extract_lane (type $3) (param $0 v128) (result f32) + ;; CHECK-TEXT: (func $f16x8.extract_lane (type $4) (param $0 v128) (result f32) ;; CHECK-TEXT-NEXT: (f16x8.extract_lane 0 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.extract_lane (type $3) (param $0 v128) (result f32) + ;; CHECK-BIN: (func $f16x8.extract_lane (type $4) (param $0 v128) (result f32) ;; CHECK-BIN-NEXT: (f16x8.extract_lane 0 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -103,13 +107,13 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.replace_lane (type $4) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-TEXT: (func $f16x8.replace_lane (type $5) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-TEXT-NEXT: (f16x8.replace_lane 0 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.replace_lane (type $4) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-BIN: (func $f16x8.replace_lane (type $5) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-BIN-NEXT: (f16x8.replace_lane 0 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) @@ -121,48 +125,200 @@ (local.get $1) ) ) + ;; CHECK-TEXT: (func $f16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.eq + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.eq (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.eq + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.eq (param $0 v128) (param $1 v128) (result v128) + (f16x8.eq + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.ne + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.ne (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.ne + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.ne (param $0 v128) (param $1 v128) (result v128) + (f16x8.ne + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.lt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.lt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.lt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.lt (param $0 v128) (param $1 v128) (result v128) + (f16x8.lt + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.gt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.gt (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.gt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.gt (param $0 v128) (param $1 v128) (result v128) + (f16x8.gt + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.le + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.le (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.le + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.le (param $0 v128) (param $1 v128) (result v128) + (f16x8.le + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.ge + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.ge (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.ge + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.ge (param $0 v128) (param $1 v128) (result v128) + (f16x8.ge + (local.get $0) + (local.get $1) + ) + ) ) -;; CHECK-BIN-NODEBUG: (type $0 (func (param i32) (result f32))) +;; CHECK-BIN-NODEBUG: (type $0 (func (param v128 v128) (result v128))) + +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result f32))) -;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 f32))) +;; CHECK-BIN-NODEBUG: (type $2 (func (param i32 f32))) -;; CHECK-BIN-NODEBUG: (type $2 (func (param f32) (result v128))) +;; CHECK-BIN-NODEBUG: (type $3 (func (param f32) (result v128))) -;; CHECK-BIN-NODEBUG: (type $3 (func (param v128) (result f32))) +;; CHECK-BIN-NODEBUG: (type $4 (func (param v128) (result f32))) -;; CHECK-BIN-NODEBUG: (type $4 (func (param v128 f32) (result v128))) +;; CHECK-BIN-NODEBUG: (type $5 (func (param v128 f32) (result v128))) ;; CHECK-BIN-NODEBUG: (memory $0 1 1) -;; CHECK-BIN-NODEBUG: (func $0 (type $0) (param $0 i32) (result f32) +;; CHECK-BIN-NODEBUG: (func $0 (type $1) (param $0 i32) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (f32.load_f16 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $1 (type $1) (param $0 i32) (param $1 f32) +;; CHECK-BIN-NODEBUG: (func $1 (type $2) (param $0 i32) (param $1 f32) ;; CHECK-BIN-NODEBUG-NEXT: (f32.store_f16 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $2 (type $2) (param $0 f32) (result v128) +;; CHECK-BIN-NODEBUG: (func $2 (type $3) (param $0 f32) (result v128) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.splat ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $3) (param $0 v128) (result f32) +;; CHECK-BIN-NODEBUG: (func $3 (type $4) (param $0 v128) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.extract_lane 0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $4 (type $4) (param $0 v128) (param $1 f32) (result v128) +;; CHECK-BIN-NODEBUG: (func $4 (type $5) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.replace_lane 0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $5 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.eq +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $6 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.ne +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.lt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $8 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.gt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $9 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.le +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $10 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.ge +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/spec/f16.wast b/test/spec/f16.wast index ef32b2ab545..360464e153a 100644 --- a/test/spec/f16.wast +++ b/test/spec/f16.wast @@ -11,6 +11,12 @@ (func (export "f16x8.extract_lane_last") (param $0 v128) (result f32) (f16x8.extract_lane 7 (local.get $0))) (func (export "f16x8.replace_lane_first") (param $0 v128) (param $1 f32) (result v128) (f16x8.replace_lane 0 (local.get $0) (local.get $1))) (func (export "f16x8.replace_lane_last") (param $0 v128) (param $1 f32) (result v128) (f16x8.replace_lane 7 (local.get $0) (local.get $1))) + (func (export "f16x8.eq") (param $0 v128) (param $1 v128) (result v128) (f16x8.eq (local.get $0) (local.get $1))) + (func (export "f16x8.ne") (param $0 v128) (param $1 v128) (result v128) (f16x8.ne (local.get $0) (local.get $1))) + (func (export "f16x8.lt") (param $0 v128) (param $1 v128) (result v128) (f16x8.lt (local.get $0) (local.get $1))) + (func (export "f16x8.gt") (param $0 v128) (param $1 v128) (result v128) (f16x8.gt (local.get $0) (local.get $1))) + (func (export "f16x8.le") (param $0 v128) (param $1 v128) (result v128) (f16x8.le (local.get $0) (local.get $1))) + (func (export "f16x8.ge") (param $0 v128) (param $1 v128) (result v128) (f16x8.ge (local.get $0) (local.get $1))) ) (assert_return (invoke "f32.load_f16") (f32.const 42.0)) @@ -25,3 +31,53 @@ (assert_return (invoke "f16x8.extract_lane_last" (v128.const i16x8 0 0 0 0 0 0 0 0xc500)) (f32.const -5)) (assert_return (invoke "f16x8.replace_lane_first" (v128.const i64x2 0 0) (f32.const 100.5)) (v128.const i16x8 0x5648 0 0 0 0 0 0 0)) (assert_return (invoke "f16x8.replace_lane_last" (v128.const i64x2 0 0) (f32.const 100.5)) (v128.const i16x8 0 0 0 0 0 0 0 0x5648)) + +;; comparisons +(assert_return (invoke "f16x8.eq" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 -1 0 0 0 -1 0 0 0) +) +(assert_return (invoke "f16x8.ne" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 0 -1 -1 -1 0 -1 -1 -1) +) +(assert_return (invoke "f16x8.lt" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 0 -1 0 0 0 0 0 0) +) +(assert_return (invoke "f16x8.gt" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 0 0 -1 0 0 0 -1 0) +) +(assert_return (invoke "f16x8.le" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 -1 -1 0 0 -1 0 0 0) +) +(assert_return (invoke "f16x8.ge" + ;; 0 -1 1 nan inf nan inf nan + ;; 0 0 -1 nan inf 0 -inf inf + (v128.const i16x8 0 0xbc00 0x3c00 0x7e00 0x7c00 0x7e00 0x7c00 0x7e00) + (v128.const i16x8 0 0 0xbc00 0x7e00 0x7c00 0 0xfc00 0x7c00) + ) + (v128.const i16x8 -1 0 -1 0 -1 0 -1 0) +) From 3386e642c76028438fc783bf97089115ea9a900f Mon Sep 17 00:00:00 2001 From: Frank Emrich Date: Fri, 9 Aug 2024 21:30:56 +0100 Subject: [PATCH 509/553] Typed continuations: update syntax of handler clauses (#6824) The syntax for handler clauses in `resume` instructions has recently changed, using `on` instead of `tag` now. Instead of ``` (resume $ct (tag $tag0 $block0) ... (tag $tagn $blockn)) ``` we now have ``` (resume $ct (on $tag0 $block0) ... (on $tagn $blockn)) ``` This PR adapts parsing, printing, and some tests accordingly. (Note that this PR deliberately makes none of the other changes that will arise from implementing the new, combined stack switching proposal, yet.) --- src/parser/parsers.h | 4 ++-- src/passes/Print.cpp | 4 +--- test/lit/basic/typed_continuations_resume.wast | 12 ++++++------ test/lit/wat-kitchen-sink.wast | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/parser/parsers.h b/src/parser/parsers.h index e3434d1e653..ef46a395a7c 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -2426,7 +2426,7 @@ makeContNew(Ctx& ctx, Index pos, const std::vector& annotations) { return ctx.makeContNew(pos, annotations, *type); } -// resume ::= 'resume' typeidx ('(' 'tag' tagidx labelidx ')')* +// resume ::= 'resume' typeidx ('(' 'on' tagidx labelidx ')')* template Result<> makeResume(Ctx& ctx, Index pos, const std::vector& annotations) { @@ -2434,7 +2434,7 @@ makeResume(Ctx& ctx, Index pos, const std::vector& annotations) { CHECK_ERR(type); auto tagLabels = ctx.makeTagLabelList(); - while (ctx.in.takeSExprStart("tag"sv)) { + while (ctx.in.takeSExprStart("on"sv)) { auto tag = tagidx(ctx); CHECK_ERR(tag); auto label = labelidx(ctx); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 5c83e89f19f..8bf30702c3d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2374,11 +2374,9 @@ struct PrintExpressionContents o << ' '; printHeapType(curr->contType); - // We deliberate keep all (tag ...) clauses on the same line as the resume - // itself to work around a quirk in update_lit_checks.py for (Index i = 0; i < curr->handlerTags.size(); i++) { o << " ("; - printMedium(o, "tag "); + printMedium(o, "on "); curr->handlerTags[i].print(o); o << ' '; curr->handlerBlocks[i].print(o); diff --git a/test/lit/basic/typed_continuations_resume.wast b/test/lit/basic/typed_continuations_resume.wast index d2430e2a033..5cd2277d311 100644 --- a/test/lit/basic/typed_continuations_resume.wast +++ b/test/lit/basic/typed_continuations_resume.wast @@ -39,7 +39,7 @@ ;; CHECK-BINARY-NEXT: (drop ;; CHECK-BINARY-NEXT: (block $label$1 (result (ref $ct)) ;; CHECK-BINARY-NEXT: (return - ;; CHECK-BINARY-NEXT: (resume $ct (tag $t $label$1) + ;; CHECK-BINARY-NEXT: (resume $ct (on $t $label$1) ;; CHECK-BINARY-NEXT: (i32.const 123) ;; CHECK-BINARY-NEXT: (local.get $x) ;; CHECK-BINARY-NEXT: ) @@ -52,7 +52,7 @@ ;; CHECK-TEXT-NEXT: (tuple.extract 2 0 ;; CHECK-TEXT-NEXT: (block $handler (type $2) (result i32 (ref $ct)) ;; CHECK-TEXT-NEXT: (return - ;; CHECK-TEXT-NEXT: (resume $ct (tag $t $handler) + ;; CHECK-TEXT-NEXT: (resume $ct (on $t $handler) ;; CHECK-TEXT-NEXT: (i32.const 123) ;; CHECK-TEXT-NEXT: (local.get $x) ;; CHECK-TEXT-NEXT: ) @@ -66,7 +66,7 @@ ;; CHECK-BIN-NEXT: (local.set $1 ;; CHECK-BIN-NEXT: (block $label$1 (type $2) (result i32 (ref $ct)) ;; CHECK-BIN-NEXT: (return - ;; CHECK-BIN-NEXT: (resume $ct (tag $t $label$1) + ;; CHECK-BIN-NEXT: (resume $ct (on $t $label$1) ;; CHECK-BIN-NEXT: (i32.const 123) ;; CHECK-BIN-NEXT: (local.get $x) ;; CHECK-BIN-NEXT: ) @@ -92,7 +92,7 @@ (block $handler (result i32 (ref $ct)) (return (resume $ct - (tag $t $handler) + (on $t $handler) (i32.const 123) (local.get $x) ) @@ -115,7 +115,7 @@ ;; CHECK-NODEBUG-NEXT: (drop ;; CHECK-NODEBUG-NEXT: (block $label$1 (result (ref $1)) ;; CHECK-NODEBUG-NEXT: (return -;; CHECK-NODEBUG-NEXT: (resume $1 (tag $tag$0 $label$1) +;; CHECK-NODEBUG-NEXT: (resume $1 (on $tag$0 $label$1) ;; CHECK-NODEBUG-NEXT: (i32.const 123) ;; CHECK-NODEBUG-NEXT: (local.get $0) ;; CHECK-NODEBUG-NEXT: ) @@ -140,7 +140,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 ;; CHECK-BIN-NODEBUG-NEXT: (block $label$1 (type $2) (result i32 (ref $1)) ;; CHECK-BIN-NODEBUG-NEXT: (return -;; CHECK-BIN-NODEBUG-NEXT: (resume $1 (tag $tag$0 $label$1) +;; CHECK-BIN-NODEBUG-NEXT: (resume $1 (on $tag$0 $label$1) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 123) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index ac8a00cc288..de16f6923ce 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -4868,7 +4868,7 @@ ;; CHECK-NEXT: (tuple.drop 3 ;; CHECK-NEXT: (block $block0 (type $36) (result i32 i64 (ref null $simple-cont)) ;; CHECK-NEXT: (local.set $f - ;; CHECK-NEXT: (resume $simple-cont (tag $empty $block) (tag $tag-pair-to-pair $block0) + ;; CHECK-NEXT: (resume $simple-cont (on $empty $block) (on $tag-pair-to-pair $block0) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i64.const 1) ;; CHECK-NEXT: (local.get $ct) @@ -4890,7 +4890,7 @@ i32.const 0 i64.const 1 local.get $ct - resume $simple-cont (tag $empty 1) (tag $tag-pair-to-pair 0) + resume $simple-cont (on $empty 1) (on $tag-pair-to-pair 0) local.set $f unreachable end From e729e012c50eb118be09f6a8005f0c9090fff3a0 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 9 Aug 2024 14:49:32 -0700 Subject: [PATCH 510/553] Set hasExplicitName for thunks generated in FuncCastEmulation. NFC (#6826) Without this all the newly created thunks lack names in the name section. --- src/passes/FuncCastEmulation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 972cf719cb7..49ef2fd7a03 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -206,6 +206,7 @@ struct FuncCastEmulation : public Pass { Signature(Type(thunkParams), Type::i64), {}, // no vars toABI(call, module)); + thunkFunc->hasExplicitName = true; module->addFunction(std::move(thunkFunc)); return thunk; } From a4f9128f94b540fa04b67610eb501cb32ea203b4 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 12 Aug 2024 12:30:23 -0700 Subject: [PATCH 511/553] GlobalTypeOptimization: Reorder fields in order to remove them (#6820) Before, we only removed fields from the end of a struct. If we had, say struct Foo { int x; int y; int z; }; // Add no fields but inherit the parent's. struct Bar : Foo {}; If y is only used in Bar, but never Foo, then we still kept it around, because if we removed it from Foo we'd end up with Foo = {x, z}, Bar = {x, y, z} which is invalid - Bar no longer extends Foo. But we can do this if we first reorder the two: struct Foo { int x; int z; int y; // now y is at the end }; struct Bar : Foo {}; And the optimized form is struct Foo { int x; int z; }; struct Bar : Foo { int y; // now y is added in Bar }; This lets us remove all fields possible in all cases AFAIK. This situation is not super-common, as most fields are actually used both up and down the hierarchy (if they are used at all), but testing on some large real-world codebases, I see 10 fields removed in Java, 45 in Kotlin, and 31 in Dart testcases. The NFC change to src/wasm-type-ordering.h was needed for this to compile. --- src/ir/localize.h | 2 + src/passes/GlobalTypeOptimization.cpp | 201 ++++++++--- src/wasm-type-ordering.h | 3 - test/lit/passes/gto-removals.wast | 458 +++++++++++++++++++++++++- 4 files changed, 594 insertions(+), 70 deletions(-) diff --git a/src/ir/localize.h b/src/ir/localize.h index 85e4415f5ef..b36fe639612 100644 --- a/src/ir/localize.h +++ b/src/ir/localize.h @@ -130,6 +130,8 @@ struct ChildLocalizer { // effects we can't remove, or if it interacts with other children. bool needLocal = effects[i].hasUnremovableSideEffects(); if (!needLocal) { + // TODO: Avoid quadratic time here by accumulating effects and checking + // vs the accumulation. for (Index j = 0; j < num; j++) { if (j != i && effects[i].invalidates(effects[j])) { needLocal = true; diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index 5362135616e..eec8e206d7d 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -29,7 +29,9 @@ #include "ir/type-updating.h" #include "ir/utils.h" #include "pass.h" +#include "support/permutations.h" #include "wasm-builder.h" +#include "wasm-type-ordering.h" #include "wasm-type.h" #include "wasm.h" @@ -160,19 +162,23 @@ struct GlobalTypeOptimization : public Pass { // immutable). Note that by making more things immutable we therefore // make it possible to apply more specific subtypes in subtype fields. StructUtils::TypeHierarchyPropagator propagator(*module); - auto subSupers = combinedSetGetInfos; - propagator.propagateToSuperAndSubTypes(subSupers); - auto subs = std::move(combinedSetGetInfos); - propagator.propagateToSubTypes(subs); - - // Process the propagated info. - for (auto type : propagator.subTypes.types) { + auto dataFromSubsAndSupersMap = combinedSetGetInfos; + propagator.propagateToSuperAndSubTypes(dataFromSubsAndSupersMap); + auto dataFromSupersMap = std::move(combinedSetGetInfos); + propagator.propagateToSubTypes(dataFromSupersMap); + + // Process the propagated info. We look at supertypes first, as the order of + // fields in a supertype is a constraint on what subtypes can do. That is, + // we decide for each supertype what the optimal order is, and consider that + // fixed, and then subtypes can decide how to sort fields that they append. + HeapTypeOrdering::SupertypesFirst sorted; + for (auto type : sorted.sort(propagator.subTypes.types)) { if (!type.isStruct()) { continue; } auto& fields = type.getStruct().fields; - auto& subSuper = subSupers[type]; - auto& sub = subs[type]; + auto& dataFromSubsAndSupers = dataFromSubsAndSupersMap[type]; + auto& dataFromSupers = dataFromSupersMap[type]; // Process immutability. for (Index i = 0; i < fields.size(); i++) { @@ -181,7 +187,7 @@ struct GlobalTypeOptimization : public Pass { continue; } - if (subSuper[i].hasWrite) { + if (dataFromSubsAndSupers[i].hasWrite) { // A set exists. continue; } @@ -192,48 +198,132 @@ struct GlobalTypeOptimization : public Pass { vec[i] = true; } - // Process removability. We check separately for the ability to - // remove in a general way based on sub+super-propagated info (that is, - // fields that are not used in sub- or super-types, and so we can - // definitely remove them from all the relevant types) and also in the - // specific way that only works for removing at the end, which as - // mentioned above only looks at super-types. + // Process removability. std::set removableIndexes; for (Index i = 0; i < fields.size(); i++) { - if (!subSuper[i].hasRead) { - removableIndexes.insert(i); - } - } - for (int i = int(fields.size()) - 1; i >= 0; i--) { - // Unlike above, a write would stop us here: above we propagated to both - // sub- and super-types, which means if we see no reads then there is no - // possible read of the data at all. But here we just propagated to - // subtypes, and so we need to care about the case where the parent - // writes to a field but does not read from it - we still need those - // writes to happen as children may read them. (Note that if no child - // reads this field, and since we check for reads in parents here, that - // means the field is not read anywhere at all, and we would have - // handled that case in the previous loop anyhow.) - if (!sub[i].hasRead && !sub[i].hasWrite) { + // If there is no read whatsoever, in either subs or supers, then we can + // remove the field. That is so even if there are writes (it would be a + // pointless "write-only field"). + auto hasNoReadsAnywhere = !dataFromSubsAndSupers[i].hasRead; + + // Check for reads or writes in ourselves and our supers. If there are + // none, then operations only happen in our strict subtypes, and those + // subtypes can define the field there, and we don't need it here. + auto hasNoReadsOrWritesInSupers = + !dataFromSupers[i].hasRead && !dataFromSupers[i].hasWrite; + + if (hasNoReadsAnywhere || hasNoReadsOrWritesInSupers) { removableIndexes.insert(i); - } else { - // Once we see something we can't remove, we must stop, as we can only - // remove from the end in this case. - break; } } - if (!removableIndexes.empty()) { - auto& indexesAfterRemoval = indexesAfterRemovals[type]; - indexesAfterRemoval.resize(fields.size()); - Index skip = 0; - for (Index i = 0; i < fields.size(); i++) { - if (!removableIndexes.count(i)) { - indexesAfterRemoval[i] = i - skip; + + // We need to compute the new set of indexes if we are removing fields, or + // if our parent removed fields. In the latter case, our parent may have + // reordered fields even if we ourselves are not removing anything, and we + // must update to match the parent's order. + auto super = type.getDeclaredSuperType(); + auto superHasUpdates = super && indexesAfterRemovals.count(*super); + if (!removableIndexes.empty() || superHasUpdates) { + // We are removing fields. Reorder them to allow that, as in the general + // case we can only remove fields from the end, so that if our subtypes + // still need the fields they can append them. For example: + // + // type A = { x: i32, y: f64 }; + // type B : A = { x: 132, y: f64, z: v128 }; + // + // If field x is used in B but never in A then we want to remove it, but + // we cannot end up with this: + // + // type A = { y: f64 }; + // type B : A = { x: 132, y: f64, z: v128 }; + // + // Here B no longer extends A's fields. Instead, we reorder A, which + // then imposes the same order on B's fields: + // + // type A = { y: f64, x: i32 }; + // type B : A = { y: f64, x: i32, z: v128 }; + // + // And after that, it is safe to remove x in A: B will then append it, + // just like it appends z, leading to this: + // + // type A = { y: f64 }; + // type B : A = { y: f64, x: i32, z: v128 }; + // + std::vector indexesAfterRemoval(fields.size()); + + // The next new index to use. + Index next = 0; + + // If we have a super, then we extend it, and must match its fields. + // That is, we can only append fields: we cannot reorder or remove any + // field that is in the super. + Index numSuperFields = 0; + if (super) { + // We have visited the super before. Get the information about its + // fields. + std::vector superIndexes; + auto iter = indexesAfterRemovals.find(*super); + if (iter != indexesAfterRemovals.end()) { + superIndexes = iter->second; } else { + // We did not store any information about the parent, because we + // found nothing to optimize there. That means it is not removing or + // reordering anything, so its new indexes are trivial. + superIndexes = makeIdentity(super->getStruct().fields.size()); + } + + numSuperFields = superIndexes.size(); + + // Fields we keep but the super removed will be handled at the end. + std::vector keptFieldsNotInSuper; + + // Go over the super fields and handle them. + for (Index i = 0; i < superIndexes.size(); ++i) { + auto superIndex = superIndexes[i]; + if (superIndex == RemovedField) { + if (removableIndexes.count(i)) { + // This was removed in the super, and in us as well. + indexesAfterRemoval[i] = RemovedField; + } else { + // This was removed in the super, but we actually need it. It + // must appear after all other super fields, when we get to the + // proper index for that, later. That is, we are reordering. + keptFieldsNotInSuper.push_back(i); + } + } else { + // The super kept this field, so we must keep it as well. + assert(!removableIndexes.count(i)); + // We need to keep it at the same index so we remain compatible. + indexesAfterRemoval[i] = superIndex; + // Update |next| to refer to the next available index. Due to + // possible reordering in the parent, we may not see indexes in + // order here, so just take the max at each point in time. + next = std::max(next, superIndex + 1); + } + } + + // Handle fields we keep but the super removed. + for (auto i : keptFieldsNotInSuper) { + indexesAfterRemoval[i] = next++; + } + } + + // Go over the fields only defined in us, and not in any super. + for (Index i = numSuperFields; i < fields.size(); ++i) { + if (removableIndexes.count(i)) { indexesAfterRemoval[i] = RemovedField; - skip++; + } else { + indexesAfterRemoval[i] = next++; } } + + // Only store the new indexes we computed if we found something + // interesting. We might not, if e.g. our parent removes fields and we + // add them back in the exact order we started with. In such cases, + // avoid wasting memory and also time later. + if (indexesAfterRemoval != makeIdentity(indexesAfterRemoval.size())) { + indexesAfterRemovals[type] = indexesAfterRemoval; + } } } @@ -273,15 +363,16 @@ struct GlobalTypeOptimization : public Pass { } } - // Remove fields where we can. + // Remove/reorder fields where we can. auto remIter = parent.indexesAfterRemovals.find(oldStructType); if (remIter != parent.indexesAfterRemovals.end()) { auto& indexesAfterRemoval = remIter->second; Index removed = 0; + auto copy = newFields; for (Index i = 0; i < newFields.size(); i++) { auto newIndex = indexesAfterRemoval[i]; if (newIndex != RemovedField) { - newFields[newIndex] = newFields[i]; + newFields[newIndex] = copy[i]; } else { removed++; } @@ -347,26 +438,32 @@ struct GlobalTypeOptimization : public Pass { auto& operands = curr->operands; assert(indexesAfterRemoval.size() == operands.size()); - // Localize things so that we can simply remove the operands we no - // longer need. + // Ensure any children with non-trivial effects are replaced with + // local.gets, so that we can remove/reorder to our hearts' content. ChildLocalizer localizer( curr, getFunction(), *getModule(), getPassOptions()); replaceCurrent(localizer.getReplacement()); - // Remove the unneeded operands. + // Remove and reorder operands. Index removed = 0; + std::vector old(operands.begin(), operands.end()); for (Index i = 0; i < operands.size(); i++) { auto newIndex = indexesAfterRemoval[i]; if (newIndex != RemovedField) { assert(newIndex < operands.size()); - operands[newIndex] = operands[i]; + operands[newIndex] = old[i]; } else { removed++; } } - operands.resize(operands.size() - removed); - // We should only get here if we did actual work. - assert(removed > 0); + if (removed) { + operands.resize(operands.size() - removed); + } else { + // If we didn't remove anything then we must have reordered (or else + // we have done pointless work). + assert(indexesAfterRemoval != + makeIdentity(indexesAfterRemoval.size())); + } } void visitStructSet(StructSet* curr) { diff --git a/src/wasm-type-ordering.h b/src/wasm-type-ordering.h index 72b1818f72d..981ac004d23 100644 --- a/src/wasm-type-ordering.h +++ b/src/wasm-type-ordering.h @@ -68,9 +68,6 @@ struct SupertypesFirstBase }; struct SupertypesFirst : SupertypesFirstBase { - template - SupertypesFirst(const T& types) : SupertypesFirstBase(types) {} - std::optional getDeclaredSuperType(HeapType type) { return type.getDeclaredSuperType(); } diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index c5e148afaff..c2e82aee9c8 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -637,26 +637,27 @@ ) ) -;; We can remove fields from the end if they are only used in subtypes, because -;; the subtypes can always add fields at the end (and only at the end). +;; We can remove fields if they are only used in subtypes, because we can +;; reorder the fields in the super and re-add them in the sub, appending on top +;; of the now-shorter super. (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $parent (sub (struct (field i32) (field i64)))) + ;; CHECK-NEXT: (type $parent (sub (struct (field i64)))) (type $parent (sub (struct (field i32) (field i64) (field f32) (field f64)))) - ;; CHECK: (type $child (sub $parent (struct (field i32) (field i64) (field f32) (field f64) (field anyref)))) + ;; CHECK: (type $child (sub $parent (struct (field i64) (field i32) (field f32) (field f64) (field anyref)))) (type $child (sub $parent (struct (field i32) (field i64) (field f32) (field f64) (field anyref)))) ;; CHECK: (type $2 (func (param (ref $parent) (ref $child)))) ;; CHECK: (func $func (type $2) (param $x (ref $parent)) (param $y (ref $child)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.get $parent 1 + ;; CHECK-NEXT: (struct.get $parent 0 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.get $child 0 + ;; CHECK-NEXT: (struct.get $child 1 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -678,9 +679,10 @@ ;; CHECK-NEXT: ) (func $func (param $x (ref $parent)) (param $y (ref $child)) ;; The parent has fields 0, 1, 2, 3 and the child adds 4. - ;; Use fields only 1 in the parent, and all the rest in the child. We can - ;; only remove from the end in the child, which means we can remove 2 and 3 - ;; in the parent, but not 0. + ;; Use only field 1 in the parent, and all the rest in the child. We can + ;; reorder field 1 to the start of the parent (flipping its position with + ;; field 0) and then remove all the fields but the now-first. The child + ;; keeps all fields, but is reordered. (drop (struct.get $parent 1 (local.get $x))) (drop (struct.get $child 0 (local.get $y))) (drop (struct.get $child 2 (local.get $y))) @@ -691,31 +693,31 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $parent (sub (struct (field i32) (field i64) (field (mut f32))))) + ;; CHECK-NEXT: (type $parent (sub (struct (field i64) (field (mut f32))))) (type $parent (sub (struct (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64))))) - ;; CHECK: (type $child (sub $parent (struct (field i32) (field i64) (field (mut f32)) (field f64) (field anyref)))) + ;; CHECK: (type $child (sub $parent (struct (field i64) (field (mut f32)) (field i32) (field f64) (field anyref)))) (type $child (sub $parent (struct (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64)) (field (mut anyref))))) ;; CHECK: (type $2 (func (param (ref $parent) (ref $child)))) ;; CHECK: (func $func (type $2) (param $x (ref $parent)) (param $y (ref $child)) - ;; CHECK-NEXT: (struct.set $parent 2 + ;; CHECK-NEXT: (struct.set $parent 1 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (f32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.get $parent 1 + ;; CHECK-NEXT: (struct.get $parent 0 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.get $child 0 + ;; CHECK-NEXT: (struct.get $child 2 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (struct.get $child 2 + ;; CHECK-NEXT: (struct.get $child 1 ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -743,6 +745,54 @@ ) ) +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $parent (sub (struct (field i64) (field (mut f32))))) + (type $parent (sub (struct (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64))))) + + ;; CHECK: (type $child (sub $parent (struct (field i64) (field (mut f32)) (field i32) (field anyref)))) + (type $child (sub $parent (struct (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64)) (field (mut anyref))))) + + ;; CHECK: (type $2 (func (param (ref $parent) (ref $child)))) + + ;; CHECK: (func $func (type $2) (param $x (ref $parent)) (param $y (ref $child)) + ;; CHECK-NEXT: (struct.set $parent 1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $parent 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $child 2 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $child 1 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $child 3 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func (param $x (ref $parent)) (param $y (ref $child)) + ;; As above, but now we remove fields in the child as well: 3 is not used. + (struct.set $parent 2 (local.get $x) (f32.const 0)) + + (drop (struct.get $parent 1 (local.get $x))) + (drop (struct.get $child 0 (local.get $y))) + (drop (struct.get $child 2 (local.get $y))) + ;; the read of 3 was removed here. + (drop (struct.get $child 4 (local.get $y))) + ) +) + ;; A parent with two children, and there are only reads of the parent. Those ;; reads might be of data of either child, of course (as a refernce to the ;; parent might point to them), so we cannot optimize here. @@ -977,3 +1027,381 @@ ) ) ) + +;; A parent with two children, with fields used in various combinations. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field v128) (field nullref)))) + (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + + ;; CHECK: (type $C (sub $A (struct (field i64) (field v128) (field nullref) (field f64) (field anyref)))) + (type $C (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + + ;; CHECK: (type $B (sub $A (struct (field i64) (field v128) (field nullref) (field f32) (field anyref)))) + (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ) + + ;; CHECK: (type $3 (func (param anyref))) + + ;; CHECK: (func $func (type $3) (param $x anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 3 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 3 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 4 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 4 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 1 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 1 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 2 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 2 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func (param $x anyref) + ;; Field 0 (i32) is used nowhere. + ;; Field 1 (i64) is used only in $A. + ;; Field 2 (f32) is used only in $B. + ;; Field 3 (f64) is used only in $C. + ;; Field 4 (anyref) is used only in $B and $C. + ;; Field 5 (v128) is used only in $A and $C. + ;; Field 6 (nullref) is used only in $A and $B. + ;; As a result: + ;; * A can keep only fields 1, 5, 6 (i64, v128, nullref). + ;; * B keeps A's fields, and appends 2, 4 (f32, anyref). + ;; * C keeps A's fields, and appends 3, 4 (f64, anyref). + + (drop (struct.get $A 1 (ref.cast (ref $A) (local.get $x)))) + + (drop (struct.get $B 2 (ref.cast (ref $B) (local.get $x)))) + + (drop (struct.get $C 3 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $B 4 (ref.cast (ref $B) (local.get $x)))) + (drop (struct.get $C 4 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $A 5 (ref.cast (ref $A) (local.get $x)))) + (drop (struct.get $C 5 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $A 6 (ref.cast (ref $A) (local.get $x)))) + (drop (struct.get $B 6 (ref.cast (ref $B) (local.get $x)))) + ) +) + +;; As above, but instead of $A having children $B, $C, now they are a chain, +;; $A :> $B :> $C +;; $C must now also include $B's fields (specifically field 2, the f32). +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field v128) (field nullref)))) + (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + + ;; CHECK: (type $B (sub $A (struct (field i64) (field v128) (field nullref) (field f32) (field anyref)))) + (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + + ;; CHECK: (type $C (sub $B (struct (field i64) (field v128) (field nullref) (field f32) (field anyref) (field f64)))) + (type $C (sub $B (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ) + + ;; CHECK: (type $3 (func (param anyref))) + + ;; CHECK: (func $func (type $3) (param $x anyref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 3 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 5 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 4 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 4 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 1 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $C 1 + ;; CHECK-NEXT: (ref.cast (ref $C) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 2 + ;; CHECK-NEXT: (ref.cast (ref $A) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 2 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func (param $x anyref) + ;; Same uses as before. + + (drop (struct.get $A 1 (ref.cast (ref $A) (local.get $x)))) + + (drop (struct.get $B 2 (ref.cast (ref $B) (local.get $x)))) + + (drop (struct.get $C 3 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $B 4 (ref.cast (ref $B) (local.get $x)))) + (drop (struct.get $C 4 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $A 5 (ref.cast (ref $A) (local.get $x)))) + (drop (struct.get $C 5 (ref.cast (ref $C) (local.get $x)))) + + (drop (struct.get $A 6 (ref.cast (ref $A) (local.get $x)))) + (drop (struct.get $B 6 (ref.cast (ref $B) (local.get $x)))) + ) +) + +;; The parent $A is an empty struct, with nothing to remove. See we do not error +;; here. +(module + ;; CHECK: (type $A (sub (struct))) + (type $A (sub (struct))) + + ;; CHECK: (type $B (sub $A (struct))) + (type $B (sub $A (struct))) + + ;; CHECK: (type $2 (func (param (ref $B)))) + + ;; CHECK: (func $func (type $2) (param $x (ref $B)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $func (param $x (ref $B)) + ;; Use $B in a param to keep it alive, and lead us to process it and $A. + ) +) + +;; As above, but now $B has fields to remove. +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct))) + (type $A (sub (struct))) + + ;; CHECK: (type $B (sub $A (struct))) + (type $B (sub $A (struct (field i32) (field i64)))) + + ;; CHECK: (type $2 (func (param (ref $B)))) + + ;; CHECK: (func $func (type $2) (param $x (ref $B)) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $func (param $x (ref $B)) + ) +) + +;; As above, but now $B's fields are used. +(module + ;; CHECK: (type $A (sub (struct))) + (type $A (sub (struct))) + + ;; CHECK: (type $B (sub $A (struct (field i32) (field i64)))) + (type $B (sub $A (struct (field i32) (field i64)))) + + ;; CHECK: (type $2 (func (param (ref $B)))) + + ;; CHECK: (func $func (type $2) (param $x (ref $B)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func (param $x (ref $B)) + (drop (struct.get $B 0 (local.get $x))) + (drop (struct.get $B 1 (local.get $x))) + ) +) + +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct (field i32)))) + (type $A (sub (struct (field i32)))) + ;; CHECK: (type $B (sub $A (struct (field i32)))) + (type $B (sub $A (struct (field i32) (field f64)))) + ) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (func $test (type $2) + ;; CHECK-NEXT: (local $x (ref null $A)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $A 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 0 + ;; CHECK-NEXT: (ref.cast (ref $B) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test + (local $x (ref null $A)) + ;; We cannot remove anything from $A, but we can from $B. That $A is + ;; unchanged should not confuse us. + (drop + (struct.get $A 0 + (local.get $x) + ) + ) + ;; $B reads field 0, but not its new field 1. + (drop + (struct.get $B 0 + (ref.cast (ref $B) + (local.get $x) + ) + ) + ) + ) +) + +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (sub (struct))) + (type $A (sub (struct (field i32)))) + ;; CHECK: (type $B (sub $A (struct (field i32) (field f64)))) + (type $B (sub $A (struct (field i32) (field f64)))) + ) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (func $test (type $2) + ;; CHECK-NEXT: (local $x (ref null $B)) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (struct.new $B + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 0 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $B 1 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test + (local $x (ref null $B)) + ;; We can remove everything from $A, but nothing from $B. That $A changes + ;; entirely, and $B changes not at all, should not cause any errors. + (local.set $x + (struct.new $B + (i32.const 42) + (f64.const 3.14159) + ) + ) + (drop + (struct.get $B 0 + (local.get $x) + ) + ) + (drop + (struct.get $B 1 + (local.get $x) + ) + ) + ) +) From d7955a34e332a78cc71bf77800114cba008185bb Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 13 Aug 2024 00:32:49 -0400 Subject: [PATCH 512/553] Add a TypeBuilder API for copying a heap type (#6828) Given a function that maps the old child heap types to new child heap types, the new API takes care of copying the rest of the structure of a given heap type into a TypeBuilder slot. Use the new API in GlobalTypeRewriter::rebuildTypes. It will also be used in an upcoming type optimization. This refactoring also required adding the ability to clear the supertype of a TypeBuilder slot, which was previously not possible. --- src/ir/type-updating.cpp | 73 ++++++++++++++++++---------------------- src/passes/TypeSSA.cpp | 15 +-------- src/wasm-type.h | 72 +++++++++++++++++++++++++++++++++++++-- src/wasm/wasm-type.cpp | 4 +-- 4 files changed, 105 insertions(+), 59 deletions(-) diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index ceb37300a91..92ec97980d6 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -88,55 +88,47 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( // Create the temporary heap types. i = 0; + auto map = [&](HeapType type) -> HeapType { + if (auto it = typeIndices.find(type); it != typeIndices.end()) { + return typeBuilder[it->second]; + } + return type; + }; for (auto [type, _] : typeIndices) { - typeBuilder[i].setOpen(type.isOpen()); - typeBuilder[i].setShared(type.getShared()); - if (type.isSignature()) { - auto sig = type.getSignature(); - TypeList newParams, newResults; - for (auto t : sig.params) { - newParams.push_back(getTempType(t)); + typeBuilder[i].copy(type, map); + switch (type.getKind()) { + case HeapTypeKind::Func: { + auto newSig = HeapType(typeBuilder[i]).getSignature(); + modifySignature(type, newSig); + typeBuilder[i] = newSig; + break; } - for (auto t : sig.results) { - newResults.push_back(getTempType(t)); + case HeapTypeKind::Struct: { + auto newStruct = HeapType(typeBuilder[i]).getStruct(); + modifyStruct(type, newStruct); + typeBuilder[i] = newStruct; + break; } - Signature newSig(typeBuilder.getTempTupleType(newParams), - typeBuilder.getTempTupleType(newResults)); - modifySignature(type, newSig); - typeBuilder[i] = newSig; - } else if (type.isStruct()) { - auto struct_ = type.getStruct(); - // Start with a copy to get mutability/packing/etc. - auto newStruct = struct_; - for (auto& field : newStruct.fields) { - field.type = getTempType(field.type); + case HeapTypeKind::Array: { + auto newArray = HeapType(typeBuilder[i]).getArray(); + modifyArray(type, newArray); + typeBuilder[i] = newArray; + break; } - modifyStruct(type, newStruct); - typeBuilder[i] = newStruct; - } else if (type.isArray()) { - auto array = type.getArray(); - // Start with a copy to get mutability/packing/etc. - auto newArray = array; - newArray.element.type = getTempType(newArray.element.type); - modifyArray(type, newArray); - typeBuilder[i] = newArray; - } else { - WASM_UNREACHABLE("bad type"); + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } - // Apply a super, if there is one if (auto super = getDeclaredSuperType(type)) { - if (auto it = typeIndices.find(*super); it != typeIndices.end()) { - assert(it->second < i); - typeBuilder[i].subTypeOf(typeBuilder[it->second]); - } else { - typeBuilder[i].subTypeOf(*super); - } + typeBuilder[i].subTypeOf(map(*super)); + } else { + typeBuilder[i].subTypeOf(std::nullopt); } modifyTypeBuilderEntry(typeBuilder, i, type); - - i++; + ++i; } auto buildResults = typeBuilder.build(); @@ -316,8 +308,7 @@ Type GlobalTypeRewriter::getTempType(Type type) { return type; } if (type.isTuple()) { - auto& tuple = type.getTuple(); - auto newTuple = tuple; + auto newTuple = type.getTuple(); for (auto& t : newTuple) { t = getTempType(t); } diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 1d00efb5bff..1355b113e03 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -98,20 +98,7 @@ std::vector ensureTypesAreInNewRecGroup(RecGroup recGroup, // Make a builder and add a slot for the hash. TypeBuilder builder(num + 1); for (Index i = 0; i < num; i++) { - auto type = types[i]; - if (type.isStruct()) { - builder[i] = type.getStruct(); - } else { - // Atm this pass only needs struct and array types. If we refactor - // this function to be general purpose we'd need to extend that. TODO - assert(type.isArray()); - builder[i] = type.getArray(); - } - if (auto super = type.getDeclaredSuperType()) { - builder[i].subTypeOf(*super); - } - builder[i].setOpen(type.isOpen()); - builder[i].setShared(type.getShared()); + builder[i].copy(types[i]); } // Implement the hash as a struct with "random" fields, and add it. diff --git a/src/wasm-type.h b/src/wasm-type.h index e2eec5f3523..ff1358a122d 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -660,6 +660,67 @@ struct TypeBuilder { void setHeapType(size_t i, Struct&& struct_); void setHeapType(size_t i, Array array); + // Sets the heap type at index `i` to be a copy of the given heap type with + // its referenced HeapTypes to be replaced according to the provided mapping + // function. + template void copyHeapType(size_t i, HeapType type, F map) { + assert(!type.isBasic()); + if (auto super = type.getDeclaredSuperType()) { + setSubType(i, map(*super)); + } + setOpen(i, type.isOpen()); + setShared(i, type.getShared()); + + auto copySingleType = [&](Type t) -> Type { + if (t.isBasic()) { + return t; + } + assert(t.isRef()); + return getTempRefType(map(t.getHeapType()), t.getNullability()); + }; + auto copyType = [&](Type t) -> Type { + if (t.isTuple()) { + std::vector elems; + elems.reserve(t.size()); + for (auto elem : t) { + elems.push_back(copySingleType(elem)); + } + return getTempTupleType(elems); + } + return copySingleType(t); + }; + switch (type.getKind()) { + case HeapTypeKind::Func: { + auto sig = type.getSignature(); + setHeapType(i, Signature(copyType(sig.params), copyType(sig.results))); + return; + } + case HeapTypeKind::Struct: { + const auto& struct_ = type.getStruct(); + std::vector fields; + fields.reserve(struct_.fields.size()); + for (auto field : struct_.fields) { + field.type = copyType(field.type); + fields.push_back(field); + } + setHeapType(i, Struct(fields)); + return; + } + case HeapTypeKind::Array: { + auto elem = type.getArray().element; + elem.type = copyType(elem.type); + // MSVC gets confused without this disambiguation. + setHeapType(i, wasm::Array(elem)); + return; + } + case HeapTypeKind::Cont: + setHeapType(i, Continuation(map(type.getContinuation().type))); + return; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); + } + } + // Gets the temporary HeapType at index `i`. This HeapType should only be used // to construct temporary Types using the methods below. HeapType getTempHeapType(size_t i); @@ -672,7 +733,7 @@ struct TypeBuilder { // Declare the HeapType being built at index `i` to be an immediate subtype of // the given HeapType. - void setSubType(size_t i, HeapType super); + void setSubType(size_t i, std::optional super); // Create a new recursion group covering slots [i, i + length). Groups must // not overlap or go out of bounds. @@ -746,7 +807,7 @@ struct TypeBuilder { builder.setHeapType(index, array); return *this; } - Entry& subTypeOf(HeapType other) { + Entry& subTypeOf(std::optional other) { builder.setSubType(index, other); return *this; } @@ -758,6 +819,13 @@ struct TypeBuilder { builder.setShared(index, share); return *this; } + template Entry& copy(HeapType type, F map) { + builder.copyHeapType(index, type, map); + return *this; + } + Entry& copy(HeapType type) { + return copy(type, [](HeapType t) { return t; }); + } }; Entry operator[](size_t i) { return Entry{*this, i}; } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 173e4b8c3fe..011c51e7b7e 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -2532,10 +2532,10 @@ Type TypeBuilder::getTempRefType(HeapType type, Nullability nullable) { return markTemp(impl->typeStore.insert(TypeInfo(type, nullable))); } -void TypeBuilder::setSubType(size_t i, HeapType super) { +void TypeBuilder::setSubType(size_t i, std::optional super) { assert(i < size() && "index out of bounds"); HeapTypeInfo* sub = impl->entries[i].info.get(); - sub->supertype = getHeapTypeInfo(super); + sub->supertype = super ? getHeapTypeInfo(*super) : nullptr; } void TypeBuilder::createRecGroup(size_t index, size_t length) { From 9ce4b8a47b15c324b170f7572829532b7e5bfe47 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 13 Aug 2024 00:34:19 -0400 Subject: [PATCH 513/553] [NFC] Separate out GlobalTypeRewriter::mapTypeNames (#6829) Previously a module's type names were updated in `GlobalTypeRewriter::rebuildTypes`, which builds new versions of the existing types, rather than `GlobalTypeRewriter::mapTypes`, which otherwise handles replacing old types with new types everywhere in a module, but should not necessarily replace names. So that users of `mapTypes` who are building their own versions of existing types can also easily update type names, split type name mapping logic out into a new method `GlobalTypeRewriter::mapTypeNames`. --- src/ir/type-updating.cpp | 52 +++++++++++++++++++++------------------- src/ir/type-updating.h | 5 ++++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 92ec97980d6..123b1311941 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -145,31 +145,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes( for (auto [type, index] : typeIndices) { oldToNewTypes[type] = newTypes[index]; } - - // Update type names to avoid duplicates. - std::unordered_set typeNames; - for (auto& [type, info] : wasm.typeNames) { - typeNames.insert(info.name); - } - for (auto& [old, new_] : oldToNewTypes) { - if (old == new_) { - // The type is being mapped to itself; no need to rename anything. - continue; - } - - if (auto it = wasm.typeNames.find(old); it != wasm.typeNames.end()) { - wasm.typeNames[new_] = wasm.typeNames[old]; - // Use the existing name in the new type, as usually it completely - // replaces the old. Rename the old name in a unique way to avoid - // confusion in the case that it remains used. - auto deduped = - Names::getValidName(wasm.typeNames[old].name, - [&](Name test) { return !typeNames.count(test); }); - wasm.typeNames[old].name = deduped; - typeNames.insert(deduped); - } - } - + mapTypeNames(oldToNewTypes); return oldToNewTypes; } @@ -293,6 +269,32 @@ void GlobalTypeRewriter::mapTypes(const TypeMap& oldToNewTypes) { } } +void GlobalTypeRewriter::mapTypeNames(const TypeMap& oldToNewTypes) { + // Update type names to avoid duplicates. + std::unordered_set typeNames; + for (auto& [type, info] : wasm.typeNames) { + typeNames.insert(info.name); + } + for (auto& [old, new_] : oldToNewTypes) { + if (old == new_) { + // The type is being mapped to itself; no need to rename anything. + continue; + } + + if (auto it = wasm.typeNames.find(old); it != wasm.typeNames.end()) { + wasm.typeNames[new_] = wasm.typeNames[old]; + // Use the existing name in the new type, as usually it completely + // replaces the old. Rename the old name in a unique way to avoid + // confusion in the case that it remains used. + auto deduped = + Names::getValidName(wasm.typeNames[old].name, + [&](Name test) { return !typeNames.count(test); }); + wasm.typeNames[old].name = deduped; + typeNames.insert(deduped); + } + } +} + Type GlobalTypeRewriter::getTempType(Type type) { if (type.isBasic()) { return type; diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h index 60b92e58531..a8e071fb647 100644 --- a/src/ir/type-updating.h +++ b/src/ir/type-updating.h @@ -369,6 +369,11 @@ class GlobalTypeRewriter { // not appear, it is mapped to itself. void mapTypes(const TypeMap& oldToNewTypes); + // Users of `mapTypes` may want to update the type names according to their + // mapping. This is not done automatically in `mapTypes` because other users + // may want the names to reflect that types have been replaced. + void mapTypeNames(const TypeMap& oldToNewTypes); + // Subclasses can implement these methods to modify the new set of types that // we map to. By default, we simply copy over the types, and these functions // are the hooks to apply changes through. The methods receive as input the From 6dc5b907fc17fc7f705781dbe16c6b79ed3a1f9a Mon Sep 17 00:00:00 2001 From: Sofi Aberegg <31450814+sofiaaberegg@users.noreply.github.com> Date: Tue, 13 Aug 2024 14:37:48 -0700 Subject: [PATCH 514/553] Add missing parser error check in makeArrayInitElem (#6835) Fixes #6833 --- src/parser/parsers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parser/parsers.h b/src/parser/parsers.h index ef46a395a7c..23286bb2805 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -2329,6 +2329,7 @@ Result<> makeArrayInitElem(Ctx& ctx, auto type = typeidx(ctx); CHECK_ERR(type); auto elem = elemidx(ctx); + CHECK_ERR(elem); return ctx.makeArrayInitElem(pos, annotations, *type, *elem); } From 0c84afe87ea67239c4d7bf885b43b5c4f52322af Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 13 Aug 2024 16:04:09 -0700 Subject: [PATCH 515/553] Heap2Local: Track interactions in detail (#6834) Previously we tracked only whether an expression was relevant to analysis, that is, whether it interacted with the allocation we were tracing the behavior of. That is not enough for all cases, though, so also track the form of the interaction, namely whether the allocation flows through or is fully consumed. An example where that matters: (ref.eq (struct.get $A 0 (local.tee $x (struct.new_default $A) ) ) (local.get $x) ) Here the local.get flows out the allocation, but the struct.get only fully consumes it. Before this PR we thought the struct.get flowed the allocation, and we misoptimized this to 1. To make this possible, do a bunch of minor refactoring: * Move ParentChildInteraction out of the class. * Add a "None" interaction there. * Replace the set of reached expressions with a map of them to their interactions. * Add helper functions to get an expression's interaction or to update it when replacing. The new testcase here shows the main fix. The new assertions are covered by existing testcases. --- src/passes/Heap2Local.cpp | 175 +++++++++++++++++++------------- test/lit/passes/heap2local.wast | 57 +++++++++++ 2 files changed, 162 insertions(+), 70 deletions(-) diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index c8d478ad586..0531ebf9a2d 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -167,6 +167,30 @@ namespace wasm { namespace { +// Interactions between a child and a parent, with regard to the behavior of the +// allocation. +enum class ParentChildInteraction : int8_t { + // The parent lets the child escape. E.g. the parent is a call. + Escapes, + // The parent fully consumes the child in a safe, non-escaping way, and + // after consuming it nothing remains to flow further through the parent. + // E.g. the parent is a struct.get, which reads from the allocated heap + // value and does nothing more with the reference. + FullyConsumes, + // The parent flows the child out, that is, the child is the single value + // that can flow out from the parent. E.g. the parent is a block with no + // branches and the child is the final value that is returned. + Flows, + // The parent does not consume the child completely, so the child's value + // can be used through it. However the child does not flow cleanly through. + // E.g. the parent is a block with branches, and the value on them may be + // returned from the block and not only the child. This means the allocation + // is not used in an exclusive way, and we cannot optimize it. + Mixes, + // No interaction (not relevant to the analysis). + None, +}; + // Core analysis that provides an escapes() method to check if an allocation // escapes in a way that prevents optimizing it away as described above. It also // stashes information about the relevant expressions as it goes, which helps @@ -194,30 +218,16 @@ struct EscapeAnalyzer { // exclusivity. std::unordered_set sets; - // All the expressions we reached during the flow analysis. That is exactly - // all the places where our allocation is used. We track these so that we - // can fix them up at the end, if the optimization ends up possible. - std::unordered_set reached; - - enum class ParentChildInteraction { - // The parent lets the child escape. E.g. the parent is a call. - Escapes, - // The parent fully consumes the child in a safe, non-escaping way, and - // after consuming it nothing remains to flow further through the parent. - // E.g. the parent is a struct.get, which reads from the allocated heap - // value and does nothing more with the reference. - FullyConsumes, - // The parent flows the child out, that is, the child is the single value - // that can flow out from the parent. E.g. the parent is a block with no - // branches and the child is the final value that is returned. - Flows, - // The parent does not consume the child completely, so the child's value - // can be used through it. However the child does not flow cleanly through. - // E.g. the parent is a block with branches, and the value on them may be - // returned from the block and not only the child. This means the allocation - // is not used in an exclusive way, and we cannot optimize it. - Mixes, - }; + // A map of every expression we reached during the flow analysis (which is + // exactly all the places where our allocation is used) to the interaction of + // the allocation there. If we optimize, anything in this map will be fixed up + // at the end, and how we fix it up may depend on the interaction, + // specifically, it can matter if the allocations flows out of here (Flows, + // which is the case for e.g. a Block that we flow through) or if it is fully + // consumed (FullyConsumes, e.g. for a struct.get). We do not store irrelevant + // things here (that is, anything not in the map has the interaction |None|, + // implicitly). + std::unordered_map reachedInteractions; // Analyze an allocation to see if it escapes or not. bool escapes(Expression* allocation) { @@ -284,9 +294,10 @@ struct EscapeAnalyzer { // If we got to here, then we can continue to hope that we can optimize // this allocation. Mark the parent and child as reached by it, and - // continue. - reached.insert(parent); - reached.insert(child); + // continue. The child flows the value to the parent, and the parent's + // behavior was computed before. + reachedInteractions[child] = ParentChildInteraction::Flows; + reachedInteractions[parent] = interaction; } // We finished the loop over the flows. Do the final checks. @@ -300,7 +311,7 @@ struct EscapeAnalyzer { ParentChildInteraction getParentChildInteraction(Expression* allocation, Expression* parent, - Expression* child) { + Expression* child) const { // If there is no parent then we are the body of the function, and that // means we escape by flowing to the caller. if (!parent) { @@ -517,6 +528,36 @@ struct EscapeAnalyzer { return true; } + + // Helper function for Struct2Local and Array2Struct. Given an old expression + // that is being replaced by a new one, add the proper interaction for the + // replacement. + void applyOldInteractionToReplacement(Expression* old, Expression* rep) { + // We can only replace something relevant that we found in the analysis. + // (Not only would anything else be invalid to process, but also we wouldn't + // know what interaction to give the replacement.) + assert(reachedInteractions.count(old)); + + // The replacement should have the same interaction as the thing it + // replaces, since it is a drop-in replacement for it. The one exception is + // when we replace with something unreachable, which is the result of us + // figuring out that some code will trap at runtime. In that case, we've + // made the code unreachable and the allocation does not interact with that + // code at all. + if (rep->type != Type::unreachable) { + reachedInteractions[rep] = reachedInteractions[old]; + } + } + + // Get the interaction of an expression. + ParentChildInteraction getInteraction(Expression* curr) { + auto iter = reachedInteractions.find(curr); + if (iter == reachedInteractions.end()) { + // This is not interacted with. + return ParentChildInteraction::None; + } + return iter->second; + } }; // An optimizer that handles the rewriting to turn a struct allocation into @@ -527,8 +568,8 @@ struct EscapeAnalyzer { struct Struct2Local : PostWalker { StructNew* allocation; - // The analyzer is not |const| because we update |analyzer.reached| as we go - // (see replaceCurrent, below). + // The analyzer is not |const| because we update + // |analyzer.reachedInteractions| as we go (see replaceCurrent, below). EscapeAnalyzer& analyzer; Function* func; @@ -563,11 +604,8 @@ struct Struct2Local : PostWalker { bool refinalize = false; Expression* replaceCurrent(Expression* expression) { + analyzer.applyOldInteractionToReplacement(getCurrent(), expression); PostWalker::replaceCurrent(expression); - // Also update |reached|: we are replacing something that was reached, so - // logically the replacement is also reached. This update is necessary if - // the parent of an expression cares about whether a child was reached. - analyzer.reached.insert(expression); return expression; } @@ -583,7 +621,7 @@ struct Struct2Local : PostWalker { // Adjust the type that flows through an expression, updating that type as // necessary. void adjustTypeFlowingThrough(Expression* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) != ParentChildInteraction::Flows) { return; } @@ -603,7 +641,7 @@ struct Struct2Local : PostWalker { void visitLoop(Loop* curr) { adjustTypeFlowingThrough(curr); } void visitLocalSet(LocalSet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -617,7 +655,7 @@ struct Struct2Local : PostWalker { } void visitLocalGet(LocalGet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -639,7 +677,7 @@ struct Struct2Local : PostWalker { } void visitBreak(Break* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -721,7 +759,7 @@ struct Struct2Local : PostWalker { } void visitRefIsNull(RefIsNull* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -732,7 +770,7 @@ struct Struct2Local : PostWalker { } void visitRefEq(RefEq* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -745,15 +783,16 @@ struct Struct2Local : PostWalker { // If our reference is compared to itself, the result is 1. If it is // compared to something else, the result must be 0, as our reference does // not escape to any other place. - int32_t result = analyzer.reached.count(curr->left) > 0 && - analyzer.reached.count(curr->right) > 0; + int32_t result = + analyzer.getInteraction(curr->left) == ParentChildInteraction::Flows && + analyzer.getInteraction(curr->right) == ParentChildInteraction::Flows; replaceCurrent(builder.makeBlock({builder.makeDrop(curr->left), builder.makeDrop(curr->right), builder.makeConst(Literal(result))})); } void visitRefAs(RefAs* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -764,7 +803,7 @@ struct Struct2Local : PostWalker { } void visitRefTest(RefTest* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -781,7 +820,7 @@ struct Struct2Local : PostWalker { } void visitRefCast(RefCast* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -805,7 +844,7 @@ struct Struct2Local : PostWalker { } void visitStructSet(StructSet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -817,7 +856,7 @@ struct Struct2Local : PostWalker { } void visitStructGet(StructGet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -913,13 +952,14 @@ struct Array2Struct : PostWalker { WASM_UNREACHABLE("bad allocation"); } - // Mark the new expressions we created as reached by the analysis. We need - // to inform the analysis of this because Struct2Local will only process - // such code (it depends on the analysis to tell it what the allocation is - // and where it flowed). Note that the two values here may be identical but - // there is no harm to calling it twice in that case. - noteIsReached(structNew); - noteIsReached(arrayNewReplacement); + // Mark new expressions we created as flowing out the allocation. We need to + // inform the analysis of this because Struct2Local will only process such + // code (it depends on the analysis to tell it what the allocation is and + // where it flowed). Note that the two values here may be identical but + // there is no harm to doing this twice in that case. + analyzer.reachedInteractions[structNew] = + analyzer.reachedInteractions[arrayNewReplacement] = + ParentChildInteraction::Flows; // Update types along the path reached by the allocation: whenever we see // the array type, it should be the struct type. Note that we do this before @@ -935,7 +975,7 @@ struct Array2Struct : PostWalker { auto nonNullArray = Type(arrayType, NonNullable); nullStruct = Type(structType, Nullable); nonNullStruct = Type(structType, NonNullable); - for (auto* reached : analyzer.reached) { + for (auto& [reached, _] : analyzer.reachedInteractions) { if (reached->is()) { // Casts must be handled later: We need to see the old type, and to // potentially replace the cast based on that, see below. @@ -971,6 +1011,12 @@ struct Array2Struct : PostWalker { } } + Expression* replaceCurrent(Expression* expression) { + analyzer.applyOldInteractionToReplacement(getCurrent(), expression); + PostWalker::replaceCurrent(expression); + return expression; + } + // In rare cases we may need to refinalize, as with Struct2Local. bool refinalize = false; @@ -989,19 +1035,17 @@ struct Array2Struct : PostWalker { void visitArrayNew(ArrayNew* curr) { if (curr == allocation) { replaceCurrent(arrayNewReplacement); - noteCurrentIsReached(); } } void visitArrayNewFixed(ArrayNewFixed* curr) { if (curr == allocation) { replaceCurrent(arrayNewReplacement); - noteCurrentIsReached(); } } void visitArraySet(ArraySet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -1018,11 +1062,10 @@ struct Array2Struct : PostWalker { // Convert the ArraySet into a StructSet. replaceCurrent(builder.makeStructSet(index, curr->ref, curr->value)); - noteCurrentIsReached(); } void visitArrayGet(ArrayGet* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -1039,13 +1082,12 @@ struct Array2Struct : PostWalker { // Convert the ArrayGet into a StructGet. replaceCurrent( builder.makeStructGet(index, curr->ref, curr->type, curr->signed_)); - noteCurrentIsReached(); } // Some additional operations need special handling void visitRefTest(RefTest* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -1061,7 +1103,7 @@ struct Array2Struct : PostWalker { } void visitRefCast(RefCast* curr) { - if (!analyzer.reached.count(curr)) { + if (analyzer.getInteraction(curr) == ParentChildInteraction::None) { return; } @@ -1089,13 +1131,6 @@ struct Array2Struct : PostWalker { return curr->cast()->value.getUnsigned(); } - // Inform the analyzer that the current expression (which we just replaced) - // has been reached in its analysis. We are replacing something it reached, - // and want it to consider it as its equivalent. - void noteCurrentIsReached() { noteIsReached(getCurrent()); } - - void noteIsReached(Expression* curr) { analyzer.reached.insert(curr); } - // Given an ArrayNew or ArrayNewFixed, return the size of the array that is // being allocated. Index getArrayNewSize(Expression* allocation) { diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 2e38b7e4e3d..143b7033a9b 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -4428,3 +4428,60 @@ ) ) ) + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $A (sub (struct (field structref)))) + (type $A (sub (struct (field structref)))) + + ;; CHECK: (func $struct.get-ref.eq (type $0) + ;; CHECK-NEXT: (local $x (ref $A)) + ;; CHECK-NEXT: (local $1 structref) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result structref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $struct.get-ref.eq + (local $x (ref $A)) + ;; This ref.eq ends up comparing the tee'd allocation with a read of null + ;; from the allocation's field, which returns 0. This tests that we can + ;; differentiate when the allocation gets somewhere vs when it flows out + ;; from that place, as the allocation does reach the struct.get - hence we + ;; need to update it, when we optimize - but it does not flow it back out. + (if + (ref.eq + (struct.get $A 0 + (local.tee $x + (struct.new_default $A) + ) + ) + (local.get $x) + ) + (then + (unreachable) + ) + ) + ) +) From 39553a0247eb39c2f58c883cd6fb6b7e00f559ad Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 14 Aug 2024 10:45:01 -0700 Subject: [PATCH 516/553] Monomorphization: Add a flag to control the required improvement (#6837) The argument is the minimum benefit we must see for us to decide to optimize, e.g. --monomorphize --pass-arg=monomorphize-min-benefit@50 When the minimum benefit is 50% then if we reduce the cost by 50% through monomorphization then we optimize there. 95% would only optimize when we remove almost all the cost, etc. In practice I see 95% will actually tend to reduce code size overall, as while we add monomorphized versions of functions, we only do so when we remove a lot of work and size, and after inlining we gain benefits. However, 50% or even lower can lead to better benchmark results, in return for larger code size, just like with inlining. To be careful, the default is set to 95%. Previously we optimized whenever we saw any benefit at all, which is the same as requiring a minimum benefit of 0%. Old tests have the flag applied in this PR to set that value, so they do not change. --- scripts/fuzz_opt.py | 5 +- src/passes/Monomorphize.cpp | 59 +- test/lit/passes/monomorphize-benefit.wast | 1652 +++++++++++++++++++++ test/lit/passes/monomorphize-consts.wast | 7 +- test/lit/passes/monomorphize-context.wast | 7 +- test/lit/passes/monomorphize-drop.wast | 7 +- test/lit/passes/monomorphize-types.wast | 7 +- 7 files changed, 1722 insertions(+), 22 deletions(-) create mode 100644 test/lit/passes/monomorphize-benefit.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index a4adb7b7910..4087abed17b 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -1566,7 +1566,10 @@ def write_commands(commands, filename): ("--memory-packing",), ("--merge-blocks",), ('--merge-locals',), - ('--monomorphize',), + # test a few monomorphization levels, and also -always + ('--monomorphize', '--pass-arg=monomorphize-min-benefit@0'), + ('--monomorphize', '--pass-arg=monomorphize-min-benefit@50'), + ('--monomorphize', '--pass-arg=monomorphize-min-benefit@95'), ('--monomorphize-always',), ('--no-stack-ir',), ('--once-reduction',), diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp index f46e27d830d..f05d42445fa 100644 --- a/src/passes/Monomorphize.cpp +++ b/src/passes/Monomorphize.cpp @@ -25,7 +25,7 @@ // parameter. // * If a call provides a constant as a parameter. // * If a call provides a GC allocation as a parameter. TODO -// * If a call is dropped. TODO also other stuff on the outside? +// * If a call is dropped. TODO also other stuff on the outside, e.g. eqz? // // We realize the benefit by creating a monomorphized (specialized/refined) // version of the function, and call that instead. For example, if we have @@ -68,6 +68,26 @@ // testing that always monomorphizes non-trivial callsites, without checking if // the optimizer can help or not (that makes writing testcases simpler). // +// This pass takes an argument: +// +// --pass-arg=monomorphize-min-benefit@N +// +// The minimum amount of benefit we require in order to decide to optimize, +// as a percentage of the original cost. If this is 0 then we always +// optimize, if the cost improves by even 0.0001%. If this is 50 then we +// optimize only when the optimized monomorphized function has half the +// cost of the original, and so forth, that is higher values are more +// careful (and 100 will only optimize when the cost goes to nothing at +// all). +// +// TODO: We may also want more arguments here: +// * Max function size on which to operate (to not even try to optimize huge +// functions, which could be slow). +// * Max optimized size (if the max optimized size is less than the size we +// inline, then all optimized cases would end up inlined; that would also +// put a limit on the size increase). +// * Max absolute size increase (total of all added code). +// // TODO: When we optimize we could run multiple cycles: A calls B calls C might // end up with the refined+optimized B now having refined types in its // call to C, which it did not have before. This is in fact the expected @@ -110,6 +130,9 @@ namespace wasm { namespace { +// Pass arguments. See descriptions in the comment above. +Index MinPercentBenefit = 95; + // A limit on the number of parameters we are willing to have on monomorphized // functions. Large numbers can lead to large stack frames, which can be slow // and lead to stack overflows. @@ -552,6 +575,8 @@ struct Monomorphize : public Pass { void run(Module* module) override { // TODO: parallelize, see comments below + applyArguments(); + // Find all the return-calling functions. We cannot remove their returns // (because turning a return call into a normal call may break the program // by using more stack). @@ -596,6 +621,11 @@ struct Monomorphize : public Pass { } } + void applyArguments() { + MinPercentBenefit = std::stoul(getArgumentOrDefault( + "monomorphize-min-benefit", std::to_string(MinPercentBenefit))); + } + // Try to optimize a call. void processCall(CallInfo& info, Module& wasm) { auto* call = info.call; @@ -678,14 +708,17 @@ struct Monomorphize : public Pass { // keep optimizing from the current contents as we go. It's not // obvious which approach is best here. doOpts(func); - doOpts(monoFunc.get()); // The cost before monomorphization is the old body + the context // operands. The operands will be *removed* from the calling code if we // optimize, and moved into the monomorphized function, so the proper // comparison is the context + the old body, versus the new body (which // includes the reverse-inlined call context). - auto costBefore = CostAnalyzer(func->body).cost; + // + // Note that we use a double here because we are going to subtract and + // multiply this value later (and want to avoid unsigned integer overflow, + // etc.). + double costBefore = CostAnalyzer(func->body).cost; for (auto* operand : context.operands) { // Note that a slight oddity is that we have *not* optimized the // operands before. We optimize func before and after, but the operands @@ -694,13 +727,21 @@ struct Monomorphize : public Pass { // very unoptimized. costBefore += CostAnalyzer(operand).cost; } - auto costAfter = CostAnalyzer(monoFunc->body).cost; - - // TODO: We should probably only accept improvements above some minimum, - // to avoid optimizing cases where we duplicate a huge function but - // only optimize a tiny part of it compared to the original. - if (costAfter >= costBefore) { + if (costBefore == 0) { + // Nothing to optimize away here. (And it would be invalid to divide by + // this amount in the code below.) worthwhile = false; + } else { + // There is a point to optimizing the monomorphized function, do so. + doOpts(monoFunc.get()); + + double costAfter = CostAnalyzer(monoFunc->body).cost; + + // Compute the percentage of benefit we see here. + auto benefit = 100 - ((100 * costAfter) / costBefore); + if (benefit <= MinPercentBenefit) { + worthwhile = false; + } } } diff --git a/test/lit/passes/monomorphize-benefit.wast b/test/lit/passes/monomorphize-benefit.wast new file mode 100644 index 00000000000..a1b69fbd2f4 --- /dev/null +++ b/test/lit/passes/monomorphize-benefit.wast @@ -0,0 +1,1652 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Test optimization decisions while varying the minimum benefit percentage +;; parameter. Zero means any benefit, no matter how small, is worthwhile, while +;; higher values demand more benefit before doing any work. +;; +;; Test with --traps-never-happen (tnh) here so that we optimize more, making it +;; easier to show the effects. This is also more realistic for toolchains like +;; Java/Kotlin/Dart, which is good coverage. + +;; RUN: foreach %s %t wasm-opt --monomorphize -all -tnh -S -o - | filecheck %s --check-prefix DEFAULT +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -tnh -S -o - | filecheck %s --check-prefix ZERO___ +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@33 -all -tnh -S -o - | filecheck %s --check-prefix THIRD__ +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@66 -all -tnh -S -o - | filecheck %s --check-prefix TWOTRDS +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@100 -all -tnh -S -o - | filecheck %s --check-prefix HUNDRED + +(module + (memory 10 20) + + ;; DEFAULT: (type $0 (func (param i32 i32 i32 i32 i32))) + + ;; DEFAULT: (type $1 (func (param i32))) + + ;; DEFAULT: (memory $0 10 20) + + ;; DEFAULT: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + ;; DEFAULT-NEXT: (i32.store + ;; DEFAULT-NEXT: (i32.const 10) + ;; DEFAULT-NEXT: (i32.div_s + ;; DEFAULT-NEXT: (local.get $0) + ;; DEFAULT-NEXT: (i32.add + ;; DEFAULT-NEXT: (local.get $0) + ;; DEFAULT-NEXT: (i32.const 1) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (i32.store + ;; DEFAULT-NEXT: (i32.const 20) + ;; DEFAULT-NEXT: (i32.div_s + ;; DEFAULT-NEXT: (local.get $1) + ;; DEFAULT-NEXT: (i32.add + ;; DEFAULT-NEXT: (local.get $1) + ;; DEFAULT-NEXT: (i32.const 1) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (i32.store + ;; DEFAULT-NEXT: (i32.const 30) + ;; DEFAULT-NEXT: (i32.div_s + ;; DEFAULT-NEXT: (local.get $2) + ;; DEFAULT-NEXT: (i32.add + ;; DEFAULT-NEXT: (local.get $2) + ;; DEFAULT-NEXT: (i32.const 1) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (i32.store + ;; DEFAULT-NEXT: (i32.const 40) + ;; DEFAULT-NEXT: (i32.div_s + ;; DEFAULT-NEXT: (local.get $3) + ;; DEFAULT-NEXT: (i32.add + ;; DEFAULT-NEXT: (local.get $3) + ;; DEFAULT-NEXT: (i32.const 1) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (i32.store + ;; DEFAULT-NEXT: (i32.const 50) + ;; DEFAULT-NEXT: (i32.div_s + ;; DEFAULT-NEXT: (local.get $4) + ;; DEFAULT-NEXT: (i32.add + ;; DEFAULT-NEXT: (local.get $4) + ;; DEFAULT-NEXT: (i32.const 1) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (type $0 (func (param i32))) + + ;; ZERO___: (type $1 (func (param i32 i32 i32 i32 i32))) + + ;; ZERO___: (type $2 (func)) + + ;; ZERO___: (type $3 (func (param i32 i32))) + + ;; ZERO___: (type $4 (func (param i32 i32 i32))) + + ;; ZERO___: (type $5 (func (param i32 i32 i32 i32))) + + ;; ZERO___: (memory $0 10 20) + + ;; ZERO___: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + ;; ZERO___-NEXT: (i32.store + ;; ZERO___-NEXT: (i32.const 10) + ;; ZERO___-NEXT: (i32.div_s + ;; ZERO___-NEXT: (local.get $0) + ;; ZERO___-NEXT: (i32.add + ;; ZERO___-NEXT: (local.get $0) + ;; ZERO___-NEXT: (i32.const 1) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (i32.store + ;; ZERO___-NEXT: (i32.const 20) + ;; ZERO___-NEXT: (i32.div_s + ;; ZERO___-NEXT: (local.get $1) + ;; ZERO___-NEXT: (i32.add + ;; ZERO___-NEXT: (local.get $1) + ;; ZERO___-NEXT: (i32.const 1) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (i32.store + ;; ZERO___-NEXT: (i32.const 30) + ;; ZERO___-NEXT: (i32.div_s + ;; ZERO___-NEXT: (local.get $2) + ;; ZERO___-NEXT: (i32.add + ;; ZERO___-NEXT: (local.get $2) + ;; ZERO___-NEXT: (i32.const 1) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (i32.store + ;; ZERO___-NEXT: (i32.const 40) + ;; ZERO___-NEXT: (i32.div_s + ;; ZERO___-NEXT: (local.get $3) + ;; ZERO___-NEXT: (i32.add + ;; ZERO___-NEXT: (local.get $3) + ;; ZERO___-NEXT: (i32.const 1) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (i32.store + ;; ZERO___-NEXT: (i32.const 50) + ;; ZERO___-NEXT: (i32.div_s + ;; ZERO___-NEXT: (local.get $4) + ;; ZERO___-NEXT: (i32.add + ;; ZERO___-NEXT: (local.get $4) + ;; ZERO___-NEXT: (i32.const 1) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; THIRD__: (type $0 (func (param i32))) + + ;; THIRD__: (type $1 (func (param i32 i32 i32 i32 i32))) + + ;; THIRD__: (type $2 (func)) + + ;; THIRD__: (type $3 (func (param i32 i32))) + + ;; THIRD__: (memory $0 10 20) + + ;; THIRD__: (func $target (type $1) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + ;; THIRD__-NEXT: (i32.store + ;; THIRD__-NEXT: (i32.const 10) + ;; THIRD__-NEXT: (i32.div_s + ;; THIRD__-NEXT: (local.get $0) + ;; THIRD__-NEXT: (i32.add + ;; THIRD__-NEXT: (local.get $0) + ;; THIRD__-NEXT: (i32.const 1) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (i32.store + ;; THIRD__-NEXT: (i32.const 20) + ;; THIRD__-NEXT: (i32.div_s + ;; THIRD__-NEXT: (local.get $1) + ;; THIRD__-NEXT: (i32.add + ;; THIRD__-NEXT: (local.get $1) + ;; THIRD__-NEXT: (i32.const 1) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (i32.store + ;; THIRD__-NEXT: (i32.const 30) + ;; THIRD__-NEXT: (i32.div_s + ;; THIRD__-NEXT: (local.get $2) + ;; THIRD__-NEXT: (i32.add + ;; THIRD__-NEXT: (local.get $2) + ;; THIRD__-NEXT: (i32.const 1) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (i32.store + ;; THIRD__-NEXT: (i32.const 40) + ;; THIRD__-NEXT: (i32.div_s + ;; THIRD__-NEXT: (local.get $3) + ;; THIRD__-NEXT: (i32.add + ;; THIRD__-NEXT: (local.get $3) + ;; THIRD__-NEXT: (i32.const 1) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (i32.store + ;; THIRD__-NEXT: (i32.const 50) + ;; THIRD__-NEXT: (i32.div_s + ;; THIRD__-NEXT: (local.get $4) + ;; THIRD__-NEXT: (i32.add + ;; THIRD__-NEXT: (local.get $4) + ;; THIRD__-NEXT: (i32.const 1) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (type $0 (func (param i32 i32 i32 i32 i32))) + + ;; TWOTRDS: (type $1 (func (param i32))) + + ;; TWOTRDS: (type $2 (func)) + + ;; TWOTRDS: (memory $0 10 20) + + ;; TWOTRDS: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + ;; TWOTRDS-NEXT: (i32.store + ;; TWOTRDS-NEXT: (i32.const 10) + ;; TWOTRDS-NEXT: (i32.div_s + ;; TWOTRDS-NEXT: (local.get $0) + ;; TWOTRDS-NEXT: (i32.add + ;; TWOTRDS-NEXT: (local.get $0) + ;; TWOTRDS-NEXT: (i32.const 1) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (i32.store + ;; TWOTRDS-NEXT: (i32.const 20) + ;; TWOTRDS-NEXT: (i32.div_s + ;; TWOTRDS-NEXT: (local.get $1) + ;; TWOTRDS-NEXT: (i32.add + ;; TWOTRDS-NEXT: (local.get $1) + ;; TWOTRDS-NEXT: (i32.const 1) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (i32.store + ;; TWOTRDS-NEXT: (i32.const 30) + ;; TWOTRDS-NEXT: (i32.div_s + ;; TWOTRDS-NEXT: (local.get $2) + ;; TWOTRDS-NEXT: (i32.add + ;; TWOTRDS-NEXT: (local.get $2) + ;; TWOTRDS-NEXT: (i32.const 1) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (i32.store + ;; TWOTRDS-NEXT: (i32.const 40) + ;; TWOTRDS-NEXT: (i32.div_s + ;; TWOTRDS-NEXT: (local.get $3) + ;; TWOTRDS-NEXT: (i32.add + ;; TWOTRDS-NEXT: (local.get $3) + ;; TWOTRDS-NEXT: (i32.const 1) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (i32.store + ;; TWOTRDS-NEXT: (i32.const 50) + ;; TWOTRDS-NEXT: (i32.div_s + ;; TWOTRDS-NEXT: (local.get $4) + ;; TWOTRDS-NEXT: (i32.add + ;; TWOTRDS-NEXT: (local.get $4) + ;; TWOTRDS-NEXT: (i32.const 1) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (type $0 (func (param i32 i32 i32 i32 i32))) + + ;; HUNDRED: (type $1 (func (param i32))) + + ;; HUNDRED: (memory $0 10 20) + + ;; HUNDRED: (func $target (type $0) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + ;; HUNDRED-NEXT: (i32.store + ;; HUNDRED-NEXT: (i32.const 10) + ;; HUNDRED-NEXT: (i32.div_s + ;; HUNDRED-NEXT: (local.get $0) + ;; HUNDRED-NEXT: (i32.add + ;; HUNDRED-NEXT: (local.get $0) + ;; HUNDRED-NEXT: (i32.const 1) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (i32.store + ;; HUNDRED-NEXT: (i32.const 20) + ;; HUNDRED-NEXT: (i32.div_s + ;; HUNDRED-NEXT: (local.get $1) + ;; HUNDRED-NEXT: (i32.add + ;; HUNDRED-NEXT: (local.get $1) + ;; HUNDRED-NEXT: (i32.const 1) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (i32.store + ;; HUNDRED-NEXT: (i32.const 30) + ;; HUNDRED-NEXT: (i32.div_s + ;; HUNDRED-NEXT: (local.get $2) + ;; HUNDRED-NEXT: (i32.add + ;; HUNDRED-NEXT: (local.get $2) + ;; HUNDRED-NEXT: (i32.const 1) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (i32.store + ;; HUNDRED-NEXT: (i32.const 40) + ;; HUNDRED-NEXT: (i32.div_s + ;; HUNDRED-NEXT: (local.get $3) + ;; HUNDRED-NEXT: (i32.add + ;; HUNDRED-NEXT: (local.get $3) + ;; HUNDRED-NEXT: (i32.const 1) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (i32.store + ;; HUNDRED-NEXT: (i32.const 50) + ;; HUNDRED-NEXT: (i32.div_s + ;; HUNDRED-NEXT: (local.get $4) + ;; HUNDRED-NEXT: (i32.add + ;; HUNDRED-NEXT: (local.get $4) + ;; HUNDRED-NEXT: (i32.const 1) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $target (param $a i32) (param $b i32) (param $c i32) (param $d i32) (param $e i32) + ;; This function takes five parameters and uses each one to do some work. In + ;; Each of the following identical stores, when we know one of the five + ;; params, we can compute in full the value stored. (The store offsets + ;; differ to guard against a future dead store elimination.) + (i32.store + (i32.const 10) + (i32.div_s + (local.get $a) + (i32.add + (local.get $a) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.const 20) + (i32.div_s + (local.get $b) + (i32.add + (local.get $b) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.const 30) + (i32.div_s + (local.get $c) + (i32.add + (local.get $c) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.const 40) + (i32.div_s + (local.get $d) + (i32.add + (local.get $d) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.const 50) + (i32.div_s + (local.get $e) + (i32.add + (local.get $e) + (i32.const 1) + ) + ) + ) + ) + + ;; DEFAULT: (func $calls (type $1) (param $x i32) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (func $calls (type $0) (param $x i32) + ;; ZERO___-NEXT: (call $target_2) + ;; ZERO___-NEXT: (call $target_3 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target_4 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target_5 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target_6 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; THIRD__: (func $calls (type $0) (param $x i32) + ;; THIRD__-NEXT: (call $target_2) + ;; THIRD__-NEXT: (call $target_3 + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target_4 + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (i32.const 42) + ;; THIRD__-NEXT: (i32.const 42) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (i32.const 42) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (func $calls (type $1) (param $x i32) + ;; TWOTRDS-NEXT: (call $target_2) + ;; TWOTRDS-NEXT: (call $target + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (func $calls (type $1) (param $x i32) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $target + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $calls (param $x i32) + ;; Call the target with an increasing amount of non-constant params, 0-5. + ;; + ;; With 5 unknowns, the call context is trivial and we do nothing. All the + ;; differences are therefore on 0-4: + ;; + ;; * ZERO monomorphizes all of 0-4. + ;; * THIRD monomorphizes only 0-2. + ;; * TWOTRDS monomorphizes just 0. + ;; * HUNDRED monomorphizes none at all. + + (call $target + (i32.const 42) + (i32.const 42) + (i32.const 42) + (i32.const 42) + (i32.const 42) + ) + (call $target + (local.get $x) + (i32.const 42) + (i32.const 42) + (i32.const 42) + (i32.const 42) + ) + (call $target + (local.get $x) + (local.get $x) + (i32.const 42) + (i32.const 42) + (i32.const 42) + ) + (call $target + (local.get $x) + (local.get $x) + (local.get $x) + (i32.const 42) + (i32.const 42) + ) + (call $target + (local.get $x) + (local.get $x) + (local.get $x) + (local.get $x) + (i32.const 42) + ) + (call $target + (local.get $x) + (local.get $x) + (local.get $x) + (local.get $x) + (local.get $x) + ) + ) +) + +;; ZERO___: (func $target_2 (type $2) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 10) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 20) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 30) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 40) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 50) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target_3 (type $0) (param $0 i32) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 10) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 20) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 30) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 40) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 50) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target_4 (type $3) (param $0 i32) (param $1 i32) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 10) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 20) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 30) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 40) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 50) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target_5 (type $4) (param $0 i32) (param $1 i32) (param $2 i32) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 10) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 20) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 30) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $2) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $2) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 40) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 50) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target_6 (type $5) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 10) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 20) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 30) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $2) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $2) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 40) +;; ZERO___-NEXT: (i32.div_s +;; ZERO___-NEXT: (local.get $3) +;; ZERO___-NEXT: (i32.add +;; ZERO___-NEXT: (local.get $3) +;; ZERO___-NEXT: (i32.const 1) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (i32.store +;; ZERO___-NEXT: (i32.const 50) +;; ZERO___-NEXT: (i32.const 0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; THIRD__: (func $target_2 (type $2) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 10) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 20) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 30) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 40) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 50) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target_3 (type $0) (param $0 i32) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 10) +;; THIRD__-NEXT: (i32.div_s +;; THIRD__-NEXT: (local.get $0) +;; THIRD__-NEXT: (i32.add +;; THIRD__-NEXT: (local.get $0) +;; THIRD__-NEXT: (i32.const 1) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 20) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 30) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 40) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 50) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target_4 (type $3) (param $0 i32) (param $1 i32) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 10) +;; THIRD__-NEXT: (i32.div_s +;; THIRD__-NEXT: (local.get $0) +;; THIRD__-NEXT: (i32.add +;; THIRD__-NEXT: (local.get $0) +;; THIRD__-NEXT: (i32.const 1) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 20) +;; THIRD__-NEXT: (i32.div_s +;; THIRD__-NEXT: (local.get $1) +;; THIRD__-NEXT: (i32.add +;; THIRD__-NEXT: (local.get $1) +;; THIRD__-NEXT: (i32.const 1) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 30) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 40) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: (i32.store +;; THIRD__-NEXT: (i32.const 50) +;; THIRD__-NEXT: (i32.const 0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) + +;; TWOTRDS: (func $target_2 (type $2) +;; TWOTRDS-NEXT: (i32.store +;; TWOTRDS-NEXT: (i32.const 10) +;; TWOTRDS-NEXT: (i32.const 0) +;; TWOTRDS-NEXT: ) +;; TWOTRDS-NEXT: (i32.store +;; TWOTRDS-NEXT: (i32.const 20) +;; TWOTRDS-NEXT: (i32.const 0) +;; TWOTRDS-NEXT: ) +;; TWOTRDS-NEXT: (i32.store +;; TWOTRDS-NEXT: (i32.const 30) +;; TWOTRDS-NEXT: (i32.const 0) +;; TWOTRDS-NEXT: ) +;; TWOTRDS-NEXT: (i32.store +;; TWOTRDS-NEXT: (i32.const 40) +;; TWOTRDS-NEXT: (i32.const 0) +;; TWOTRDS-NEXT: ) +;; TWOTRDS-NEXT: (i32.store +;; TWOTRDS-NEXT: (i32.const 50) +;; TWOTRDS-NEXT: (i32.const 0) +;; TWOTRDS-NEXT: ) +;; TWOTRDS-NEXT: ) +(module + ;; DEFAULT: (type $A (sub (struct (field i32)))) + ;; ZERO___: (type $A (sub (struct (field i32)))) + ;; THIRD__: (type $A (sub (struct (field i32)))) + ;; TWOTRDS: (type $A (sub (struct (field i32)))) + ;; HUNDRED: (type $A (sub (struct (field i32)))) + (type $A (sub (struct (field i32)))) + + ;; DEFAULT: (type $1 (func)) + + ;; DEFAULT: (type $2 (func (param anyref) (result (ref $A)))) + + ;; DEFAULT: (type $3 (func (param anyref i32))) + + ;; DEFAULT: (type $4 (func (param (ref $A)))) + + ;; DEFAULT: (type $5 (func (param anyref))) + + ;; DEFAULT: (type $6 (func (param i32))) + + ;; DEFAULT: (import "a" "b" (func $import (type $1))) + ;; ZERO___: (type $1 (func)) + + ;; ZERO___: (type $2 (func (param anyref) (result (ref $A)))) + + ;; ZERO___: (type $3 (func (param anyref i32))) + + ;; ZERO___: (type $4 (func (param anyref))) + + ;; ZERO___: (type $5 (func (param i32) (result (ref $A)))) + + ;; ZERO___: (type $6 (func (param i32))) + + ;; ZERO___: (type $7 (func (result (ref $A)))) + + ;; ZERO___: (type $8 (func (param (ref $A)))) + + ;; ZERO___: (import "a" "b" (func $import (type $1))) + ;; THIRD__: (type $1 (func)) + + ;; THIRD__: (type $2 (func (param anyref) (result (ref $A)))) + + ;; THIRD__: (type $3 (func (param anyref i32))) + + ;; THIRD__: (type $4 (func (param (ref $A)))) + + ;; THIRD__: (type $5 (func (param anyref))) + + ;; THIRD__: (type $6 (func (param i32) (result (ref $A)))) + + ;; THIRD__: (type $7 (func (param i32))) + + ;; THIRD__: (type $8 (func (result (ref $A)))) + + ;; THIRD__: (import "a" "b" (func $import (type $1))) + ;; TWOTRDS: (type $1 (func)) + + ;; TWOTRDS: (type $2 (func (param anyref) (result (ref $A)))) + + ;; TWOTRDS: (type $3 (func (param anyref i32))) + + ;; TWOTRDS: (type $4 (func (param (ref $A)))) + + ;; TWOTRDS: (type $5 (func (param anyref))) + + ;; TWOTRDS: (type $6 (func (param i32))) + + ;; TWOTRDS: (import "a" "b" (func $import (type $1))) + ;; HUNDRED: (type $1 (func (param anyref) (result (ref $A)))) + + ;; HUNDRED: (type $2 (func (param anyref i32))) + + ;; HUNDRED: (type $3 (func)) + + ;; HUNDRED: (type $4 (func (param (ref $A)))) + + ;; HUNDRED: (import "a" "b" (func $import (type $3))) + (import "a" "b" (func $import)) + + ;; DEFAULT: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) + ;; ZERO___: (import "a" "c" (func $import2 (type $8) (param (ref $A)))) + ;; THIRD__: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) + ;; TWOTRDS: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) + ;; HUNDRED: (import "a" "c" (func $import2 (type $4) (param (ref $A)))) + (import "a" "c" (func $import2 (param (ref $A)))) + + ;; DEFAULT: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (call $import) + ;; DEFAULT-NEXT: (ref.cast (ref $A) + ;; DEFAULT-NEXT: (local.get $0) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (call $import) + ;; ZERO___-NEXT: (ref.cast (ref $A) + ;; ZERO___-NEXT: (local.get $0) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; THIRD__: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (call $import) + ;; THIRD__-NEXT: (ref.cast (ref $A) + ;; THIRD__-NEXT: (local.get $0) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (func $target-long (type $2) (param $0 anyref) (result (ref $A)) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (call $import) + ;; TWOTRDS-NEXT: (ref.cast (ref $A) + ;; TWOTRDS-NEXT: (local.get $0) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (func $target-long (type $1) (param $0 anyref) (result (ref $A)) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (call $import) + ;; HUNDRED-NEXT: (ref.cast (ref $A) + ;; HUNDRED-NEXT: (local.get $0) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $target-long (param $any anyref) (result (ref $A)) + ;; This function does a cast, aside from a lot of other work. The other work + ;; causes us to only optimize when we are ok with getting a very small % of + ;; improvement. + (call $import) + (call $import) + (call $import) + (call $import) + (call $import) + (call $import) + (ref.cast (ref $A) + (local.get $any) + ) + ) + + ;; DEFAULT: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) + ;; DEFAULT-NEXT: (ref.cast (ref $A) + ;; DEFAULT-NEXT: (local.get $0) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) + ;; ZERO___-NEXT: (ref.cast (ref $A) + ;; ZERO___-NEXT: (local.get $0) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; THIRD__: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) + ;; THIRD__-NEXT: (ref.cast (ref $A) + ;; THIRD__-NEXT: (local.get $0) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (func $target-short (type $2) (param $0 anyref) (result (ref $A)) + ;; TWOTRDS-NEXT: (ref.cast (ref $A) + ;; TWOTRDS-NEXT: (local.get $0) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (func $target-short (type $1) (param $0 anyref) (result (ref $A)) + ;; HUNDRED-NEXT: (ref.cast (ref $A) + ;; HUNDRED-NEXT: (local.get $0) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $target-short (param $any anyref) (result (ref $A)) + ;; As above, but without all the work in the middle: this is really just a + ;; simple casting function, and we can remove almost all the work here when + ;; we remove the cast, meaning we optimize in more cases. + (ref.cast (ref $A) + (local.get $any) + ) + ) + + ;; DEFAULT: (func $calls-long (type $3) (param $x anyref) (param $y i32) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (drop + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (local.get $y) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (drop + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (local.get $y) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (drop + ;; DEFAULT-NEXT: (call $target-long + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (func $calls-long (type $3) (param $x anyref) (param $y i32) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-long + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-long_6 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-long_7 + ;; ZERO___-NEXT: (local.get $y) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-long_8 + ;; ZERO___-NEXT: (local.get $y) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-long_9) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-long_10) + ;; ZERO___-NEXT: ) + ;; THIRD__: (func $calls-long (type $3) (param $x anyref) (param $y i32) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-long + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (drop + ;; THIRD__-NEXT: (call $target-long + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-long + ;; THIRD__-NEXT: (struct.new $A + ;; THIRD__-NEXT: (local.get $y) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (drop + ;; THIRD__-NEXT: (call $target-long + ;; THIRD__-NEXT: (struct.new $A + ;; THIRD__-NEXT: (local.get $y) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-long + ;; THIRD__-NEXT: (struct.new $A + ;; THIRD__-NEXT: (i32.const 42) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target-long_6) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (func $calls-long (type $3) (param $x anyref) (param $y i32) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (drop + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (local.get $y) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (drop + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (local.get $y) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (drop + ;; TWOTRDS-NEXT: (call $target-long + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (func $calls-long (type $2) (param $x anyref) (param $y i32) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (local.get $y) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (local.get $y) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-long + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $calls-long (param $x anyref) (param $y i32) + ;; Various calls to $target-long. Because of the large amount of work that + ;; cannot be removed there, all we do here is: + ;; * Optimize in all cases when the minimum benefit is 0% (except the + ;; first call, which is a trivial call context). Removing a cast is + ;; enough to justify optimizing. + ;; * In 33% we optimize only the very last case. There we remove both a + ;; cast and a struct.new, which ends up just over 33%. + ;; * In 66% and 100% we optimize nothing at all. + + ;; Call with an unknown input and the output is sent to an import. + (call $import2 + (call $target-long + (local.get $x) + ) + ) + ;; Ditto, but drop the output. + (drop + (call $target-long + (local.get $x) + ) + ) + ;; Calls with a struct.new input. + (call $import2 + (call $target-long + (struct.new $A + (local.get $y) + ) + ) + ) + (drop + (call $target-long + (struct.new $A + (local.get $y) + ) + ) + ) + ;; Now the struct.new has a constant input. + (call $import2 + (call $target-long + (struct.new $A + (i32.const 42) + ) + ) + ) + (drop + (call $target-long + (struct.new $A + (i32.const 42) + ) + ) + ) + ) + + ;; DEFAULT: (func $calls-short (type $3) (param $x anyref) (param $y i32) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-short + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target-short_6 + ;; DEFAULT-NEXT: (local.get $x) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-short + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (local.get $y) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target-short_7 + ;; DEFAULT-NEXT: (local.get $y) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $import2 + ;; DEFAULT-NEXT: (call $target-short + ;; DEFAULT-NEXT: (struct.new $A + ;; DEFAULT-NEXT: (i32.const 42) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: ) + ;; DEFAULT-NEXT: (call $target-short_8) + ;; DEFAULT-NEXT: ) + ;; ZERO___: (func $calls-short (type $3) (param $x anyref) (param $y i32) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-short + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-short_11 + ;; ZERO___-NEXT: (local.get $x) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-short_12 + ;; ZERO___-NEXT: (local.get $y) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-short_13 + ;; ZERO___-NEXT: (local.get $y) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $import2 + ;; ZERO___-NEXT: (call $target-short_14) + ;; ZERO___-NEXT: ) + ;; ZERO___-NEXT: (call $target-short_15) + ;; ZERO___-NEXT: ) + ;; THIRD__: (func $calls-short (type $3) (param $x anyref) (param $y i32) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-short + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target-short_7 + ;; THIRD__-NEXT: (local.get $x) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-short_8 + ;; THIRD__-NEXT: (local.get $y) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target-short_9 + ;; THIRD__-NEXT: (local.get $y) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $import2 + ;; THIRD__-NEXT: (call $target-short_10) + ;; THIRD__-NEXT: ) + ;; THIRD__-NEXT: (call $target-short_11) + ;; THIRD__-NEXT: ) + ;; TWOTRDS: (func $calls-short (type $3) (param $x anyref) (param $y i32) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-short + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target-short_6 + ;; TWOTRDS-NEXT: (local.get $x) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-short + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (local.get $y) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target-short_7 + ;; TWOTRDS-NEXT: (local.get $y) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $import2 + ;; TWOTRDS-NEXT: (call $target-short + ;; TWOTRDS-NEXT: (struct.new $A + ;; TWOTRDS-NEXT: (i32.const 42) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: ) + ;; TWOTRDS-NEXT: (call $target-short_8) + ;; TWOTRDS-NEXT: ) + ;; HUNDRED: (func $calls-short (type $2) (param $x anyref) (param $y i32) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (local.get $x) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (local.get $y) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (local.get $y) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (call $import2 + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: (drop + ;; HUNDRED-NEXT: (call $target-short + ;; HUNDRED-NEXT: (struct.new $A + ;; HUNDRED-NEXT: (i32.const 42) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + ;; HUNDRED-NEXT: ) + (func $calls-short (param $x anyref) (param $y i32) + ;; As above, but now calling the short function: + ;; * 0% is the same with the long function: any improvement is enough. + ;; * 33% optimizes them all (but for the first, which is a trivial call + ;; context). + ;; * 66% optimizes a few less cases: when the output isn't dropped then we + ;; can't do enough work to justify it. + ;; * 100% optimizes nothing. + (call $import2 + (call $target-short + (local.get $x) + ) + ) + (drop + (call $target-short + (local.get $x) + ) + ) + (call $import2 + (call $target-short + (struct.new $A + (local.get $y) + ) + ) + ) + (drop + (call $target-short + (struct.new $A + (local.get $y) + ) + ) + ) + (call $import2 + (call $target-short + (struct.new $A + (i32.const 42) + ) + ) + ) + (drop + (call $target-short + (struct.new $A + (i32.const 42) + ) + ) + ) + ) +) +;; DEFAULT: (func $target-short_6 (type $5) (param $0 anyref) +;; DEFAULT-NEXT: (nop) +;; DEFAULT-NEXT: ) + +;; DEFAULT: (func $target-short_7 (type $6) (param $0 i32) +;; DEFAULT-NEXT: (nop) +;; DEFAULT-NEXT: ) + +;; DEFAULT: (func $target-short_8 (type $1) +;; DEFAULT-NEXT: (nop) +;; DEFAULT-NEXT: ) + +;; ZERO___: (func $target-long_6 (type $4) (param $0 anyref) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-long_7 (type $5) (param $0 i32) (result (ref $A)) +;; ZERO___-NEXT: (local $1 (ref $A)) +;; ZERO___-NEXT: (local.set $1 +;; ZERO___-NEXT: (struct.new $A +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (local.get $1) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-long_8 (type $6) (param $0 i32) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-long_9 (type $7) (result (ref $A)) +;; ZERO___-NEXT: (local $0 (ref $A)) +;; ZERO___-NEXT: (local.set $0 +;; ZERO___-NEXT: (struct.new $A +;; ZERO___-NEXT: (i32.const 42) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-long_10 (type $1) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: (call $import) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-short_11 (type $4) (param $0 anyref) +;; ZERO___-NEXT: (nop) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-short_12 (type $5) (param $0 i32) (result (ref $A)) +;; ZERO___-NEXT: (struct.new $A +;; ZERO___-NEXT: (local.get $0) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-short_13 (type $6) (param $0 i32) +;; ZERO___-NEXT: (nop) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-short_14 (type $7) (result (ref $A)) +;; ZERO___-NEXT: (struct.new $A +;; ZERO___-NEXT: (i32.const 42) +;; ZERO___-NEXT: ) +;; ZERO___-NEXT: ) + +;; ZERO___: (func $target-short_15 (type $1) +;; ZERO___-NEXT: (nop) +;; ZERO___-NEXT: ) + +;; THIRD__: (func $target-long_6 (type $1) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: (call $import) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target-short_7 (type $5) (param $0 anyref) +;; THIRD__-NEXT: (nop) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target-short_8 (type $6) (param $0 i32) (result (ref $A)) +;; THIRD__-NEXT: (struct.new $A +;; THIRD__-NEXT: (local.get $0) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target-short_9 (type $7) (param $0 i32) +;; THIRD__-NEXT: (nop) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target-short_10 (type $8) (result (ref $A)) +;; THIRD__-NEXT: (struct.new $A +;; THIRD__-NEXT: (i32.const 42) +;; THIRD__-NEXT: ) +;; THIRD__-NEXT: ) + +;; THIRD__: (func $target-short_11 (type $1) +;; THIRD__-NEXT: (nop) +;; THIRD__-NEXT: ) + +;; TWOTRDS: (func $target-short_6 (type $5) (param $0 anyref) +;; TWOTRDS-NEXT: (nop) +;; TWOTRDS-NEXT: ) + +;; TWOTRDS: (func $target-short_7 (type $6) (param $0 i32) +;; TWOTRDS-NEXT: (nop) +;; TWOTRDS-NEXT: ) + +;; TWOTRDS: (func $target-short_8 (type $1) +;; TWOTRDS-NEXT: (nop) +;; TWOTRDS-NEXT: ) diff --git a/test/lit/passes/monomorphize-consts.wast b/test/lit/passes/monomorphize-consts.wast index d7136756977..1d18f6dab52 100644 --- a/test/lit/passes/monomorphize-consts.wast +++ b/test/lit/passes/monomorphize-consts.wast @@ -2,10 +2,11 @@ ;; As in monomorphize-types.wast, test in both "always" mode, which always ;; monomorphizes, and in "careful" mode which does it only when it appears to -;; actually help. +;; actually help, and use a minimum benefit of 0 to make it easy to write +;; small testcases. -;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS -;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -S -o - | filecheck %s --check-prefix CAREFUL (module ;; Test that constants are monomorphized. diff --git a/test/lit/passes/monomorphize-context.wast b/test/lit/passes/monomorphize-context.wast index d3bc4a242e0..e4391d3a57a 100644 --- a/test/lit/passes/monomorphize-context.wast +++ b/test/lit/passes/monomorphize-context.wast @@ -2,10 +2,11 @@ ;; As in monomorphize-types.wast, test in both "always" mode, which always ;; monomorphizes, and in "careful" mode which does it only when it appears to -;; actually help. +;; actually help, and use a minimum benefit of 0 to make it easy to write +;; small testcases. -;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS -;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -S -o - | filecheck %s --check-prefix CAREFUL (module ;; ALWAYS: (type $0 (func (param i32) (result i32))) diff --git a/test/lit/passes/monomorphize-drop.wast b/test/lit/passes/monomorphize-drop.wast index 63923f76841..a9f0e1f06df 100644 --- a/test/lit/passes/monomorphize-drop.wast +++ b/test/lit/passes/monomorphize-drop.wast @@ -2,10 +2,11 @@ ;; As in monomorphize-types.wast, test in both "always" mode, which always ;; monomorphizes, and in "careful" mode which does it only when it appears to -;; actually help. +;; actually help, and use a minimum benefit of 0 to make it easy to write +;; small testcases. -;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS -;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -S -o - | filecheck %s --check-prefix CAREFUL (module ;; Test that dropped functions are monomorphized, and the drop is reverse- diff --git a/test/lit/passes/monomorphize-types.wast b/test/lit/passes/monomorphize-types.wast index 7d90a0f87af..863ccc08678 100644 --- a/test/lit/passes/monomorphize-types.wast +++ b/test/lit/passes/monomorphize-types.wast @@ -1,10 +1,11 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; Test in both "always" mode, which always monomorphizes, and in "careful" -;; mode which does it only when it appears to actually help. +;; mode which does it only when it appears to actually help. Also use a minimum +;; benefit of 0 to make it easy to write small testcases in careful mode. -;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS -;; RUN: foreach %s %t wasm-opt --monomorphize -all -S -o - | filecheck %s --check-prefix CAREFUL +;; RUN: foreach %s %t wasm-opt --monomorphize-always -all -S -o - | filecheck %s --check-prefix ALWAYS +;; RUN: foreach %s %t wasm-opt --monomorphize --pass-arg=monomorphize-min-benefit@0 -all -S -o - | filecheck %s --check-prefix CAREFUL (module ;; ALWAYS: (type $A (sub (struct))) From bcb83fd68710daf1f5ddd8252d0a0a4557494ca7 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 14 Aug 2024 13:52:52 -0400 Subject: [PATCH 517/553] Count supertypes when collecting module types (#6838) Previously we included supertypes, but did not increase their count. This was done so that the output for the nominal type system, which introduced explicitly supertypes, would more closely match the output with the old equirecursive types system. Neither type system exists anymore and we only support the single, standard isorecursive type system, so we can now properly count supertypes. It turns out it doesn't make much of a difference in the test outputs anyway. --- src/ir/module-utils.cpp | 6 +----- test/lit/passes/cfp.wast | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 8ad1270864d..da2d7bb9f84 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -516,11 +516,7 @@ InsertOrderedMap getHeapTypeCounts(Module& wasm, if (auto super = ht.getDeclaredSuperType()) { if (!counts.counts.count(*super)) { noteNewType(*super); - // We should unconditionally count supertypes, but while the type - // system is in flux, skip counting them to keep the type orderings in - // nominal test outputs more similar to the orderings in the - // equirecursive outputs. FIXME - counts.include(*super); + counts.note(*super); } } diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index c3bc81a1bcf..cfc8c8d4937 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -658,17 +658,17 @@ ;; reference to the subtype (we never create a supertype) and so we ;; can optimize. (module - ;; CHECK: (type $0 (func)) - ;; CHECK: (type $struct (sub (struct (field i32)))) (type $struct (sub (struct i32))) + ;; CHECK: (type $1 (func)) + ;; CHECK: (type $substruct (sub $struct (struct (field i32) (field f64)))) (type $substruct (sub $struct (struct i32 f64))) ;; CHECK: (type $3 (func (param (ref null $struct)))) - ;; CHECK: (func $create (type $0) + ;; CHECK: (func $create (type $1) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $substruct ;; CHECK-NEXT: (i32.const 10) From cde2a52fc6d679d53d1c5b72b081992d53e01c6b Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 14 Aug 2024 15:03:48 -0400 Subject: [PATCH 518/553] Heap type `none` requires GC (#6840) Since reference types only introduced function and extern references, all of the types in the `any` hierarchy require GC, including `none`. Fixes #6839. --- src/wasm/wasm-type.cpp | 2 +- test/lit/binary/strings-nogc.test | 3 --- test/lit/validation/nullref-no-gc.wast | 11 +++++++++++ test/lit/validation/shared-null.wast | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 test/lit/validation/nullref-no-gc.wast diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 011c51e7b7e..34299a9a1ef 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1496,12 +1496,12 @@ FeatureSet HeapType::getFeatures() const { case HeapType::i31: case HeapType::struct_: case HeapType::array: + case HeapType::none: feats |= FeatureSet::ReferenceTypes | FeatureSet::GC; return; case HeapType::string: feats |= FeatureSet::ReferenceTypes | FeatureSet::Strings; return; - case HeapType::none: case HeapType::noext: case HeapType::nofunc: // Technically introduced in GC, but used internally as part of diff --git a/test/lit/binary/strings-nogc.test b/test/lit/binary/strings-nogc.test index 7aa21d75088..23fb489a3eb 100644 --- a/test/lit/binary/strings-nogc.test +++ b/test/lit/binary/strings-nogc.test @@ -5,8 +5,5 @@ (module (func $0 (local $0 stringref) - (local.set $0 - (ref.null none) - ) ) ) diff --git a/test/lit/validation/nullref-no-gc.wast b/test/lit/validation/nullref-no-gc.wast new file mode 100644 index 00000000000..27560b3ff77 --- /dev/null +++ b/test/lit/validation/nullref-no-gc.wast @@ -0,0 +1,11 @@ +;; Test that nullref without GC is a validation error. + +;; RUN: not wasm-opt %s -all --disable-gc 2>&1 | filecheck %s + +;; CHECK: all used types should be allowed + +(module + (func $test + (local nullref) + ) +) diff --git a/test/lit/validation/shared-null.wast b/test/lit/validation/shared-null.wast index 1c34873bb49..0e491dd90cd 100644 --- a/test/lit/validation/shared-null.wast +++ b/test/lit/validation/shared-null.wast @@ -4,7 +4,7 @@ ;; RUN: wasm-opt %s --enable-reference-types --enable-gc --enable-shared-everything -o - -S | filecheck %s --check-prefix SHARED ;; NO-SHARED: ref.null requires additional features -;; NO-SHARED: [--enable-reference-types --enable-shared-everything] +;; NO-SHARED: [--enable-reference-types --enable-gc --enable-shared-everything] ;; SHARED: (ref.null (shared none)) (module From ad0802226a180d9797d17bb7fee391c0d62f9913 Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Thu, 15 Aug 2024 16:40:49 +0100 Subject: [PATCH 519/553] Save build ID in a source map (#6799) This is based on these two proposals: * https://github.com/WebAssembly/tool-conventions/blob/main/BuildId.md * https://github.com/tc39/source-map/blob/main/proposals/debug-id.md --- src/wasm-binary.h | 1 + src/wasm/wasm-binary.cpp | 27 +++++++++++++++++- src/wasm/wasm.cpp | 1 + test/lit/binary/custom-section-build-id.test | 7 +++++ .../binary/custom-section-build-id.test.wasm | Bin 0 -> 29 bytes 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/lit/binary/custom-section-build-id.test create mode 100644 test/lit/binary/custom-section-build-id.test.wasm diff --git a/src/wasm-binary.h b/src/wasm-binary.h index d568abd6c4a..989ce891a5f 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -414,6 +414,7 @@ extern const char* Dylink; extern const char* Dylink0; extern const char* Linking; extern const char* Producers; +extern const char* BuildId; extern const char* TargetFeatures; extern const char* AtomicsFeature; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index d9985212fe2..4082fbf5f2a 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "ir/eh-utils.h" #include "ir/module-utils.h" @@ -1212,7 +1213,31 @@ void WasmBinaryWriter::initializeDebugInfo() { } void WasmBinaryWriter::writeSourceMapProlog() { - *sourceMap << "{\"version\":3,\"sources\":["; + *sourceMap << "{\"version\":3,"; + + for (const auto& section : wasm->customSections) { + if (section.name == BinaryConsts::CustomSections::BuildId) { + U32LEB ret; + size_t pos = 0; + ret.read([&]() { return section.data[pos++]; }); + + if (section.data.size() != pos + ret.value) { + std::cerr + << "warning: build id section with an incorrect size detected!\n"; + break; + } + + *sourceMap << "\"debugId\":\""; + for (size_t i = pos; i < section.data.size(); i++) { + *sourceMap << std::setfill('0') << std::setw(2) << std::hex + << static_cast(static_cast(section.data[i])); + } + *sourceMap << "\","; + break; + } + } + + *sourceMap << "\"sources\":["; for (size_t i = 0; i < wasm->debugInfoFileNames.size(); i++) { if (i > 0) { *sourceMap << ","; diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index ae70e4a2238..d138e422610 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -36,6 +36,7 @@ const char* Dylink = "dylink"; const char* Dylink0 = "dylink.0"; const char* Linking = "linking"; const char* Producers = "producers"; +const char* BuildId = "build_id"; const char* TargetFeatures = "target_features"; const char* AtomicsFeature = "atomics"; const char* BulkMemoryFeature = "bulk-memory"; diff --git a/test/lit/binary/custom-section-build-id.test b/test/lit/binary/custom-section-build-id.test new file mode 100644 index 00000000000..65d88675261 --- /dev/null +++ b/test/lit/binary/custom-section-build-id.test @@ -0,0 +1,7 @@ +# Verify that the build id is included in the source map. + +;; RUN: wasm-opt %s.wasm -o %t.wasm -osm %t.map +;; RUN: cat %t.map | filecheck %s + +;; CHECK: {"version":3,"debugId":"01ab23cd45ef67ab89","sources":[],"names":[],"mappings":""} + diff --git a/test/lit/binary/custom-section-build-id.test.wasm b/test/lit/binary/custom-section-build-id.test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..caa70f82100f71617145bb2dea6d3ba7f1f57206 GIT binary patch literal 29 jcmZQbEY4+Q00Lo-q|(fsl=#dPPR7;BXI Date: Thu, 15 Aug 2024 10:27:37 -0700 Subject: [PATCH 520/553] [NFC] Clean up Literal copy constructor (#6841) Diff without whitespace is smaller. * HeapType::ext was handled in two places. The second place was wrong, but not reached. * Near the end all we have left are refs, so no need to check isRef etc. * Simplify the code to get the heap type once. --- src/wasm/literal.cpp | 57 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index b0dcf5177b2..40a1f9519da 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -117,7 +117,11 @@ Literal::Literal(const Literal& other) : type(other.type) { new (&gcData) std::shared_ptr(); return; } - if (other.isData() || other.type.getHeapType().isMaybeShared(HeapType::ext)) { + // After handling nulls, only non-nullable Literals remain. + assert(!type.isNullable()); + + auto heapType = type.getHeapType(); + if (other.isData() || heapType.isMaybeShared(HeapType::ext)) { new (&gcData) std::shared_ptr(other.gcData); return; } @@ -125,35 +129,28 @@ Literal::Literal(const Literal& other) : type(other.type) { func = other.func; return; } - if (type.isRef()) { - assert(!type.isNullable()); - auto heapType = type.getHeapType(); - if (heapType.isBasic()) { - switch (heapType.getBasic(Unshared)) { - case HeapType::i31: - i32 = other.i32; - return; - case HeapType::ext: - gcData = other.gcData; - return; - case HeapType::none: - case HeapType::noext: - case HeapType::nofunc: - case HeapType::noexn: - case HeapType::nocont: - WASM_UNREACHABLE("null literals should already have been handled"); - case HeapType::any: - case HeapType::eq: - case HeapType::func: - case HeapType::cont: - case HeapType::struct_: - case HeapType::array: - case HeapType::exn: - WASM_UNREACHABLE("invalid type"); - case HeapType::string: - WASM_UNREACHABLE("TODO: string literals"); - } - } + switch (heapType.getBasic(Unshared)) { + case HeapType::i31: + i32 = other.i32; + return; + case HeapType::ext: + WASM_UNREACHABLE("handled above with isData()"); + case HeapType::none: + case HeapType::noext: + case HeapType::nofunc: + case HeapType::noexn: + case HeapType::nocont: + WASM_UNREACHABLE("null literals should already have been handled"); + case HeapType::any: + case HeapType::eq: + case HeapType::func: + case HeapType::cont: + case HeapType::struct_: + case HeapType::array: + case HeapType::exn: + WASM_UNREACHABLE("invalid type"); + case HeapType::string: + WASM_UNREACHABLE("TODO: string literals"); } } From 033a16ec0d063cbcfb6c67adcf228f70653a1bf5 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 15 Aug 2024 15:32:32 -0400 Subject: [PATCH 521/553] Simplify validation of stale types (#6842) The previous rules for stale types were complicated and hard to remember: in general it was ok for result types to be further refinable as long as they were not refinable all the way to `unreachable`, but control flow structures had a carve-out and it was ok for them to be refinable all the way to unreachable. Simplify the rules so that further refinable result types are always ok, no matter what they can be refined to and no matter what kind of instruction is being validated. This will be much easier to remember and reason about. This relaxation of the rules strictly increases the set of valid IR, so no passes or tests need to be updated. It does make it possible for us to miss type refinement opportunities that previously would have been validation errors, but only in cases where non-control-flow instructions could have been refined all the way to unreachable, so the risk seems small. --- src/wasm/wasm-validator.cpp | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index b35d1b3bed7..b032e6bad22 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3592,31 +3592,16 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) { auto oldType = curr->type; ReFinalizeNode().visit(curr); auto newType = curr->type; - if (newType != oldType) { - // We accept concrete => undefined on control flow structures: - // e.g. - // - // (drop (block (result i32) (unreachable))) - // - // The block has a type annotated on it, which can make its unreachable - // contents have a concrete type. Refinalize will make it unreachable, - // so both are valid here. - bool validControlFlowStructureChange = - Properties::isControlFlowStructure(curr) && oldType.isConcrete() && - newType == Type::unreachable; - // It's ok in general for types to get refined as long as they don't - // become unreachable. - bool validRefinement = - Type::isSubType(newType, oldType) && newType != Type::unreachable; - if (!validRefinement && !validControlFlowStructureChange) { - std::ostringstream ss; - ss << "stale type found in " << scope << " on " << curr - << "\n(marked as " << oldType << ", should be " << newType - << ")\n"; - info.fail(ss.str(), curr, getFunction()); - } - curr->type = oldType; + // It's ok for types to be further refinable, but they must admit a + // superset of the values allowed by the most precise possible type, i.e. + // they must not be strict subtypes of or unrelated to the refined type. + if (!Type::isSubType(newType, oldType)) { + std::ostringstream ss; + ss << "stale type found in " << scope << " on " << curr + << "\n(marked as " << oldType << ", should be " << newType << ")\n"; + info.fail(ss.str(), curr, getFunction()); } + curr->type = oldType; // check if a node is a duplicate - expressions must not be seen more than // once if (!seen.insert(curr).second) { From c2b43802c68a15d42c64f9404a398a842312f95a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 15 Aug 2024 16:24:55 -0700 Subject: [PATCH 522/553] [NFC] Avoid v128 in rec groups with no other v128 uses (#6843) We don't properly validate that yet. E.g.: (module (rec (type $func (func)) (type $unused (sub (struct (field v128)))) ) (func $func (type $func)) ) That v128 is not used, but it ends up in the output because it is in a rec group that is used. Atm we do not require that SIMD be enabled in such a case, which can trip up the fuzzer. Context: #6820. For now, modify the test that uncovered this. --- test/lit/passes/gto-removals.wast | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index c2e82aee9c8..c2ac66a5793 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1032,14 +1032,14 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field v128) (field nullref)))) - (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field eqref) (field nullref)))) + (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) - ;; CHECK: (type $C (sub $A (struct (field i64) (field v128) (field nullref) (field f64) (field anyref)))) - (type $C (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK: (type $C (sub $A (struct (field i64) (field eqref) (field nullref) (field f64) (field anyref)))) + (type $C (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) - ;; CHECK: (type $B (sub $A (struct (field i64) (field v128) (field nullref) (field f32) (field anyref)))) - (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK: (type $B (sub $A (struct (field i64) (field eqref) (field nullref) (field f32) (field anyref)))) + (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) ) ;; CHECK: (type $3 (func (param anyref))) @@ -1115,10 +1115,10 @@ ;; Field 2 (f32) is used only in $B. ;; Field 3 (f64) is used only in $C. ;; Field 4 (anyref) is used only in $B and $C. - ;; Field 5 (v128) is used only in $A and $C. + ;; Field 5 (eqref) is used only in $A and $C. ;; Field 6 (nullref) is used only in $A and $B. ;; As a result: - ;; * A can keep only fields 1, 5, 6 (i64, v128, nullref). + ;; * A can keep only fields 1, 5, 6 (i64, eqref, nullref). ;; * B keeps A's fields, and appends 2, 4 (f32, anyref). ;; * C keeps A's fields, and appends 3, 4 (f64, anyref). @@ -1145,14 +1145,14 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field v128) (field nullref)))) - (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK-NEXT: (type $A (sub (struct (field i64) (field eqref) (field nullref)))) + (type $A (sub (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) - ;; CHECK: (type $B (sub $A (struct (field i64) (field v128) (field nullref) (field f32) (field anyref)))) - (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK: (type $B (sub $A (struct (field i64) (field eqref) (field nullref) (field f32) (field anyref)))) + (type $B (sub $A (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) - ;; CHECK: (type $C (sub $B (struct (field i64) (field v128) (field nullref) (field f32) (field anyref) (field f64)))) - (type $C (sub $B (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field v128) (field nullref)))) + ;; CHECK: (type $C (sub $B (struct (field i64) (field eqref) (field nullref) (field f32) (field anyref) (field f64)))) + (type $C (sub $B (struct (field i32) (field i64) (field f32) (field f64) (field anyref) (field eqref) (field nullref)))) ) ;; CHECK: (type $3 (func (param anyref))) From 7209629bec3961fcc12b150ba6df546d3997b6c2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 16 Aug 2024 10:53:10 -0700 Subject: [PATCH 523/553] Testing: Add an env var to pick the V8 binary (#6836) Also we had a mix of os.environ.get and os.getenv. Prefer the former, as the default value does actual work, so it's a little more efficient to not run it unnecessarily. That is, os.getenv('X', work()) is less efficient than os.environ.get('X') or work(). --- scripts/test/shared.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index d593aa45b5a..91612a8d9d9 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -195,10 +195,10 @@ def is_exe(fpath): which('gcc') or which('clang')) NATIVEXX = (os.environ.get('CXX') or which('mingw32-g++') or which('g++') or which('clang++')) -NODEJS = os.getenv('NODE', which('node') or which('nodejs')) +NODEJS = os.environ.get('NODE') or which('node') or which('nodejs') MOZJS = which('mozjs') or which('spidermonkey') -V8 = which('v8') or which('d8') +V8 = os.environ.get('V8') or which('v8') or which('d8') BINARYEN_INSTALL_DIR = os.path.dirname(options.binaryen_bin) WASM_OPT = [os.path.join(options.binaryen_bin, 'wasm-opt')] From 958ff4115e542ef1d0ae712f4961e342386efe54 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 16 Aug 2024 12:53:52 -0700 Subject: [PATCH 524/553] Implement table.init (#6827) Also use TableInit in the interpreter to initialize module's table state, which will now handle traps properly, fixing #6431 --- scripts/gen-s-parser.py | 4 +- src/gen-s-parser.inc | 6 ++ src/ir/ReFinalize.cpp | 1 + src/ir/child-typer.h | 6 ++ src/ir/cost.h | 3 + src/ir/effects.h | 4 + src/ir/possible-contents.cpp | 1 + src/ir/subtype-exprs.h | 5 + src/parser/contexts.h | 13 +++ src/parser/parsers.h | 12 +++ src/passes/Directize.cpp | 3 + src/passes/Print.cpp | 6 ++ src/passes/Table64Lowering.cpp | 4 + src/passes/TypeGeneralizing.cpp | 2 + src/tools/wasm-ctor-eval.cpp | 24 +++-- src/wasm-binary.h | 2 + src/wasm-builder.h | 14 +++ src/wasm-delegations-fields.def | 8 ++ src/wasm-delegations.def | 1 + src/wasm-interpreter.h | 95 +++++++++++++++---- src/wasm-ir-builder.h | 1 + src/wasm.h | 15 +++ src/wasm/wasm-binary.cpp | 20 ++++ src/wasm/wasm-ir-builder.cpp | 8 ++ src/wasm/wasm-stack.cpp | 6 ++ src/wasm/wasm-validator.cpp | 36 ++++++- src/wasm/wasm.cpp | 8 ++ src/wasm2js.h | 4 + test/binaryen.js/exception-handling.js.txt | 8 +- test/binaryen.js/kitchen-sink.js.txt | 58 +++++------ test/lit/basic/table-operations.wast | 90 ++++++++++++------ test/lit/ctor-eval/table.init.wat | 62 ++++++++++++ test/lit/passes/directize_all-features.wast | 95 +++++++++++++++++++ .../passes/simplify-locals-table_copy.wast | 73 ++++++++++++++ test/lit/passes/table64-lowering.wast | 13 +++ test/lit/passes/unsubtyping.wast | 32 +++++++ test/spec/table_init.wast | 52 ++++++++++ 37 files changed, 700 insertions(+), 95 deletions(-) create mode 100644 test/lit/ctor-eval/table.init.wat create mode 100644 test/lit/passes/simplify-locals-table_copy.wast create mode 100644 test/spec/table_init.wast diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 3b2eb9d01b4..86826ad795f 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -560,9 +560,7 @@ ("table.grow", "makeTableGrow()"), ("table.fill", "makeTableFill()"), ("table.copy", "makeTableCopy()"), - # TODO: - # table.init - # + ("table.init", "makeTableInit()"), # exception handling instructions ("try", "makeTry()"), ("try_table", "makeTryTable()"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index d6eaf851db9..2fa658e65f3 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -4936,6 +4936,12 @@ switch (buf[0]) { default: goto parse_error; } } + case 'i': + if (op == "table.init"sv) { + CHECK_ERR(makeTableInit(ctx, pos, annotations)); + return Ok{}; + } + goto parse_error; case 's': { switch (buf[7]) { case 'e': diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 8fae5d0731a..0f78d37b7e9 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -126,6 +126,7 @@ void ReFinalize::visitTableSize(TableSize* curr) { curr->finalize(); } void ReFinalize::visitTableGrow(TableGrow* curr) { curr->finalize(); } void ReFinalize::visitTableFill(TableFill* curr) { curr->finalize(); } void ReFinalize::visitTableCopy(TableCopy* curr) { curr->finalize(); } +void ReFinalize::visitTableInit(TableInit* curr) { curr->finalize(); } void ReFinalize::visitTry(Try* curr) { curr->finalize(); } void ReFinalize::visitTryTable(TryTable* curr) { curr->finalize(); } void ReFinalize::visitThrow(Throw* curr) { curr->finalize(); } diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 2bfaefafff2..725bc842e27 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -742,6 +742,12 @@ template struct ChildTyper : OverriddenVisitor { note(&curr->size, Type::i32); } + void visitTableInit(TableInit* curr) { + note(&curr->dest, wasm.getTable(curr->table)->indexType); + note(&curr->offset, Type::i32); + note(&curr->size, Type::i32); + } + void visitTry(Try* curr) { note(&curr->body, curr->type); for (auto& expr : curr->catchBodies) { diff --git a/src/ir/cost.h b/src/ir/cost.h index ab8ae90ae43..11370acabb5 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -595,6 +595,9 @@ struct CostAnalyzer : public OverriddenVisitor { CostType visitTableCopy(TableCopy* curr) { return 6 + visit(curr->dest) + visit(curr->source) + visit(curr->size); } + CostType visitTableInit(TableInit* curr) { + return 6 + visit(curr->dest) + visit(curr->offset) + visit(curr->size); + } CostType visitTry(Try* curr) { // We assume no exception will be thrown in most cases return visit(curr->body); diff --git a/src/ir/effects.h b/src/ir/effects.h index be949a8bf57..fee8b344174 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -752,6 +752,10 @@ class EffectAnalyzer { parent.writesTable = true; parent.implicitTrap = true; } + void visitTableInit(TableInit* curr) { + parent.writesTable = true; + parent.implicitTrap = true; + } void visitTry(Try* curr) { if (curr->delegateTarget.is()) { parent.delegateTargets.insert(curr->delegateTarget); diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 38fa3e5f6cf..e7454c7c6d5 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -663,6 +663,7 @@ struct InfoCollector void visitTableGrow(TableGrow* curr) { addRoot(curr); } void visitTableFill(TableFill* curr) { addRoot(curr); } void visitTableCopy(TableCopy* curr) { addRoot(curr); } + void visitTableInit(TableInit* curr) {} void visitNop(Nop* curr) {} void visitUnreachable(Unreachable* curr) {} diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h index f563cce1453..640240df932 100644 --- a/src/ir/subtype-exprs.h +++ b/src/ir/subtype-exprs.h @@ -238,6 +238,11 @@ struct SubtypingDiscoverer : public OverriddenVisitor { self()->noteSubtype(self()->getModule()->getTable(curr->sourceTable)->type, self()->getModule()->getTable(curr->destTable)->type); } + void visitTableInit(TableInit* curr) { + auto* seg = self()->getModule()->getElementSegment(curr->segment); + self()->noteSubtype(seg->type, + self()->getModule()->getTable(curr->table)->type); + } void visitTry(Try* curr) { self()->noteSubtype(curr->body, curr); for (auto* body : curr->catchBodies) { diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 5acb842d67b..7e70b67764a 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -674,6 +674,10 @@ struct NullInstrParserCtx { makeTableCopy(Index, const std::vector&, TableIdxT*, TableIdxT*) { return Ok{}; } + Result<> + makeTableInit(Index, const std::vector&, TableIdxT*, ElemIdxT) { + return Ok{}; + } Result<> makeThrow(Index, const std::vector&, TagIdxT) { return Ok{}; } @@ -2325,6 +2329,15 @@ struct ParseDefsCtx : TypeParserCtx { return withLoc(pos, irBuilder.makeTableCopy(*dest, *src)); } + Result<> makeTableInit(Index pos, + const std::vector& annotations, + Name* table, + Name elem) { + auto t = getTable(pos, table); + CHECK_ERR(t); + return withLoc(pos, irBuilder.makeTableInit(elem, *t)); + } + Result<> makeThrow(Index pos, const std::vector& annotations, Name tag) { return withLoc(pos, irBuilder.makeThrow(tag)); diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 23286bb2805..85a1febb54f 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -206,6 +206,8 @@ Result<> makeTableFill(Ctx&, Index, const std::vector&); template Result<> makeTableCopy(Ctx&, Index, const std::vector&); template +Result<> makeTableInit(Ctx&, Index, const std::vector&); +template Result<> makeThrow(Ctx&, Index, const std::vector&); template Result<> makeRethrow(Ctx&, Index, const std::vector&); @@ -2067,6 +2069,16 @@ makeTableCopy(Ctx& ctx, Index pos, const std::vector& annotations) { pos, annotations, destTable.getPtr(), srcTable.getPtr()); } +template +Result<> +makeTableInit(Ctx& ctx, Index pos, const std::vector& annotations) { + auto table = maybeTableidx(ctx); + CHECK_ERR(table); + auto elem = elemidx(ctx); + CHECK_ERR(elem); + return ctx.makeTableInit(pos, annotations, table.getPtr(), *elem); +} + template Result<> makeThrow(Ctx& ctx, Index pos, const std::vector& annotations) { diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp index 6cb4e46d8c2..7faf2e23a4f 100644 --- a/src/passes/Directize.cpp +++ b/src/passes/Directize.cpp @@ -266,6 +266,9 @@ struct Directize : public Pass { void visitTableCopy(TableCopy* curr) { tablesWithSet.insert(curr->destTable); } + void visitTableInit(TableInit* curr) { + tablesWithSet.insert(curr->table); + } }; Finder(tablesWithSet).walkFunction(func); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 8bf30702c3d..3abe1f73821 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2055,6 +2055,12 @@ struct PrintExpressionContents o << ' '; curr->sourceTable.print(o); } + void visitTableInit(TableInit* curr) { + printMedium(o, "table.init "); + curr->table.print(o); + o << ' '; + curr->segment.print(o); + } void visitTry(Try* curr) { printMedium(o, "try"); if (curr->name.is()) { diff --git a/src/passes/Table64Lowering.cpp b/src/passes/Table64Lowering.cpp index 65c9a2a63c9..71fc6a6fe6d 100644 --- a/src/passes/Table64Lowering.cpp +++ b/src/passes/Table64Lowering.cpp @@ -91,6 +91,10 @@ struct Table64Lowering : public WalkerPass> { wrapAddress64(curr->size, curr->destTable); } + void visitTableInit(TableInit* curr) { + wrapAddress64(curr->dest, curr->table); + } + void visitCallIndirect(CallIndirect* curr) { wrapAddress64(curr->target, curr->table); } diff --git a/src/passes/TypeGeneralizing.cpp b/src/passes/TypeGeneralizing.cpp index faf01f173e8..fad55e50699 100644 --- a/src/passes/TypeGeneralizing.cpp +++ b/src/passes/TypeGeneralizing.cpp @@ -499,6 +499,8 @@ struct TransferFn : OverriddenVisitor { // Cannot generalize table types yet. } + void visitTableInit(TableInit* curr) {} + void visitTry(Try* curr) { WASM_UNREACHABLE("TODO"); } void visitTryTable(TryTable* curr) { WASM_UNREACHABLE("TODO"); } void visitThrow(Throw* curr) { WASM_UNREACHABLE("TODO"); } diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 22e666a52e3..6c72f1c73a8 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -86,13 +86,6 @@ class EvallingModuleRunner : public ModuleRunnerBase { return ModuleRunnerBase::visitGlobalGet(curr); } - - Flow visitTableSet(TableSet* curr) { - // TODO: Full dynamic table support. For now we stop evalling when we see a - // table.set. (To support this we need to track sets and add code to - // serialize them.) - throw FailToEvalException("table.set: TODO"); - } }; // Build an artificial `env` module based on a module's imports, so that the @@ -174,6 +167,9 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // not yet been re-added are a blind spot for it). std::unordered_set usedGlobalNames; + // Set to true after we create the instance. + bool instanceInitialized = false; + CtorEvalExternalInterface( std::map> linkedInstances_ = {}) { @@ -363,7 +359,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { } Index tableSize(Name tableName) override { - throw FailToEvalException("table size"); + // See callTable above, we assume the table is not modified FIXME + return wasm->getTableOrNull(tableName)->initial; } Literal tableLoad(Name tableName, Index index) override { @@ -371,7 +368,15 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { } // called during initialization - void tableStore(Name tableName, Index index, const Literal& value) override {} + void tableStore(Name tableName, Index index, const Literal& value) override { + // We allow stores to the table during initialization, but not after, as we + // assume the table does not change at runtime. + // TODO: Allow table changes by updating the table later like we do with the + // memory, by tracking and serializing them. + if (instanceInitialized) { + throw FailToEvalException("tableStore after init: TODO"); + } + } int8_t load8s(Address addr, Name memoryName) override { return doLoad(addr, memoryName); @@ -1294,6 +1299,7 @@ void evalCtors(Module& wasm, try { // create an instance for evalling EvallingModuleRunner instance(wasm, &interface, linkedInstances); + interface.instanceInitialized = true; // go one by one, in order, until we fail // TODO: if we knew priorities, we could reorder? for (auto& ctor : ctors) { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 989ce891a5f..32eb7657c59 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1078,6 +1078,7 @@ enum ASTNodes { TableSize = 0x10, TableFill = 0x11, TableCopy = 0x0e, + TableInit = 0x0c, RefNull = 0xd0, RefIsNull = 0xd1, RefFunc = 0xd2, @@ -1752,6 +1753,7 @@ class WasmBinaryReader { bool maybeVisitTableGrow(Expression*& out, uint32_t code); bool maybeVisitTableFill(Expression*& out, uint32_t code); bool maybeVisitTableCopy(Expression*& out, uint32_t code); + bool maybeVisitTableInit(Expression*& out, uint32_t code); bool maybeVisitRefI31(Expression*& out, uint32_t code); bool maybeVisitI31Get(Expression*& out, uint32_t code); bool maybeVisitRefTest(Expression*& out, uint32_t code); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index a4f1c5cf915..72d2a1db03b 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -775,6 +775,20 @@ class Builder { ret->finalize(); return ret; } + TableInit* makeTableInit(Name segment, + Expression* dest, + Expression* offset, + Expression* size, + Name table) { + auto* ret = wasm.allocator.alloc(); + ret->segment = segment; + ret->dest = dest; + ret->offset = offset; + ret->size = size; + ret->table = table; + ret->finalize(); + return ret; + } private: Try* makeTry(Name name, diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def index 03d46020e24..3be04022094 100644 --- a/src/wasm-delegations-fields.def +++ b/src/wasm-delegations-fields.def @@ -545,6 +545,14 @@ DELEGATE_FIELD_NAME_KIND(TableCopy, sourceTable, ModuleItemKind::Table) DELEGATE_FIELD_NAME_KIND(TableCopy, destTable, ModuleItemKind::Table) DELEGATE_FIELD_CASE_END(TableCopy) +DELEGATE_FIELD_CASE_START(TableInit) +DELEGATE_FIELD_CHILD(TableInit, size) +DELEGATE_FIELD_CHILD(TableInit, offset) +DELEGATE_FIELD_CHILD(TableInit, dest) +DELEGATE_FIELD_NAME_KIND(TableInit, segment, ModuleItemKind::ElementSegment) +DELEGATE_FIELD_NAME_KIND(TableInit, table, ModuleItemKind::Table) +DELEGATE_FIELD_CASE_END(TableInit) + DELEGATE_FIELD_CASE_START(Try) DELEGATE_FIELD_SCOPE_NAME_USE(Try, delegateTarget) DELEGATE_FIELD_CHILD_VECTOR(Try, catchBodies) diff --git a/src/wasm-delegations.def b/src/wasm-delegations.def index ea801ab9bb3..f4552a98b20 100644 --- a/src/wasm-delegations.def +++ b/src/wasm-delegations.def @@ -64,6 +64,7 @@ DELEGATE(TableSize); DELEGATE(TableGrow); DELEGATE(TableFill); DELEGATE(TableCopy); +DELEGATE(TableInit); DELEGATE(Try); DELEGATE(TryTable); DELEGATE(Throw); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 7fd5b3cd32a..644a141a227 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1417,6 +1417,7 @@ class ExpressionRunner : public OverriddenVisitor { Flow visitTableGrow(TableGrow* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTableFill(TableFill* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTableCopy(TableCopy* curr) { WASM_UNREACHABLE("unimp"); } + Flow visitTableInit(TableInit* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTry(Try* curr) { WASM_UNREACHABLE("unimp"); } Flow visitTryTable(TryTable* curr) { WASM_UNREACHABLE("unimp"); } Flow visitThrow(Throw* curr) { @@ -2354,6 +2355,10 @@ class ConstantExpressionRunner : public ExpressionRunner { NOTE_ENTER("TableCopy"); return Flow(NONCONSTANT_FLOW); } + Flow visitTableInit(TableInit* curr) { + NOTE_ENTER("TableInit"); + return Flow(NONCONSTANT_FLOW); + } Flow visitLoad(Load* curr) { NOTE_ENTER("Load"); return Flow(NONCONSTANT_FLOW); @@ -2821,23 +2826,24 @@ class ModuleRunnerBase : public ExpressionRunner { } } + Const zero; + zero.value = Literal(uint32_t(0)); + zero.finalize(); + ModuleUtils::iterActiveElementSegments(wasm, [&](ElementSegment* segment) { - Address offset = - (uint32_t)self()->visit(segment->offset).getSingleValue().geti32(); - - Table* table = wasm.getTable(segment->table); - ExternalInterface* extInterface = externalInterface; - Name tableName = segment->table; - if (table->imported()) { - auto inst = linkedInstances.at(table->module); - extInterface = inst->externalInterface; - tableName = inst->wasm.getExport(table->base)->value; - } + Const size; + size.value = Literal(uint32_t(segment->data.size())); + size.finalize(); - for (Index i = 0; i < segment->data.size(); ++i) { - Flow ret = self()->visit(segment->data[i]); - extInterface->tableStore(tableName, offset + i, ret.getSingleValue()); - } + TableInit init; + init.table = segment->table; + init.segment = segment->name; + init.dest = segment->offset; + init.offset = &zero; + init.size = &size; + init.finalize(); + + self()->visit(&init); droppedElementSegments.insert(segment->name); }); @@ -2865,9 +2871,10 @@ class ModuleRunnerBase : public ExpressionRunner { void initializeMemoryContents() { initializeMemorySizes(); - Const offset; - offset.value = Literal(uint32_t(0)); - offset.finalize(); + + Const zero; + zero.value = Literal(uint32_t(0)); + zero.finalize(); // apply active memory segments for (size_t i = 0, e = wasm.dataSegments.size(); i < e; ++i) { @@ -2883,7 +2890,7 @@ class ModuleRunnerBase : public ExpressionRunner { init.memory = segment->memory; init.segment = segment->name; init.dest = segment->offset; - init.offset = &offset; + init.offset = &zero; init.size = &size; init.finalize(); @@ -3251,6 +3258,54 @@ class ModuleRunnerBase : public ExpressionRunner { return {}; } + Flow visitTableInit(TableInit* curr) { + NOTE_ENTER("TableInit"); + Flow dest = self()->visit(curr->dest); + if (dest.breaking()) { + return dest; + } + Flow offset = self()->visit(curr->offset); + if (offset.breaking()) { + return offset; + } + Flow size = self()->visit(curr->size); + if (size.breaking()) { + return size; + } + NOTE_EVAL1(dest); + NOTE_EVAL1(offset); + NOTE_EVAL1(size); + + auto* segment = wasm.getElementSegment(curr->segment); + + Address destVal(dest.getSingleValue().getUnsigned()); + Address offsetVal(uint32_t(offset.getSingleValue().geti32())); + Address sizeVal(uint32_t(size.getSingleValue().geti32())); + + if (offsetVal + sizeVal > 0 && + droppedElementSegments.count(curr->segment)) { + trap("out of bounds segment access in table.init"); + } + if (offsetVal + sizeVal > segment->data.size()) { + trap("out of bounds segment access in table.init"); + } + auto info = getTableInstanceInfo(curr->table); + auto tableSize = info.interface()->tableSize(info.name); + if (destVal + sizeVal > tableSize) { + trap("out of bounds table access in table.init"); + } + for (size_t i = 0; i < sizeVal; ++i) { + // FIXME: We should not call visit() here more than once at runtime. The + // values in the segment should be computed once during startup, + // and then read here as needed. For example, if we had a + // struct.new here then we should not allocate a new struct each + // time we table.init that data. + auto value = self()->visit(segment->data[offsetVal + i]).getSingleValue(); + info.interface()->tableStore(info.name, destVal + i, value); + } + return {}; + } + Flow visitLocalGet(LocalGet* curr) { NOTE_ENTER("LocalGet"); auto index = curr->index; @@ -3741,7 +3796,7 @@ class ModuleRunnerBase : public ExpressionRunner { if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) { trap("out of bounds segment access in memory.init"); } - if ((uint64_t)offsetVal + sizeVal > segment->data.size()) { + if (offsetVal + sizeVal > segment->data.size()) { trap("out of bounds segment access in memory.init"); } auto info = getMemoryInstanceInfo(curr->memory); diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index eff8c85ad8d..d7a1dde87b9 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -169,6 +169,7 @@ class IRBuilder : public UnifiedExpressionVisitor> { [[nodiscard]] Result<> makeTableGrow(Name table); [[nodiscard]] Result<> makeTableFill(Name table); [[nodiscard]] Result<> makeTableCopy(Name destTable, Name srcTable); + [[nodiscard]] Result<> makeTableInit(Name elem, Name table); [[nodiscard]] Result<> makeTry(Name label, Type type); [[nodiscard]] Result<> makeTryTable(Name label, Type type, diff --git a/src/wasm.h b/src/wasm.h index e47b7c6edff..9d43a4f9fcc 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -678,6 +678,7 @@ class Expression { TableGrowId, TableFillId, TableCopyId, + TableInitId, TryId, TryTableId, ThrowId, @@ -1421,6 +1422,20 @@ class TableCopy : public SpecificExpression { void finalize(); }; +class TableInit : public SpecificExpression { +public: + TableInit() = default; + TableInit(MixedArena& allocator) : TableInit() {} + + Name segment; + Expression* dest; + Expression* offset; + Expression* size; + Name table; + + void finalize(); +}; + // 'try' from the old (Phase 3) EH proposal class Try : public SpecificExpression { public: diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 4082fbf5f2a..2abb32837a0 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4223,6 +4223,9 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { if (maybeVisitTableCopy(curr, opcode)) { break; } + if (maybeVisitTableInit(curr, opcode)) { + break; + } if (maybeVisitLoad(curr, opcode, BinaryConsts::MiscPrefix)) { break; } @@ -5646,6 +5649,23 @@ bool WasmBinaryReader::maybeVisitTableCopy(Expression*& out, uint32_t code) { return true; } +bool WasmBinaryReader::maybeVisitTableInit(Expression*& out, uint32_t code) { + if (code != BinaryConsts::TableInit) { + return false; + } + auto* curr = allocator.alloc(); + curr->size = popNonVoidExpression(); + curr->offset = popNonVoidExpression(); + curr->dest = popNonVoidExpression(); + Index segIdx = getU32LEB(); + elemRefs[segIdx].push_back(&curr->segment); + Index memIdx = getU32LEB(); + tableRefs[memIdx].push_back(&curr->table); + curr->finalize(); + out = curr; + return true; +} + bool WasmBinaryReader::maybeVisitBinary(Expression*& out, uint8_t code) { Binary* curr; #define INT_TYPED_CODE(code) \ diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 3db6238c4e1..2f2f3b595fe 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1523,6 +1523,14 @@ Result<> IRBuilder::makeTableCopy(Name destTable, Name srcTable) { return Ok{}; } +Result<> IRBuilder::makeTableInit(Name elem, Name table) { + TableInit curr; + curr.table = table; + CHECK_ERR(visitTableInit(&curr)); + push(builder.makeTableInit(elem, curr.dest, curr.offset, curr.size, table)); + return Ok{}; +} + Result<> IRBuilder::makeTry(Name label, Type type) { auto* tryy = wasm.allocator.alloc(); tryy->type = type; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index a9b582f43ed..1c2c2c42bac 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2053,6 +2053,12 @@ void BinaryInstWriter::visitTableCopy(TableCopy* curr) { o << U32LEB(parent.getTableIndex(curr->sourceTable)); } +void BinaryInstWriter::visitTableInit(TableInit* curr) { + o << int8_t(BinaryConsts::MiscPrefix) << U32LEB(BinaryConsts::TableInit); + o << U32LEB(parent.getElementSegmentIndex(curr->segment)); + o << U32LEB(parent.getTableIndex(curr->table)); +} + void BinaryInstWriter::visitTry(Try* curr) { breakStack.push_back(curr->name); o << int8_t(BinaryConsts::Try); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index b032e6bad22..758ae158e51 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -469,6 +469,7 @@ struct FunctionValidator : public WalkerPass> { void visitTableGrow(TableGrow* curr); void visitTableFill(TableFill* curr); void visitTableCopy(TableCopy* curr); + void visitTableInit(TableInit* curr); void noteDelegate(Name name, Expression* curr); void noteRethrow(Name name, Expression* curr); void visitTry(Try* curr); @@ -2443,12 +2444,41 @@ void FunctionValidator::visitTableCopy(TableCopy* curr) { curr, "table.copy source must have right type for dest"); } + shouldBeEqualOrFirstIsUnreachable(curr->dest->type, + destTable->indexType, + curr, + "table.copy dest must be valid"); + shouldBeEqualOrFirstIsUnreachable(curr->source->type, + sourceTable->indexType, + curr, + "table.copy source must be valid"); + Type sizeType = + sourceTable->is64() && destTable->is64() ? Type::i64 : Type::i32; shouldBeEqualOrFirstIsUnreachable( - curr->dest->type, Type(Type::i32), curr, "table.copy dest must be i32"); + curr->size->type, sizeType, curr, "table.copy size must be valid"); +} + +void FunctionValidator::visitTableInit(TableInit* curr) { + shouldBeTrue(getModule()->features.hasBulkMemory(), + curr, + "table.init requires bulk-memory [--enable-bulk-memory]"); + auto* segment = getModule()->getElementSegment(curr->segment); + auto* table = getModule()->getTableOrNull(curr->table); + if (shouldBeTrue(!!segment, curr, "table.init segment must exist") && + shouldBeTrue(!!table, curr, "table.init table must exist")) { + shouldBeSubType(segment->type, + table->type, + curr, + "table.init source must have right type for dest"); + } shouldBeEqualOrFirstIsUnreachable( - curr->source->type, Type(Type::i32), curr, "table.copy source must be i32"); + curr->dest->type, table->indexType, curr, "table.init dest must be valid"); + shouldBeEqualOrFirstIsUnreachable(curr->offset->type, + Type(Type::i32), + curr, + "table.init offset must be valid"); shouldBeEqualOrFirstIsUnreachable( - curr->size->type, Type(Type::i32), curr, "table.copy size must be i32"); + curr->size->type, Type(Type::i32), curr, "table.init size must be valid"); } void FunctionValidator::noteDelegate(Name name, Expression* curr) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index d138e422610..ff641c7eb0a 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -875,6 +875,14 @@ void TableCopy::finalize() { } } +void TableInit::finalize() { + type = Type::none; + if (dest->type == Type::unreachable || offset->type == Type::unreachable || + size->type == Type::unreachable) { + type = Type::unreachable; + } +} + void Try::finalize(std::optional type_) { if (type_) { type = *type_; diff --git a/src/wasm2js.h b/src/wasm2js.h index 7fa923ceb07..15ae019ea22 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -2241,6 +2241,10 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr, visit(curr->source, EXPRESSION_RESULT), visit(curr->size, EXPRESSION_RESULT)); } + Ref visitTableInit(TableInit* curr) { + unimplemented(curr); + WASM_UNREACHABLE("unimp"); + } Ref visitTry(Try* curr) { unimplemented(curr); WASM_UNREACHABLE("unimp"); diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt index d2a0c6dd62f..f8b71302538 100644 --- a/test/binaryen.js/exception-handling.js.txt +++ b/test/binaryen.js/exception-handling.js.txt @@ -34,7 +34,7 @@ ) ) -getExpressionInfo(throw) = {"id":53,"type":1,"tag":"e"} -getExpressionInfo(rethrow) = {"id":54,"type":1,"target":"l0"} -getExpressionInfo(try_catch) = {"id":51,"type":1,"name":"l0","hasCatchAll":0,"delegateTarget":"","isDelegate":0} -getExpressionInfo(try_delegate) = {"id":51,"type":0,"name":"try_outer","hasCatchAll":1,"delegateTarget":"","isDelegate":0} +getExpressionInfo(throw) = {"id":54,"type":1,"tag":"e"} +getExpressionInfo(rethrow) = {"id":55,"type":1,"target":"l0"} +getExpressionInfo(try_catch) = {"id":52,"type":1,"name":"l0","hasCatchAll":0,"delegateTarget":"","isDelegate":0} +getExpressionInfo(try_delegate) = {"id":52,"type":0,"name":"try_outer","hasCatchAll":1,"delegateTarget":"","isDelegate":0} diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 28922c2a0ab..212194c9c86 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -82,35 +82,35 @@ TableGetId: 45 TableSetId: 46 TableSizeId: 47 TableGrowId: 48 -TryId: 51 -ThrowId: 53 -RethrowId: 54 -TupleMakeId: 56 -TupleExtractId: 57 -RefI31Id: 58 -I31GetId: 59 -CallRefId: 60 -RefTestId: 61 -RefCastId: 62 -BrOnId: 63 -StructNewId: 64 -StructGetId: 65 -StructSetId: 66 -ArrayNewId: 67 -ArrayNewFixedId: 70 -ArrayGetId: 71 -ArraySetId: 72 -ArrayLenId: 73 -ArrayCopy: 74 -RefAs: 78 -StringNew: 79 -StringConst: 80 -StringMeasure: 81 -StringEncode: 82 -StringConcat: 83 -StringEq: 84 -StringWTF16Get: 85 -StringSliceWTF: 86 +TryId: 52 +ThrowId: 54 +RethrowId: 55 +TupleMakeId: 57 +TupleExtractId: 58 +RefI31Id: 59 +I31GetId: 60 +CallRefId: 61 +RefTestId: 62 +RefCastId: 63 +BrOnId: 64 +StructNewId: 65 +StructGetId: 66 +StructSetId: 67 +ArrayNewId: 68 +ArrayNewFixedId: 71 +ArrayGetId: 72 +ArraySetId: 73 +ArrayLenId: 74 +ArrayCopy: 75 +RefAs: 79 +StringNew: 80 +StringConst: 81 +StringMeasure: 82 +StringEncode: 83 +StringConcat: 84 +StringEq: 85 +StringWTF16Get: 86 +StringSliceWTF: 87 getExpressionInfo={"id":15,"type":4,"op":6} (f32.neg (f32.const -33.61199951171875) diff --git a/test/lit/basic/table-operations.wast b/test/lit/basic/table-operations.wast index 4ccbe6c6a4a..8999814107a 100644 --- a/test/lit/basic/table-operations.wast +++ b/test/lit/basic/table-operations.wast @@ -12,24 +12,24 @@ (module ;; CHECK-TEXT: (type $0 (func)) - ;; CHECK-TEXT: (type $1 (func (result i32))) + ;; CHECK-TEXT: (type $1 (func (param i32 i32 i32))) - ;; CHECK-TEXT: (type $2 (func (param i32) (result i32))) + ;; CHECK-TEXT: (type $2 (func (result i32))) - ;; CHECK-TEXT: (type $3 (func (param i32 funcref i32))) + ;; CHECK-TEXT: (type $3 (func (param i32) (result i32))) - ;; CHECK-TEXT: (type $4 (func (param i32 i32 i32))) + ;; CHECK-TEXT: (type $4 (func (param i32 funcref i32))) ;; CHECK-TEXT: (table $table-1 1 1 funcref) ;; CHECK-BIN: (type $0 (func)) - ;; CHECK-BIN: (type $1 (func (result i32))) + ;; CHECK-BIN: (type $1 (func (param i32 i32 i32))) - ;; CHECK-BIN: (type $2 (func (param i32) (result i32))) + ;; CHECK-BIN: (type $2 (func (result i32))) - ;; CHECK-BIN: (type $3 (func (param i32 funcref i32))) + ;; CHECK-BIN: (type $3 (func (param i32) (result i32))) - ;; CHECK-BIN: (type $4 (func (param i32 i32 i32))) + ;; CHECK-BIN: (type $4 (func (param i32 funcref i32))) ;; CHECK-BIN: (table $table-1 1 1 funcref) (table $table-1 funcref @@ -46,13 +46,17 @@ ;; CHECK-TEXT: (elem $implicit-elem_1 (table $table-2) (i32.const 0) func $bar $bar $bar) - ;; CHECK-TEXT: (func $foo (type $0) - ;; CHECK-TEXT-NEXT: (nop) - ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT: (elem $elem func) ;; CHECK-BIN: (elem $0 (table $table-1) (i32.const 0) func $foo) ;; CHECK-BIN: (elem $1 (table $table-2) (i32.const 0) func $bar $bar $bar) + ;; CHECK-BIN: (elem $elem func) + (elem $elem funcref) + + ;; CHECK-TEXT: (func $foo (type $0) + ;; CHECK-TEXT-NEXT: (nop) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $foo (type $0) ;; CHECK-BIN-NEXT: (nop) ;; CHECK-BIN-NEXT: ) @@ -131,23 +135,23 @@ ) ) - ;; CHECK-TEXT: (func $get-table-size (type $1) (result i32) + ;; CHECK-TEXT: (func $get-table-size (type $2) (result i32) ;; CHECK-TEXT-NEXT: (table.size $table-1) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $get-table-size (type $1) (result i32) + ;; CHECK-BIN: (func $get-table-size (type $2) (result i32) ;; CHECK-BIN-NEXT: (table.size $table-1) ;; CHECK-BIN-NEXT: ) (func $get-table-size (result i32) (table.size $table-1) ) - ;; CHECK-TEXT: (func $table-grow (type $2) (param $sz i32) (result i32) + ;; CHECK-TEXT: (func $table-grow (type $3) (param $sz i32) (result i32) ;; CHECK-TEXT-NEXT: (table.grow $table-1 ;; CHECK-TEXT-NEXT: (ref.null nofunc) ;; CHECK-TEXT-NEXT: (local.get $sz) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $table-grow (type $2) (param $sz i32) (result i32) + ;; CHECK-BIN: (func $table-grow (type $3) (param $sz i32) (result i32) ;; CHECK-BIN-NEXT: (table.grow $table-1 ;; CHECK-BIN-NEXT: (ref.null nofunc) ;; CHECK-BIN-NEXT: (local.get $sz) @@ -157,14 +161,14 @@ (table.grow $table-1 (ref.null func) (local.get $sz)) ) - ;; CHECK-TEXT: (func $table-fill (type $3) (param $dest i32) (param $value funcref) (param $size i32) + ;; CHECK-TEXT: (func $table-fill (type $4) (param $dest i32) (param $value funcref) (param $size i32) ;; CHECK-TEXT-NEXT: (table.fill $table-1 ;; CHECK-TEXT-NEXT: (local.get $dest) ;; CHECK-TEXT-NEXT: (local.get $value) ;; CHECK-TEXT-NEXT: (local.get $size) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $table-fill (type $3) (param $dest i32) (param $value funcref) (param $size i32) + ;; CHECK-BIN: (func $table-fill (type $4) (param $dest i32) (param $value funcref) (param $size i32) ;; CHECK-BIN-NEXT: (table.fill $table-1 ;; CHECK-BIN-NEXT: (local.get $dest) ;; CHECK-BIN-NEXT: (local.get $value) @@ -179,14 +183,14 @@ ) ) - ;; CHECK-TEXT: (func $table-copy (type $4) (param $dest i32) (param $source i32) (param $size i32) + ;; CHECK-TEXT: (func $table-copy (type $1) (param $dest i32) (param $source i32) (param $size i32) ;; CHECK-TEXT-NEXT: (table.copy $table-1 $table-2 ;; CHECK-TEXT-NEXT: (local.get $dest) ;; CHECK-TEXT-NEXT: (local.get $source) ;; CHECK-TEXT-NEXT: (local.get $size) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $table-copy (type $4) (param $dest i32) (param $source i32) (param $size i32) + ;; CHECK-BIN: (func $table-copy (type $1) (param $dest i32) (param $source i32) (param $size i32) ;; CHECK-BIN-NEXT: (table.copy $table-1 $table-2 ;; CHECK-BIN-NEXT: (local.get $dest) ;; CHECK-BIN-NEXT: (local.get $source) @@ -200,16 +204,38 @@ (local.get $size) ) ) + + ;; CHECK-TEXT: (func $table-init (type $1) (param $dest i32) (param $offset i32) (param $size i32) + ;; CHECK-TEXT-NEXT: (table.init $table-1 $elem + ;; CHECK-TEXT-NEXT: (local.get $dest) + ;; CHECK-TEXT-NEXT: (local.get $offset) + ;; CHECK-TEXT-NEXT: (local.get $size) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $table-init (type $1) (param $dest i32) (param $offset i32) (param $size i32) + ;; CHECK-BIN-NEXT: (table.init $table-1 $elem + ;; CHECK-BIN-NEXT: (local.get $dest) + ;; CHECK-BIN-NEXT: (local.get $offset) + ;; CHECK-BIN-NEXT: (local.get $size) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $table-init (param $dest i32) (param $offset i32) (param $size i32) + (table.init $table-1 $elem + (local.get $dest) + (local.get $offset) + (local.get $size) + ) + ) ) ;; CHECK-BIN-NODEBUG: (type $0 (func)) -;; CHECK-BIN-NODEBUG: (type $1 (func (result i32))) +;; CHECK-BIN-NODEBUG: (type $1 (func (param i32 i32 i32))) -;; CHECK-BIN-NODEBUG: (type $2 (func (param i32) (result i32))) +;; CHECK-BIN-NODEBUG: (type $2 (func (result i32))) -;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 funcref i32))) +;; CHECK-BIN-NODEBUG: (type $3 (func (param i32) (result i32))) -;; CHECK-BIN-NODEBUG: (type $4 (func (param i32 i32 i32))) +;; CHECK-BIN-NODEBUG: (type $4 (func (param i32 funcref i32))) ;; CHECK-BIN-NODEBUG: (table $0 1 1 funcref) @@ -219,6 +245,8 @@ ;; CHECK-BIN-NODEBUG: (elem $1 (table $1) (i32.const 0) func $1 $1 $1) +;; CHECK-BIN-NODEBUG: (elem $2 func) + ;; CHECK-BIN-NODEBUG: (func $0 (type $0) ;; CHECK-BIN-NODEBUG-NEXT: (nop) ;; CHECK-BIN-NODEBUG-NEXT: ) @@ -248,18 +276,18 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $1) (result i32) +;; CHECK-BIN-NODEBUG: (func $3 (type $2) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (table.size $0) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $4 (type $2) (param $0 i32) (result i32) +;; CHECK-BIN-NODEBUG: (func $4 (type $3) (param $0 i32) (result i32) ;; CHECK-BIN-NODEBUG-NEXT: (table.grow $0 ;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $5 (type $3) (param $0 i32) (param $1 funcref) (param $2 i32) +;; CHECK-BIN-NODEBUG: (func $5 (type $4) (param $0 i32) (param $1 funcref) (param $2 i32) ;; CHECK-BIN-NODEBUG-NEXT: (table.fill $0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) @@ -267,10 +295,18 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $6 (type $4) (param $0 i32) (param $1 i32) (param $2 i32) +;; CHECK-BIN-NODEBUG: (func $6 (type $1) (param $0 i32) (param $1 i32) (param $2 i32) ;; CHECK-BIN-NODEBUG-NEXT: (table.copy $0 $1 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $7 (type $1) (param $0 i32) (param $1 i32) (param $2 i32) +;; CHECK-BIN-NODEBUG-NEXT: (table.init $0 $2 +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/ctor-eval/table.init.wat b/test/lit/ctor-eval/table.init.wat new file mode 100644 index 00000000000..7af2a09c6e1 --- /dev/null +++ b/test/lit/ctor-eval/table.init.wat @@ -0,0 +1,62 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-ctor-eval %s --ctors=run --kept-exports=run --quiet -all -S -o - | filecheck %s + +(module + ;; CHECK: (type $none_=>_none (func)) + (type $none_=>_none (func)) + + ;; CHECK: (table $table 22 funcref) + (table $table 22 funcref) + + ;; CHECK: (elem $init (i32.const 0) $nop) + (elem $init (i32.const 0) $nop) + + ;; CHECK: (elem $later func $trap) + (elem $later $trap) + + (export "run" (func $run)) + + (func $run (type $none_=>_none) + ;; This call can be evalled away (it does nothing as the target is a nop). + (call_indirect $table (type $none_=>_none) + (i32.const 0) + ) + + ;; We stop at this table.init, which is not handled yet. The call after it + ;; should also remain where it is. + (table.init $table $later + (i32.const 0) + (i32.const 0) + (i32.const 1) + ) + (call_indirect $table (type $none_=>_none) + (i32.const 0) + ) + ) + + ;; CHECK: (export "run" (func $run_3)) + + ;; CHECK: (func $nop (type $none_=>_none) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nop (type $none_=>_none) + (nop) + ) + + ;; CHECK: (func $trap (type $none_=>_none) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $trap (type $none_=>_none) + (unreachable) + ) +) +;; CHECK: (func $run_3 (type $none_=>_none) +;; CHECK-NEXT: (table.init $table $later +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (call_indirect $table (type $none_=>_none) +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) diff --git a/test/lit/passes/directize_all-features.wast b/test/lit/passes/directize_all-features.wast index 997992b0766..074558d95ae 100644 --- a/test/lit/passes/directize_all-features.wast +++ b/test/lit/passes/directize_all-features.wast @@ -1599,6 +1599,101 @@ ) ) +;; A table.init prevents optimization. +(module + ;; CHECK: (type $i32 (func (result i32))) + ;; IMMUT: (type $i32 (func (result i32))) + (type $i32 (func (result i32))) + + ;; CHECK: (type $1 (func)) + + ;; CHECK: (table $table 111 funcref) + ;; IMMUT: (type $1 (func)) + + ;; IMMUT: (table $table 111 funcref) + (table $table 111 funcref) + (elem (i32.const 0) $func-A) + + ;; CHECK: (elem $0 (i32.const 0) $func-A) + + ;; CHECK: (elem $elem func $func-B) + ;; IMMUT: (elem $0 (i32.const 0) $func-A) + + ;; IMMUT: (elem $elem func $func-B) + (elem $elem $func-B) + + ;; CHECK: (export "a" (func $init)) + ;; IMMUT: (export "a" (func $init)) + (export "a" (func $init)) + ;; CHECK: (export "b" (func $call)) + ;; IMMUT: (export "b" (func $call)) + (export "b" (func $call)) + + ;; CHECK: (func $func-A (type $i32) (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; IMMUT: (func $func-A (type $i32) (result i32) + ;; IMMUT-NEXT: (i32.const 0) + ;; IMMUT-NEXT: ) + (func $func-A (result i32) + (i32.const 0) + ) + + ;; CHECK: (func $func-B (type $i32) (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; IMMUT: (func $func-B (type $i32) (result i32) + ;; IMMUT-NEXT: (unreachable) + ;; IMMUT-NEXT: ) + (func $func-B (result i32) + (unreachable) + ) + + ;; CHECK: (func $init (type $1) + ;; CHECK-NEXT: (table.init $table $elem + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (func $init (type $1) + ;; IMMUT-NEXT: (table.init $table $elem + ;; IMMUT-NEXT: (i32.const 0) + ;; IMMUT-NEXT: (i32.const 0) + ;; IMMUT-NEXT: (i32.const 1) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $init + (table.init $table $elem + (i32.const 0) + (i32.const 0) + (i32.const 1) + ) + ) + + ;; CHECK: (func $call (type $1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_indirect $table (type $i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (func $call (type $1) + ;; IMMUT-NEXT: (drop + ;; IMMUT-NEXT: (call $func-A) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $call + (drop + ;; This cannot be turned into a direct call due to the table.init, unless we + ;; assume initial contents are immutable. + (call_indirect (type $i32) + (i32.const 0) + ) + ) + ) +) + ;; The elem's offset is way out of bounds, which we should not error on, and do ;; nothing otherwise. (module diff --git a/test/lit/passes/simplify-locals-table_copy.wast b/test/lit/passes/simplify-locals-table_copy.wast new file mode 100644 index 00000000000..a10c16b1b16 --- /dev/null +++ b/test/lit/passes/simplify-locals-table_copy.wast @@ -0,0 +1,73 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --simplify-locals -all -S -o - | filecheck %s + +(module + ;; CHECK: (table $table 10 funcref) + (table $table 10 funcref) + + ;; CHECK: (elem $zero (i32.const 0) $zero) + (elem $zero (i32.const 0) $zero) + + ;; CHECK: (elem $one func $one) + (elem $one $one) + + ;; CHECK: (func $move (type $0) (result funcref) + ;; CHECK-NEXT: (local $temp funcref) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (table.get $table + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $move (result funcref) + (local $temp funcref) + (local.set $temp + (table.get $table + (i32.const 0) + ) + ) + ;; We can move the table.get past the nop. + (nop) + (local.get $temp) + ) + + ;; CHECK: (func $no-move (type $0) (result funcref) + ;; CHECK-NEXT: (local $temp funcref) + ;; CHECK-NEXT: (local.set $temp + ;; CHECK-NEXT: (table.get $table + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (table.init $table $one + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + (func $no-move (result funcref) + (local $temp funcref) + (local.set $temp + (table.get $table + (i32.const 0) + ) + ) + ;; table.init writes to the table, so table reads cannot cross it. + (table.init $table $one (i32.const 0) (i32.const 0) (i32.const 1)) + (local.get $temp) + ) + + ;; CHECK: (func $zero (type $1) (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $zero (result i32) + (i32.const 0) + ) + + ;; CHECK: (func $one (type $1) (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $one (result i32) + (i32.const 1) + ) +) diff --git a/test/lit/passes/table64-lowering.wast b/test/lit/passes/table64-lowering.wast index 7e49d3e7303..f3aaf4ef8a0 100644 --- a/test/lit/passes/table64-lowering.wast +++ b/test/lit/passes/table64-lowering.wast @@ -67,4 +67,17 @@ (func $test_table_fill (table.fill $t64 (i64.const 0) (ref.null func) (i64.const 10)) ) + + ;; CHECK: (func $test_table_init + ;; CHECK-NEXT: (table.init $t64 $elem64 + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test_table_init + (table.init $t64 $elem64 (i64.const 0) (i32.const 5) (i32.const 10)) + ) ) diff --git a/test/lit/passes/unsubtyping.wast b/test/lit/passes/unsubtyping.wast index 5181b9a1cdd..590cc5ae104 100644 --- a/test/lit/passes/unsubtyping.wast +++ b/test/lit/passes/unsubtyping.wast @@ -818,6 +818,38 @@ ) ) +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $0 (func)) + + ;; CHECK: (type $super (sub (struct))) + (type $super (sub (struct))) + ;; CHECK: (type $sub (sub $super (struct))) + (type $sub (sub $super (struct))) + + ;; CHECK: (table $super 1 1 (ref null $super)) + (table $super 1 1 (ref null $super)) + + ;; CHECK: (elem $sub (ref null $sub)) + (elem $sub (ref null $sub)) + + ;; CHECK: (func $table-copy (type $0) + ;; CHECK-NEXT: (table.init $super $sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $table-copy + ;; This requires $sub <: $super. + (table.init $super $sub + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) +) + (module ;; CHECK: (rec ;; CHECK-NEXT: (type $super (sub (struct))) diff --git a/test/spec/table_init.wast b/test/spec/table_init.wast new file mode 100644 index 00000000000..09cc0afdaf7 --- /dev/null +++ b/test/spec/table_init.wast @@ -0,0 +1,52 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. + +;; RUN: wasm-opt %s -all --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s + +;; The elem is out of bounds, leading to a trap during initialization. +(assert_unlinkable + (module + (table $table 1 1 funcref) + (elem $elem (i32.const 1) $foo) + (func $foo) + ) + "trap" +) + +;; Now it is in bounds, with the elem offset reduced to 0. +(module + (table $table 1 1 funcref) + (elem $elem (i32.const 0) $foo) + (func $foo) +) + +;; The table begins with a function that returns zero. table.init will replace +;; it with one that returns 1. +(module + (type $i (func (result i32))) + + (table $table 10 funcref) + (elem $zero (i32.const 0) $zero) + (elem $one $one) + + (func $call (export "call") (result i32) + (call_indirect (type $i) (i32.const 0)) + ) + + (func $init (export "init") (result i32) + (table.init $table $one (i32.const 0) (i32.const 0) (i32.const 1)) + (call $call) + ) + + (func $zero (result i32) + (i32.const 0) + ) + + (func $one (result i32) + (i32.const 1) + ) +) + +;; First we get 0, then 1. +(assert_return (invoke "call") (i32.const 0)) +(assert_return (invoke "init") (i32.const 1)) + From 95a4d5de6f65b35a64caf014c2f7febb8a799542 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 16 Aug 2024 17:53:37 -0400 Subject: [PATCH 525/553] Fix direct comparisons with unshared basic heap types (#6845) Audit the remaining ocurrences of `== HeapType::` and fix those that did not handle shared types correctly. Add tests for some of the fixes; others are NFC but clarify the code. --- src/passes/Precompute.cpp | 2 +- src/passes/StringLowering.cpp | 13 ++- src/tools/wasm-ctor-eval.cpp | 8 +- src/wasm-builder.h | 6 +- src/wasm/literal.cpp | 2 +- src/wasm/wasm-validator.cpp | 2 +- test/lit/ctor-eval/extern.wast | 113 +++++++++++++++++++---- test/lit/passes/precompute-ref-func.wast | 36 ++++++++ 8 files changed, 152 insertions(+), 30 deletions(-) create mode 100644 test/lit/passes/precompute-ref-func.wast diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index ba04a68aa26..c60136ec791 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -293,7 +293,7 @@ struct Precompute return; } } else if (singleValue.type.isRef() && - singleValue.type.getHeapType() == HeapType::func) { + singleValue.type.getHeapType().isSignature()) { if (auto* r = curr->value->template dynCast()) { r->func = singleValue.getFunc(); r->finalize(); diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index f735b9ab222..fa5c1c9a8ac 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -291,8 +291,9 @@ struct StringLowering : public StringGathering { // singleton rec group. std::vector params, results; auto fix = [](Type t) { - if (t.isRef() && t.getHeapType() == HeapType::string) { - t = Type(HeapType::ext, t.getNullability()); + if (t.isRef() && t.getHeapType().isMaybeShared(HeapType::string)) { + auto share = t.getHeapType().getShared(); + t = Type(HeapTypes::ext.getBasic(share), t.getNullability()); } return t; }; @@ -495,9 +496,13 @@ struct StringLowering : public StringGathering { void noteSubtype(Expression* a, Type b) { // This is the case we care about: if |a| is a null that must be a // subtype of ext then we fix that up. - if (b.isRef() && b.getHeapType().getTop() == HeapType::ext) { + if (!b.isRef()) { + return; + } + HeapType top = b.getHeapType().getTop(); + if (top.isMaybeShared(HeapType::ext)) { if (auto* null = a->dynCast()) { - null->finalize(HeapType::noext); + null->finalize(HeapTypes::noext.getBasic(top.getShared())); } } } diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 6c72f1c73a8..9cf552450bd 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -834,11 +834,13 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { // logic here, we save the original (possible externalized) value, and then // look at the internals from here on out. Literal original = value; - if (value.type.isRef() && value.type.getHeapType() == HeapType::ext) { + if (value.type.isRef() && + value.type.getHeapType().isMaybeShared(HeapType::ext)) { value = value.internalize(); // We cannot serialize truly external things, only data and i31s. - assert(value.isData() || value.type.getHeapType() == HeapType::i31); + assert(value.isData() || + value.type.getHeapType().isMaybeShared(HeapType::i31)); } // GC data (structs and arrays) must be handled with the special global- @@ -920,7 +922,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { Expression* ret = builder.makeGlobalGet(definingGlobalName, value.type); if (original != value) { // The original is externalized. - assert(original.type.getHeapType() == HeapType::ext); + assert(original.type.getHeapType().isMaybeShared(HeapType::ext)); ret = builder.makeRefAs(ExternConvertAny, ret); } return ret; diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 72d2a1db03b..8f8895781bd 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1387,8 +1387,10 @@ class Builder { if (curr->type.isNullable() && curr->type.isNull()) { return ExpressionManipulator::refNull(curr, curr->type); } - if (curr->type.isRef() && curr->type.getHeapType() == HeapType::i31) { - Expression* ret = makeRefI31(makeConst(0)); + if (curr->type.isRef() && + curr->type.getHeapType().isMaybeShared(HeapType::i31)) { + Expression* ret = + makeRefI31(makeConst(0), curr->type.getHeapType().getShared()); if (curr->type.isNullable()) { // To keep the type identical, wrap it in a block that adds nullability. ret = makeBlock({ret}, curr->type); diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 40a1f9519da..9d659f753c9 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -444,7 +444,7 @@ bool Literal::operator==(const Literal& other) const { return gcData == other.gcData; } assert(type.getHeapType().isBasic()); - if (type.getHeapType().getBasic(Unshared) == HeapType::i31) { + if (type.getHeapType().isMaybeShared(HeapType::i31)) { return i32 == other.i32; } WASM_UNREACHABLE("unexpected type"); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 758ae158e51..0bdc186584a 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2769,7 +2769,7 @@ void FunctionValidator::visitCallRef(CallRef* curr) { getModule()->features.hasGC(), curr, "call_ref requires gc [--enable-gc]"); if (curr->target->type == Type::unreachable || (curr->target->type.isRef() && - curr->target->type.getHeapType() == HeapType::nofunc)) { + curr->target->type.getHeapType().isMaybeShared(HeapType::nofunc))) { return; } if (shouldBeTrue(curr->target->type.isFunction(), diff --git a/test/lit/ctor-eval/extern.wast b/test/lit/ctor-eval/extern.wast index 9591f9034d0..d8e08eaa2f6 100644 --- a/test/lit/ctor-eval/extern.wast +++ b/test/lit/ctor-eval/extern.wast @@ -1,18 +1,19 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: wasm-ctor-eval %s --ctors=test1,test2,test3 --kept-exports=test1,test2,test3 --quiet -all -S -o - | filecheck %s +;; RUN: wasm-ctor-eval %s --ctors=test1,test1-shared,test2,test2-shared,test3,test3-shared \ +;; RUN: --kept-exports=test1,test1-shared,test2,test2-shared,test3,test3-shared --quiet -all -S -o - | filecheck %s (module ;; CHECK: (type $array (array (mut i8))) (type $array (array (mut i8))) + ;; CHECK: (type $shared-array (shared (array (mut i8)))) + (type $shared-array (shared (array (mut i8)))) ;; CHECK: (type $struct (struct (field externref))) (type $struct (struct (field externref))) + ;; CHECK: (type $shared-struct (shared (struct (field (ref null (shared extern)))))) + (type $shared-struct (shared (struct (field (ref null (shared extern)))))) - (export "test1" (func $test1)) - (export "test2" (func $test2)) - (export "test3" (func $test3)) - - (func $test1 (result externref) + (func $test1 (export "test1") (result externref) ;; This will remain almost the same, even though we eval it, since the ;; serialization of an externalized i31 is what is written here. But the add ;; will be evalled out. @@ -26,7 +27,19 @@ ) ) - (func $test2 (result externref) + (func $test1-shared (export "test1-shared") (result (ref null (shared extern))) + ;; Same as above, but now the i31 is shared. + (extern.convert_any + (ref.i31_shared + (i32.add + (i32.const 41) + (i32.const 1) + ) + ) + ) + ) + + (func $test2 (export "test2") (result externref) ;; This will be evalled into an externalization of a global.get. (extern.convert_any (array.new_fixed $array 3 @@ -37,7 +50,18 @@ ) ) - (func $test3 (result anyref) + (func $test2-shared (export "test2-shared") (result (ref null (shared extern))) + ;; Same as above, but now the array is shared. + (extern.convert_any + (array.new_fixed $shared-array 3 + (i32.const 1) + (i32.const 2) + (i32.const 3) + ) + ) + ) + + (func $test3 (export "test3") (result anyref) ;; This will add a global that contains an externalization operation. (struct.new $struct (extern.convert_any @@ -47,11 +71,26 @@ ) ) ) + + (func $test3-shared (export "test3-shared") (result (ref null (shared any))) + ;; Same as above, but now the struct and i31 are shared. + (struct.new $shared-struct + (extern.convert_any + (ref.i31_shared + (i32.const 1) + ) + ) + ) + ) ) -;; CHECK: (type $2 (func (result externref))) +;; CHECK: (type $4 (func (result externref))) + +;; CHECK: (type $5 (func (result (ref null (shared extern))))) + +;; CHECK: (type $6 (func (result anyref))) -;; CHECK: (type $3 (func (result anyref))) +;; CHECK: (type $7 (func (result (ref null (shared any))))) ;; CHECK: (global $ctor-eval$global (ref $array) (array.new_fixed $array 3 ;; CHECK-NEXT: (i32.const 1) @@ -59,7 +98,13 @@ ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: )) -;; CHECK: (global $ctor-eval$global_1 (ref $struct) (struct.new $struct +;; CHECK: (global $ctor-eval$global_1 (ref $shared-array) (array.new_fixed $shared-array 3 +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: (i32.const 2) +;; CHECK-NEXT: (i32.const 3) +;; CHECK-NEXT: )) + +;; CHECK: (global $ctor-eval$global_2 (ref $struct) (struct.new $struct ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (i32.const 1) @@ -67,13 +112,27 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: )) -;; CHECK: (export "test1" (func $test1_3)) +;; CHECK: (global $ctor-eval$global_3 (ref $shared-struct) (struct.new $shared-struct +;; CHECK-NEXT: (extern.convert_any +;; CHECK-NEXT: (ref.i31_shared +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: )) + +;; CHECK: (export "test1" (func $test1_6)) + +;; CHECK: (export "test1-shared" (func $test1-shared_7)) + +;; CHECK: (export "test2" (func $test2_8)) -;; CHECK: (export "test2" (func $test2_4)) +;; CHECK: (export "test2-shared" (func $test2-shared_9)) -;; CHECK: (export "test3" (func $test3_5)) +;; CHECK: (export "test3" (func $test3_10)) -;; CHECK: (func $test1_3 (type $2) (result externref) +;; CHECK: (export "test3-shared" (func $test3-shared_11)) + +;; CHECK: (func $test1_6 (type $4) (result externref) ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (i32.const 42) @@ -81,12 +140,30 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK: (func $test2_4 (type $2) (result externref) +;; CHECK: (func $test1-shared_7 (type $5) (result (ref null (shared extern))) +;; CHECK-NEXT: (extern.convert_any +;; CHECK-NEXT: (ref.i31_shared +;; CHECK-NEXT: (i32.const 42) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $test2_8 (type $4) (result externref) ;; CHECK-NEXT: (extern.convert_any ;; CHECK-NEXT: (global.get $ctor-eval$global) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) -;; CHECK: (func $test3_5 (type $3) (result anyref) -;; CHECK-NEXT: (global.get $ctor-eval$global_1) +;; CHECK: (func $test2-shared_9 (type $5) (result (ref null (shared extern))) +;; CHECK-NEXT: (extern.convert_any +;; CHECK-NEXT: (global.get $ctor-eval$global_1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $test3_10 (type $6) (result anyref) +;; CHECK-NEXT: (global.get $ctor-eval$global_2) +;; CHECK-NEXT: ) + +;; CHECK: (func $test3-shared_11 (type $7) (result (ref null (shared any))) +;; CHECK-NEXT: (global.get $ctor-eval$global_3) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/precompute-ref-func.wast b/test/lit/passes/precompute-ref-func.wast new file mode 100644 index 00000000000..df4415c7b5a --- /dev/null +++ b/test/lit/passes/precompute-ref-func.wast @@ -0,0 +1,36 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s -all --precompute -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func (result funcref))) + + ;; CHECK: (type $shared-func (shared (func (result (ref null (shared func)))))) + (type $shared-func (shared (func (result (ref null (shared func)))))) + ;; CHECK: (elem declare func $test $test-shared) + + ;; CHECK: (func $test (type $0) (result funcref) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (ref.func $test) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (result funcref) + (block + (return + (ref.func $test) + ) + ) + ) + + ;; CHECK: (func $test-shared (type $shared-func) (result (ref null (shared func))) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (ref.func $test-shared) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test-shared (type $shared-func) + (block + (return + (ref.func $test-shared) + ) + ) + ) +) From e058bfbdf31c7b59df8ab62a9ebaedac45521c12 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 16 Aug 2024 22:14:06 -0400 Subject: [PATCH 526/553] Add a pass for minimizing recursion groups (#6832) Most of our type optimization passes emit all non-public types as a single large rec group, which trivially ensures that different types remain different, even if they are optimized to have the same structure. Usually emitting a single large rec group is fine, but it also means that if the module is split, all of the types will need to be repeated in all of the split modules. To better support this use case, add a pass that can split the large rec group back into minimal rec groups, taking care to preserve separate type identities by emitting different permutations of the same group where possible or by inserting unused brand types to differentiate them. --- scripts/fuzz_opt.py | 1 + src/passes/CMakeLists.txt | 1 + src/passes/MinimizeRecGroups.cpp | 802 ++++++++++ src/passes/pass.cpp | 3 + src/passes/passes.h | 1 + src/wasm/wasm-type-shape.cpp | 1 + test/lit/help/wasm-metadce.test | 3 + test/lit/help/wasm-opt.test | 3 + test/lit/help/wasm2js.test | 3 + .../passes/minimize-rec-groups-brands.wast | 1378 +++++++++++++++++ test/lit/passes/minimize-rec-groups.wast | 486 ++++++ 11 files changed, 2682 insertions(+) create mode 100644 src/passes/MinimizeRecGroups.cpp create mode 100644 test/lit/passes/minimize-rec-groups-brands.wast create mode 100644 test/lit/passes/minimize-rec-groups.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 4087abed17b..28426f7734c 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -1571,6 +1571,7 @@ def write_commands(commands, filename): ('--monomorphize', '--pass-arg=monomorphize-min-benefit@50'), ('--monomorphize', '--pass-arg=monomorphize-min-benefit@95'), ('--monomorphize-always',), + ('--minimize-rec-groups',), ('--no-stack-ir',), ('--once-reduction',), ("--optimize-casts",), diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 703b27e056d..54f04405738 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -67,6 +67,7 @@ set(passes_SOURCES MergeLocals.cpp Metrics.cpp MinifyImportsAndExports.cpp + MinimizeRecGroups.cpp Monomorphize.cpp MultiMemoryLowering.cpp NameList.cpp diff --git a/src/passes/MinimizeRecGroups.cpp b/src/passes/MinimizeRecGroups.cpp new file mode 100644 index 00000000000..728cb306edb --- /dev/null +++ b/src/passes/MinimizeRecGroups.cpp @@ -0,0 +1,802 @@ +/* + * Copyright 2024 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. + */ + +// Split types into minimal recursion groups by computing the strongly connected +// components of the type graph, which are the minimal sets of +// mutually-recursive types that must be in the same recursion group with each +// other for the type section to validate. +// +// We must additionally ensure that distinct types remain distinct, which would +// not be the case if we allowed two separate strongly connected components with +// the same shape to be rewritten to two copies of the same recursion group. +// Accidentally merging types would be incorrect because it would change the +// behavior of casts that would have previously been able to differentiate the +// types. +// +// When multiple strongly connected components have the same shape, first try to +// differentiate them by permuting their types, which keeps the sizes of the rec +// groups as small as possible. When there are more strongly connected +// components that are permutations of one another than there are distinct +// permutations, fall back to keeping the types distinct by adding distinct +// brand types to the recursion groups to ensure they have different shapes. +// +// There are several possible algorithmic design for detecting when to generate +// permutations and determining what permutations to generate. They trade off +// the amount of "wasted" work spent generating shapes that have already been +// used with the amount of work spent trying to avoid the wasted work and with +// the quality of the output. +// +// The simplest possible design that avoids all "wasted" work would be to +// canonicalize the shape of each group to eagerly detect isomorphisms and +// eagerly organize the groups into equivalence classes. This would allow us to +// avoid ever generating permutations of a group with shapes that have already +// been used. See `getCanonicalPermutation` below for details on how this works. +// However, this is not an ideal solution because canonicalization is an +// expensive operation and in the common case a group's shape will not conflict +// with any other group's shape, so canonicalization itself would be wasted +// work. +// +// The simplest possible design in the other direction is to never canonicalize +// and instead to lazily build up equivalences classes of isomorphic groups when +// shape conflicts are detected in practice. Conflicts are resolved by choosing +// the next permutation generated by the representative element of the +// equivalence class. This solution is not ideal because groups with high +// symmetry can have very many permutations that have the same shape, so many +// permutations might need to be generated before finding one that is distinct +// from previous permutations with respect to its shape. This work can be +// sidestepped by instead eagerly advancing the brand type, but that increases +// the code size of the output. +// +// The design chosen here is a hybrid of those two designs that is slightly more +// complicated, but gets the best of both worlds. We lazily detect equivalence +// classes of groups without eager shape canonicalization like in the second +// design, but we canonicalize the shape for any equivalence class that grows +// larger than one group like in the first design. This ensures that we don't +// spend time canonicalizing in the common case where there are no shape +// conflicts, but it also ensures that we don't waste time generating +// permutations with shapes that conflict with the shapes of previous groups. It +// also allows us to avoid compromising on the quality of the output. + +#include "ir/module-utils.h" +#include "ir/type-updating.h" +#include "pass.h" +#include "support/disjoint_sets.h" +#include "support/strongly_connected_components.h" +#include "support/topological_orders.h" +#include "wasm-type-shape.h" +#include "wasm.h" + +namespace wasm { + +namespace { + +// Compute the strongly connected components of the private types, being sure to +// only consider edges to other private types. +struct TypeSCCs + : SCCs::const_iterator, TypeSCCs> { + std::unordered_set includedTypes; + TypeSCCs(const std::vector& types) + : SCCs(types.begin(), types.end()), + includedTypes(types.cbegin(), types.cend()) {} + void pushChildren(HeapType parent) { + for (auto child : parent.getReferencedHeapTypes()) { + if (includedTypes.count(child)) { + push(child); + } + } + } +}; + +// After all their permutations with distinct shapes have been used, different +// groups with the same shapes must be differentiated by adding in a "brand" +// type. Even with a brand mixed in, we might run out of permutations with +// distinct shapes, in which case we need a new brand type. This iterator +// provides an infinite sequence of possible brand types, prioritizing those +// with the most compact encoding. +struct BrandTypeIterator { + // See `initFieldOptions` for the 18 options. + static constexpr size_t optionCount = 18; + static std::array fieldOptions; + static void initFieldOptions(); + + struct FieldInfo { + uint8_t index = 0; + bool immutable = false; + + operator Field() const { + auto field = fieldOptions[index]; + if (immutable) { + field.mutable_ = Immutable; + } + return field; + } + + bool advance() { + if (!immutable) { + immutable = true; + return true; + } + immutable = false; + index = (index + 1) % optionCount; + return index != 0; + } + }; + + bool useArray = false; + std::vector fields; + + HeapType operator*() const { + if (useArray) { + return Array(fields[0]); + } + return Struct(std::vector(fields.begin(), fields.end())); + } + + BrandTypeIterator& operator++() { + for (size_t i = fields.size(); i > 0; --i) { + if (fields[i - 1].advance()) { + return *this; + } + } + if (useArray) { + useArray = false; + return *this; + } + fields.emplace_back(); + useArray = fields.size() == 1; + return *this; + } +}; + +// Create an adjacency list with edges from supertype to subtypes. +std::vector> +createSubtypeGraph(const std::vector& types) { + std::unordered_map indices; + for (auto type : types) { + indices.insert({type, indices.size()}); + } + + std::vector> subtypeGraph(types.size()); + for (size_t i = 0; i < types.size(); ++i) { + if (auto super = types[i].getDeclaredSuperType()) { + if (auto it = indices.find(*super); it != indices.end()) { + subtypeGraph[it->second].push_back(i); + } + } + } + return subtypeGraph; +} + +struct RecGroupInfo; + +// As we iterate through the strongly connected components, we may find +// components that have the same shape. When we find such a collision, we merge +// the groups for the components into a single equivalence class where we track +// how we have disambiguated all such isomorphic groups. +struct GroupClassInfo { + // If the group has just a single type, record it so we can make sure the + // brand is not identical to it. + std::optional singletonType; + // If we have gone through all the permutations of this group with distinct + // shapes, we need to add a brand type to continue differentiating different + // groups in the class. + std::optional brand; + // An adjacency list giving edges from supertypes to subtypes within the + // group, using indices into the (non-materialized) canonical shape of this + // group, offset by 1 iff there is a brand type. Used to ensure that we only + // find emit permutations that respect the constraint that supertypes must be + // ordered before subtypes. + std::vector> subtypeGraph; + // A generator of valid permutations of the components in this class. + TopologicalOrders orders; + + // Initialize `subtypeGraph` and `orders` based on the canonical ordering + // encoded by the group and permutation in `info`. + static std::vector> initSubtypeGraph(RecGroupInfo& info); + GroupClassInfo(RecGroupInfo& info); + + void advance() { + ++orders; + if (orders == orders.end()) { + advanceBrand(); + } + } + + void advanceBrand() { + if (brand) { + ++*brand; + } else { + brand.emplace(); + // Make room in the subtype graph for the brand type, which goes at the + // beginning of the canonical order. + subtypeGraph.insert(subtypeGraph.begin(), {{}}); + // Adjust indices. + for (size_t i = 1; i < subtypeGraph.size(); ++i) { + for (auto& edge : subtypeGraph[i]) { + ++edge; + } + } + } + // Make sure the brand is not the same as the real type. + if (singletonType && + RecGroupShape({**brand}) == RecGroupShape({*singletonType})) { + ++*brand; + } + // Start back at the initial permutation with the new brand. + orders.~TopologicalOrders(); + new (&orders) TopologicalOrders(subtypeGraph); + } + + // Permute the types in the given group to match the current configuration in + // this GroupClassInfo. + void permute(RecGroupInfo&); +}; + +// The information we keep for each produced rec group. +struct RecGroupInfo { + // The sequence of input types to be rewritten into this output group. + std::vector group; + // The permutation of the canonical shape for this group's class used to + // arrive at this group's shape. Used when we later find another strongly + // connected component with this shape to apply the inverse permutation and + // get that other component's types into the canonical shape before using a + // fresh permutation to re-shuffle them into their final shape. Only set for + // groups belonging to nontrivial equivalence classes. + std::vector permutation; + // Does this group include a brand type that does not correspond to a type in + // the original module? + bool hasBrand = false; + // This group may be the representative group for its nontrivial equivalence + // class, in which case it holds the necessary extra information used to add + // new groups to the class. + std::optional classInfo; +}; + +std::vector> +GroupClassInfo::initSubtypeGraph(RecGroupInfo& info) { + assert(!info.classInfo); + assert(info.permutation.size() == info.group.size()); + + std::vector canonical(info.group.size()); + for (size_t i = 0; i < info.group.size(); ++i) { + canonical[info.permutation[i]] = info.group[i]; + } + + return createSubtypeGraph(canonical); +} + +GroupClassInfo::GroupClassInfo(RecGroupInfo& info) + : singletonType(info.group.size() == 1 + ? std::optional(info.group[0]) + : std::nullopt), + brand(std::nullopt), subtypeGraph(initSubtypeGraph(info)), + orders(subtypeGraph) {} + +void GroupClassInfo::permute(RecGroupInfo& info) { + assert(info.group.size() == info.permutation.size()); + bool insertingBrand = info.group.size() < subtypeGraph.size(); + // First, un-permute the group to get back to the canonical order, offset by 1 + // if we are newly inserting a brand. + std::vector canonical(info.group.size() + insertingBrand); + for (size_t i = 0; i < info.group.size(); ++i) { + canonical[info.permutation[i] + insertingBrand] = info.group[i]; + } + // Update the brand. + if (brand) { + canonical[0] = **brand; + } + if (insertingBrand) { + info.group.resize(info.group.size() + 1); + info.hasBrand = true; + } + // Finally, re-permute with the new permutation.. + info.permutation = *orders; + for (size_t i = 0; i < info.group.size(); ++i) { + info.group[i] = canonical[info.permutation[i]]; + } +} + +std::array + BrandTypeIterator::fieldOptions = {{}}; + +void BrandTypeIterator::initFieldOptions() { + BrandTypeIterator::fieldOptions = {{ + Field(Field::i8, Mutable), + Field(Field::i16, Mutable), + Field(Type::i32, Mutable), + Field(Type::i64, Mutable), + Field(Type::f32, Mutable), + Field(Type::f64, Mutable), + Field(Type(HeapType::any, Nullable), Mutable), + Field(Type(HeapType::func, Nullable), Mutable), + Field(Type(HeapType::ext, Nullable), Mutable), + Field(Type(HeapType::none, Nullable), Mutable), + Field(Type(HeapType::nofunc, Nullable), Mutable), + Field(Type(HeapType::noext, Nullable), Mutable), + Field(Type(HeapType::any, NonNullable), Mutable), + Field(Type(HeapType::func, NonNullable), Mutable), + Field(Type(HeapType::ext, NonNullable), Mutable), + Field(Type(HeapType::none, NonNullable), Mutable), + Field(Type(HeapType::nofunc, NonNullable), Mutable), + Field(Type(HeapType::noext, NonNullable), Mutable), + }}; +} + +struct MinimizeRecGroups : Pass { + // The types we are optimizing and their indices in this list. + std::vector types; + + // A global ordering on all types, including public types. Used to define a + // total ordering on rec group shapes. + std::unordered_map typeIndices; + + // As we process strongly connected components, we will construct output + // recursion groups here. + std::vector groups; + + // For each shape of rec group we have created, its index in `groups`. + std::unordered_map groupShapeIndices; + + // When we find that two groups are isomorphic to (i.e. permutations of) each + // other, we combine their equivalence classes and choose a new class + // representative to use to disambiguate the groups and any further groups + // that will join the class. + DisjointSets equivalenceClasses; + + // When we see a new group, we have to make sure its shape doesn't conflict + // with the shape of any existing group. If there is a conflict, we need to + // update the group's shape and try again. Maintain a stack of group indices + // whose shapes we need to check for uniqueness to avoid deep recursions. + std::vector shapesToUpdate; + + void run(Module* module) override { + // There are no recursion groups to minimize if GC is not enabled. + if (!module->features.hasGC()) { + return; + } + + initBrandOptions(); + + types = ModuleUtils::getPrivateHeapTypes(*module); + for (auto type : ModuleUtils::collectHeapTypes(*module)) { + typeIndices.insert({type, typeIndices.size()}); + } + + // The number of types to optimize is an upper bound on the number of + // recursion groups we will emit. + groups.reserve(types.size()); + + // Compute the strongly connected components and ensure they form distinct + // recursion groups. + for (auto scc : TypeSCCs(types)) { + [[maybe_unused]] size_t index = equivalenceClasses.addSet(); + assert(index == groups.size()); + groups.emplace_back(); + + // The SCC is not necessarily topologically sorted to have the supertypes + // come first. Fix that. + std::vector sccTypes(scc.begin(), scc.end()); + auto deps = createSubtypeGraph(sccTypes); + auto permutation = *TopologicalOrders(deps).begin(); + groups.back().group.resize(sccTypes.size()); + for (size_t i = 0; i < sccTypes.size(); ++i) { + groups.back().group[i] = sccTypes[permutation[i]]; + } + assert(shapesToUpdate.empty()); + shapesToUpdate.push_back(index); + updateShapes(); + } + + rewriteTypes(*module); + } + + void initBrandOptions() { + // Initialize the field options for brand types lazily here to avoid + // depending on global constructor ordering. + [[maybe_unused]] static bool fieldsInitialized = []() { + BrandTypeIterator::initFieldOptions(); + return true; + }(); + } + + void updateShapes() { + while (!shapesToUpdate.empty()) { + auto index = shapesToUpdate.back(); + shapesToUpdate.pop_back(); + updateShape(index); + } + } + + void updateShape(size_t group) { + auto [it, inserted] = + groupShapeIndices.insert({RecGroupShape(groups[group].group), group}); + if (inserted) { + // This shape was unique. We're done. + return; + } + + // We have a conflict. There are five possibilities: + // + // 1. We are trying to insert the next permutation of an existing + // equivalence class and have found that... + // + // A. The next permutation has the same shape as some previous + // permutation in the same equivalence class. + // + // B. The next permutation has the same shape as some other group + // already in a different nontrivial equivalent class. + // + // C. The next permutation has the same shape as some other group + // not yet included in a nontrivial equivalence class. + // + // 2. We are inserting a new group not yet affiliated with a + // nontrivial equivalence class and have found that... + // + // A. It has the same shape as some group in an existing nontrivial + // equivalence class. + // + // B. It has the same shape as some other group also not yet affiliated + // with a nontrivial equivalence class, so we will form a new + // nontrivial equivalence class. + // + // These possibilities are handled in order below. + + size_t other = it->second; + + auto& groupInfo = groups[group]; + auto& otherInfo = groups[other]; + + size_t groupRep = equivalenceClasses.getRoot(group); + size_t otherRep = equivalenceClasses.getRoot(other); + + // Case 1A: We have found a permutation of this group that has the same + // shape as a previous permutation of this group. Skip the rest of the + // permutations, which will also have the same shapes as previous + // permutations. + if (groupRep == otherRep) { + assert(groups[groupRep].classInfo); + auto& classInfo = *groups[groupRep].classInfo; + + // Move to the next permutation after advancing the type brand to skip + // further repeated shapes. + classInfo.advanceBrand(); + classInfo.permute(groupInfo); + + shapesToUpdate.push_back(group); + return; + } + + // Case 1B: There is a shape conflict with a group from a different + // nontrivial equivalence class. Because we canonicalize the shapes whenever + // we first create a nontrivial equivalence class, this is usually not + // possible; two equivalence classes with groups of the same shape should + // actually be the same equivalence class. The exception is when there is a + // group in each class whose brand matches the base type of the other class. + // In this case we don't actually want to join the classes; we just want to + // advance the current group to the next permutation to resolve the + // conflict. + if (groups[groupRep].classInfo && groups[otherRep].classInfo) { + auto& classInfo = *groups[groupRep].classInfo; + classInfo.advance(); + classInfo.permute(groupInfo); + shapesToUpdate.push_back(group); + return; + } + + // Case 1C: The current group belongs to a nontrivial equivalence class and + // has the same shape as some other group unaffiliated with a nontrivial + // equivalence class. Bring that other group into our equivalence class and + // advance the current group to the next permutation to resolve the + // conflict. + if (groups[groupRep].classInfo) { + auto& classInfo = *groups[groupRep].classInfo; + + [[maybe_unused]] size_t unionRep = + equivalenceClasses.getUnion(groupRep, otherRep); + assert(groupRep == unionRep); + + // `other` must have the same permutation as `group` because they have the + // same shape. Advance `group` to the next permutation. + otherInfo.classInfo = std::nullopt; + otherInfo.permutation = groupInfo.permutation; + classInfo.advance(); + classInfo.permute(groupInfo); + + shapesToUpdate.push_back(group); + return; + } + + // Case 2A: The shape of the current group is already found in an existing + // nontrivial equivalence class. Join the class and advance to the next + // permutation to resolve the conflict. + if (groups[otherRep].classInfo) { + auto& classInfo = *groups[otherRep].classInfo; + + [[maybe_unused]] size_t unionRep = + equivalenceClasses.getUnion(otherRep, groupRep); + assert(otherRep == unionRep); + + // Since we matched shapes with `other`, unapplying its permutation gets + // us back to the canonical shape, from which we can apply a fresh + // permutation. + groupInfo.classInfo = std::nullopt; + groupInfo.permutation = otherInfo.permutation; + classInfo.advance(); + classInfo.permute(groupInfo); + + shapesToUpdate.push_back(group); + return; + } + + // Case 2B: We need to join two groups with matching shapes into a new + // nontrivial equivalence class. + assert(!groups[groupRep].classInfo && !groups[otherRep].classInfo); + assert(group == groupRep && other == otherRep); + + // We are canonicalizing and reinserting the shape for other, so remove it + // from the map under its current shape. + groupShapeIndices.erase(it); + + // Put the types for both groups into the canonical order. + auto permutation = getCanonicalPermutation(groupInfo.group); + groupInfo.permutation = otherInfo.permutation = std::move(permutation); + + // Set up `other` to be the representative element of the equivalence class. + otherInfo.classInfo.emplace(otherInfo); + auto& classInfo = *otherInfo.classInfo; + + // Update both groups to have the initial valid order. Their shapes still + // match. + classInfo.permute(otherInfo); + classInfo.permute(groupInfo); + + // Insert `other` with its new shape. It may end up being joined to another + // existing equivalence class, in which case its class info will be cleared + // and `group` will subsequently be added to that same existing class, or + // alternatively it may be inserted as the representative element of a new + // class to which `group` will subsequently be joined. + shapesToUpdate.push_back(group); + shapesToUpdate.push_back(other); + } + + std::vector + getCanonicalPermutation(const std::vector& types) { + // The correctness of this part depends on some interesting properties of + // strongly connected graphs with ordered, directed edges. A permutation of + // the vertices in a graph is an isomorphism that produces an isomorphic + // graph. An automorphism is an isomorphism of a structure onto itself, so + // an automorphism of a graph is a permutation of the vertices that does not + // change the label-independent properties of a graph. Permutations can be + // described in terms of sets of cycles of elements. + // + // As an example, consider this strongly-connected recursion group: + // + // (rec + // (type $a1 (struct (field (ref $a2) (ref $b1)))) + // (type $a2 (struct (field (ref $a1) (ref $b2)))) + // (type $b1 (struct (field (ref $b2) (ref $a1)))) + // (type $b2 (struct (field (ref $b1) (ref $a2)))) + // ) + // + // This group has one nontrivial automorphism: ($a1 $a2) ($b1 $b2). Applying + // this automorphism gives this recursion group: + // + // (rec + // (type $a2 (struct (field (ref $a1) (ref $b2)))) + // (type $a1 (struct (field (ref $a2) (ref $b1)))) + // (type $b2 (struct (field (ref $b1) (ref $a2)))) + // (type $b1 (struct (field (ref $b2) (ref $a1)))) + // ) + // + // We can verify that the permutation was an automorphism by checking that + // the label-independent properties of these two rec groups are the same. + // Indeed, when we write the adjacency matrices with ordered edges for the + // two graphs, they both come out to this: + // + // 0: _ 0 1 _ + // 1: 0 _ _ 1 + // 2: 1 _ _ 0 + // 3: _ 1 0 _ + // + // In addition to having the same adjacency matrix, the two recursion groups + // have the same vertex colorings since all of their types have the same + // top-level structure. Since the label-independent properties of the + // recursion groups (i.e. all the properties except the intended type + // identity at each index) are the same, the permutation that takes one + // group to the other is an automorphism. These are precisely the + // permutations that do not change a recursion group's shape, so would not + // change type identity under WebAssembly's isorecursive type system. In + // other words, automorphisms cannot help us resolve shape conflicts, so we + // want to avoid generating them. + // + // Theorem 1: All cycles in an automorphism of a strongly-connected + // recursion group are the same size. + // + // Proof: By contradiction. Assume there are two cycles of different + // sizes. Because the group is strongly connected, there is a path from + // an element in the smaller of these cycles to an element in the + // larger. This path must contain an edge between two vertices in cycles + // of different sizes N and M such that N < M. Apply the automorphism N + // times. The source of this edge has been cycled back to its original + // index, but the destination is not yet back at its original index, so + // the edge's destination index is different from its original + // destination index and the permutation we applied was not an + // automorphism after all. + // + // Corollary 1.1: No nontrivial automorphism of an SCC may have a stationary + // element, since either all the cycles have size 1 and the automorphism is + // trivial or all the cycles have some other size and there are no + // stationary elements. + // + // Corollary 1.2: No two distinct permutations of an SCC with the same first + // element (e.g. both with some type $t as the first element) have the same + // shape, since no nontrivial automorphism can keep the first element + // stationary while mapping one permutation to the other. + // + // Find a canonical ordering of the types in this group. The ordering must + // be independent of the initial order of the types. To do so, consider the + // orderings given by visitation order on a tree search rooted at each type + // in the group. Since the group is strongly connected, a tree search from + // any of types will visit all types in the group, so it will generate a + // total and deterministic ordering of the types in the group. We can + // compare the shapes of each of these orderings to organize the root + // types and their generated orderings into ordered equivalence classes. + // These equivalence classes each correspond to a cycle in an automorphism + // of the graph because their elements are vertices that can all occupy the + // initial index of the graph without the graph structure changing. We can + // choose an arbitrary ordering from the least equivalence class as a + // canonical ordering because all orderings in that class describe the same + // label-independent graph. + // + // Compute the orderings generated by DFS on each type. + std::unordered_set typeSet(types.begin(), types.end()); + std::vector> dfsOrders(types.size()); + for (size_t i = 0; i < types.size(); ++i) { + dfsOrders[i].reserve(types.size()); + std::vector workList; + workList.push_back(types[i]); + std::unordered_set seen; + while (!workList.empty()) { + auto curr = workList.back(); + workList.pop_back(); + if (!typeSet.count(curr)) { + continue; + } + if (seen.insert(curr).second) { + dfsOrders[i].push_back(curr); + auto children = curr.getReferencedHeapTypes(); + workList.insert(workList.end(), children.rbegin(), children.rend()); + } + } + assert(dfsOrders[i].size() == types.size()); + } + + // Organize the orderings into equivalence classes, mapping equivalent + // shapes to lists of automorphically equivalent root types. + std::map> typeClasses; + for (const auto& order : dfsOrders) { + ComparableRecGroupShape shape(order, [this](HeapType a, HeapType b) { + return this->typeIndices.at(a) < this->typeIndices.at(b); + }); + typeClasses[shape].push_back(order[0]); + } + + // Choose the initial canonical ordering. + const auto& leastOrder = typeClasses.begin()->first.types; + + // We want our canonical ordering to have the additional property that it + // contains one type from each equivalence class before a second type of any + // equivalence class. Since our utility for enumerating the topological + // sorts of the canonical order keeps the initial element fixed as long as + // possible before moving to the next one, by Corollary 1.2 and because + // permutations that begin with types in different equivalence class cannot + // have the same shape (otherwise those initial types would be in the same + // equivalence class), this will maximize the number of distinct shapes the + // utility emits before starting to emit permutations that have the same + // shapes as previous permutations. Since all the type equivalence classes + // are the same size by Theorem 1, we can assemble the final order by + // striping across the equivalence classes. We determine the order of types + // taken from each equivalence class by sorting them by order of appearance + // in the least order, which ensures the final order remains independent of + // the initial order. + std::unordered_map indexInLeastOrder; + for (auto type : leastOrder) { + indexInLeastOrder.insert({type, indexInLeastOrder.size()}); + } + auto classSize = typeClasses.begin()->second.size(); + for (auto& [shape, members] : typeClasses) { + assert(members.size() == classSize); + std::sort(members.begin(), members.end(), [&](HeapType a, HeapType b) { + return indexInLeastOrder.at(a) < indexInLeastOrder.at(b); + }); + } + std::vector finalOrder; + finalOrder.reserve(types.size()); + for (size_t i = 0; i < classSize; ++i) { + for (auto& [shape, members] : typeClasses) { + finalOrder.push_back(members[i]); + } + } + + // Now what we actually want is the permutation that takes us from the final + // canonical order to the original order of the types. + std::unordered_map indexInFinalOrder; + for (auto type : finalOrder) { + indexInFinalOrder.insert({type, indexInFinalOrder.size()}); + } + std::vector permutation; + permutation.reserve(types.size()); + for (auto type : types) { + permutation.push_back(indexInFinalOrder.at(type)); + } + return permutation; + } + + void rewriteTypes(Module& wasm) { + // Map types to indices in the builder. + std::unordered_map outputIndices; + size_t i = 0; + for (const auto& group : groups) { + for (size_t j = 0; j < group.group.size(); ++j) { + // Skip the brand if it exists. + if (!group.hasBrand || group.permutation[j] != 0) { + outputIndices.insert({group.group[j], i}); + } + ++i; + } + } + + // Build the types. + TypeBuilder builder(i); + i = 0; + for (const auto& group : groups) { + builder.createRecGroup(i, group.group.size()); + for (auto type : group.group) { + builder[i++].copy(type, [&](HeapType ht) -> HeapType { + if (auto it = outputIndices.find(ht); it != outputIndices.end()) { + return builder[it->second]; + } + return ht; + }); + } + } + auto built = builder.build(); + assert(built); + auto newTypes = *built; + + // Replace the types in the module. + std::unordered_map oldToNew; + i = 0; + for (const auto& group : groups) { + for (size_t j = 0; j < group.group.size(); ++j) { + // Skip the brand again if it exists. + if (!group.hasBrand || group.permutation[j] != 0) { + oldToNew[group.group[j]] = newTypes[i]; + } + ++i; + } + } + GlobalTypeRewriter rewriter(wasm); + rewriter.mapTypes(oldToNew); + rewriter.mapTypeNames(oldToNew); + } +}; + +} // anonymous namespace + +Pass* createMinimizeRecGroupsPass() { return new MinimizeRecGroups(); } + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 3f84ee60464..ccfc7b728d3 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -290,6 +290,9 @@ void PassRegistry::registerPasses() { "minifies both import and export names, and emits a mapping to " "the minified ones, and minifies the modules as well", createMinifyImportsAndExportsAndModulesPass); + registerPass("minimize-rec-groups", + "Split types into minimal recursion groups", + createMinimizeRecGroupsPass); registerPass("mod-asyncify-always-and-only-unwind", "apply the assumption that asyncify imports always unwind, " "and we never rewind", diff --git a/src/passes/passes.h b/src/passes/passes.h index bd3aabf9f7e..9fcb5f95fb2 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -88,6 +88,7 @@ Pass* createMinifiedPrinterPass(); Pass* createMinifyImportsPass(); Pass* createMinifyImportsAndExportsPass(); Pass* createMinifyImportsAndExportsAndModulesPass(); +Pass* createMinimizeRecGroupsPass(); Pass* createMetricsPass(); Pass* createMonomorphizePass(); Pass* createMonomorphizeAlwaysPass(); diff --git a/src/wasm/wasm-type-shape.cpp b/src/wasm/wasm-type-shape.cpp index 99398bb7b71..b1f74d49177 100644 --- a/src/wasm/wasm-type-shape.cpp +++ b/src/wasm/wasm-type-shape.cpp @@ -187,6 +187,7 @@ template struct RecGroupComparator { if (indexA != indexB) { return indexA < indexB ? LT : GT; } + return EQ; } // These types are external to the group, so fall back to the provided // comparator. diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index 8a2107ca79f..c40f2e22be6 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -269,6 +269,9 @@ ;; CHECK-NEXT: the minified ones, and minifies ;; CHECK-NEXT: the modules as well ;; CHECK-NEXT: +;; CHECK-NEXT: --minimize-rec-groups Split types into minimal +;; CHECK-NEXT: recursion groups +;; CHECK-NEXT: ;; CHECK-NEXT: --mod-asyncify-always-and-only-unwind apply the assumption that ;; CHECK-NEXT: asyncify imports always unwind, ;; CHECK-NEXT: and we never rewind diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index a48b8e303e4..a1df2640a6b 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -278,6 +278,9 @@ ;; CHECK-NEXT: the minified ones, and minifies ;; CHECK-NEXT: the modules as well ;; CHECK-NEXT: +;; CHECK-NEXT: --minimize-rec-groups Split types into minimal +;; CHECK-NEXT: recursion groups +;; CHECK-NEXT: ;; CHECK-NEXT: --mod-asyncify-always-and-only-unwind apply the assumption that ;; CHECK-NEXT: asyncify imports always unwind, ;; CHECK-NEXT: and we never rewind diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 0b87ad0aa66..beefdbbd718 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -232,6 +232,9 @@ ;; CHECK-NEXT: the minified ones, and minifies ;; CHECK-NEXT: the modules as well ;; CHECK-NEXT: +;; CHECK-NEXT: --minimize-rec-groups Split types into minimal +;; CHECK-NEXT: recursion groups +;; CHECK-NEXT: ;; CHECK-NEXT: --mod-asyncify-always-and-only-unwind apply the assumption that ;; CHECK-NEXT: asyncify imports always unwind, ;; CHECK-NEXT: and we never rewind diff --git a/test/lit/passes/minimize-rec-groups-brands.wast b/test/lit/passes/minimize-rec-groups-brands.wast new file mode 100644 index 00000000000..861f8870530 --- /dev/null +++ b/test/lit/passes/minimize-rec-groups-brands.wast @@ -0,0 +1,1378 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s -all --minimize-rec-groups -S -o - | filecheck %s + +;; Check that brands increment correctly once we get into structs with multiple +;; fields. This requires very many duplicate SCCs. + +(module + (rec + ;; CHECK: (type $0 (struct)) + (type $0 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $10 (struct)) + + ;; CHECK: (type $200 (array (mut i32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $201 (array i32)) + + ;; CHECK: (type $11 (struct)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $12 (struct)) + + ;; CHECK: (type $204 (array i32)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $205 (array (mut i64))) + + ;; CHECK: (type $13 (struct)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $14 (struct)) + + ;; CHECK: (type $208 (array (mut i64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $209 (array i64)) + + ;; CHECK: (type $15 (struct)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $16 (struct)) + + ;; CHECK: (type $212 (array i64)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $213 (array (mut f32))) + + ;; CHECK: (type $17 (struct)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $18 (struct)) + + ;; CHECK: (type $216 (array (mut f32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $217 (array f32)) + + ;; CHECK: (type $19 (struct)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $219 (array (mut i8))) + + ;; CHECK: (type $1 (struct)) + (type $1 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (struct)) + (type $2 (struct)) + ;; CHECK: (type $222 (array (mut i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $223 (array i8)) + + ;; CHECK: (type $3 (struct)) + (type $3 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $4 (struct)) + (type $4 (struct)) + ;; CHECK: (type $226 (array i8)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $227 (array (mut i16))) + + ;; CHECK: (type $5 (struct)) + (type $5 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $6 (struct)) + (type $6 (struct)) + ;; CHECK: (type $230 (array (mut i16))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $231 (array i16)) + + ;; CHECK: (type $7 (struct)) + (type $7 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $8 (struct)) + (type $8 (struct)) + ;; CHECK: (type $234 (array i16)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $235 (array (mut i32))) + + ;; CHECK: (type $9 (struct)) + (type $9 (struct)) + (type $10 (struct)) + (type $11 (struct)) + (type $12 (struct)) + (type $13 (struct)) + (type $14 (struct)) + (type $15 (struct)) + (type $16 (struct)) + (type $17 (struct)) + (type $18 (struct)) + (type $19 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $20 (struct)) + (type $20 (struct)) + ;; CHECK: (type $238 (array f32)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $239 (array (mut f64))) + + ;; CHECK: (type $21 (struct)) + (type $21 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $22 (struct)) + (type $22 (struct)) + ;; CHECK: (type $242 (array (mut f64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $243 (array f64)) + + ;; CHECK: (type $23 (struct)) + (type $23 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $24 (struct)) + (type $24 (struct)) + ;; CHECK: (type $246 (array f64)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $247 (array (mut anyref))) + + ;; CHECK: (type $25 (struct)) + (type $25 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $26 (struct)) + (type $26 (struct)) + ;; CHECK: (type $250 (array (mut anyref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $251 (array anyref)) + + ;; CHECK: (type $27 (struct)) + (type $27 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $28 (struct)) + (type $28 (struct)) + ;; CHECK: (type $254 (array anyref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $255 (array (mut funcref))) + + ;; CHECK: (type $29 (struct)) + (type $29 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $30 (struct)) + (type $30 (struct)) + ;; CHECK: (type $258 (array (mut funcref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $259 (array funcref)) + + ;; CHECK: (type $31 (struct)) + (type $31 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $32 (struct)) + (type $32 (struct)) + ;; CHECK: (type $262 (array funcref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $263 (array (mut externref))) + + ;; CHECK: (type $33 (struct)) + (type $33 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $34 (struct)) + (type $34 (struct)) + ;; CHECK: (type $266 (array (mut externref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $267 (array externref)) + + ;; CHECK: (type $35 (struct)) + (type $35 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $36 (struct)) + (type $36 (struct)) + ;; CHECK: (type $270 (array externref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $271 (array (mut nullref))) + + ;; CHECK: (type $37 (struct)) + (type $37 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $38 (struct)) + (type $38 (struct)) + ;; CHECK: (type $274 (array (mut nullref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $275 (array nullref)) + + ;; CHECK: (type $39 (struct)) + (type $39 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $40 (struct)) + (type $40 (struct)) + ;; CHECK: (type $278 (array nullref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $279 (array (mut nullfuncref))) + + ;; CHECK: (type $41 (struct)) + (type $41 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $42 (struct)) + (type $42 (struct)) + ;; CHECK: (type $282 (array (mut nullfuncref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $283 (array nullfuncref)) + + ;; CHECK: (type $43 (struct)) + (type $43 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $44 (struct)) + (type $44 (struct)) + ;; CHECK: (type $286 (array nullfuncref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $287 (array (mut nullexternref))) + + ;; CHECK: (type $45 (struct)) + (type $45 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $46 (struct)) + (type $46 (struct)) + ;; CHECK: (type $290 (array (mut nullexternref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $291 (array nullexternref)) + + ;; CHECK: (type $47 (struct)) + (type $47 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $48 (struct)) + (type $48 (struct)) + ;; CHECK: (type $294 (array nullexternref)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $295 (array (mut (ref any)))) + + ;; CHECK: (type $49 (struct)) + (type $49 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $50 (struct)) + (type $50 (struct)) + ;; CHECK: (type $298 (array (mut (ref any)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $299 (array (ref any))) + + ;; CHECK: (type $51 (struct)) + (type $51 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $52 (struct)) + (type $52 (struct)) + ;; CHECK: (type $302 (array (ref any))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $303 (array (mut (ref func)))) + + ;; CHECK: (type $53 (struct)) + (type $53 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $54 (struct)) + (type $54 (struct)) + ;; CHECK: (type $306 (array (mut (ref func)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $307 (array (ref func))) + + ;; CHECK: (type $55 (struct)) + (type $55 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $56 (struct)) + (type $56 (struct)) + ;; CHECK: (type $310 (array (ref func))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $311 (array (mut (ref extern)))) + + ;; CHECK: (type $57 (struct)) + (type $57 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $58 (struct)) + (type $58 (struct)) + ;; CHECK: (type $314 (array (mut (ref extern)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $315 (array (ref extern))) + + ;; CHECK: (type $59 (struct)) + (type $59 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $60 (struct)) + (type $60 (struct)) + ;; CHECK: (type $318 (array (ref extern))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $319 (array (mut (ref none)))) + + ;; CHECK: (type $61 (struct)) + (type $61 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $62 (struct)) + (type $62 (struct)) + ;; CHECK: (type $322 (array (mut (ref none)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $323 (array (ref none))) + + ;; CHECK: (type $63 (struct)) + (type $63 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $64 (struct)) + (type $64 (struct)) + ;; CHECK: (type $326 (array (ref none))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $327 (array (mut (ref nofunc)))) + + ;; CHECK: (type $65 (struct)) + (type $65 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $66 (struct)) + (type $66 (struct)) + ;; CHECK: (type $330 (array (mut (ref nofunc)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $331 (array (ref nofunc))) + + ;; CHECK: (type $67 (struct)) + (type $67 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $68 (struct)) + (type $68 (struct)) + ;; CHECK: (type $334 (array (ref nofunc))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $335 (array (mut (ref noextern)))) + + ;; CHECK: (type $69 (struct)) + (type $69 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $70 (struct)) + (type $70 (struct)) + ;; CHECK: (type $338 (array (mut (ref noextern)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $339 (array (ref noextern))) + + ;; CHECK: (type $71 (struct)) + (type $71 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $72 (struct)) + (type $72 (struct)) + ;; CHECK: (type $342 (array (ref noextern))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $343 (struct (field (mut i8)))) + + ;; CHECK: (type $73 (struct)) + (type $73 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $74 (struct)) + (type $74 (struct)) + ;; CHECK: (type $346 (struct (field (mut i8)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $347 (struct (field i8))) + + ;; CHECK: (type $75 (struct)) + (type $75 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $76 (struct)) + (type $76 (struct)) + ;; CHECK: (type $350 (struct (field i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $351 (struct (field (mut i16)))) + + ;; CHECK: (type $77 (struct)) + (type $77 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $78 (struct)) + (type $78 (struct)) + ;; CHECK: (type $354 (struct (field (mut i16)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $355 (struct (field i16))) + + ;; CHECK: (type $79 (struct)) + (type $79 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $80 (struct)) + (type $80 (struct)) + ;; CHECK: (type $358 (struct (field i16))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $359 (struct (field (mut i32)))) + + ;; CHECK: (type $81 (struct)) + (type $81 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $82 (struct)) + (type $82 (struct)) + ;; CHECK: (type $362 (struct (field (mut i32)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $363 (struct (field i32))) + + ;; CHECK: (type $83 (struct)) + (type $83 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $84 (struct)) + (type $84 (struct)) + ;; CHECK: (type $366 (struct (field i32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $367 (struct (field (mut i64)))) + + ;; CHECK: (type $85 (struct)) + (type $85 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $86 (struct)) + (type $86 (struct)) + ;; CHECK: (type $370 (struct (field (mut i64)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $371 (struct (field i64))) + + ;; CHECK: (type $87 (struct)) + (type $87 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $88 (struct)) + (type $88 (struct)) + ;; CHECK: (type $374 (struct (field i64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $375 (struct (field (mut f32)))) + + ;; CHECK: (type $89 (struct)) + (type $89 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $90 (struct)) + (type $90 (struct)) + ;; CHECK: (type $378 (struct (field (mut f32)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $379 (struct (field f32))) + + ;; CHECK: (type $91 (struct)) + (type $91 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $92 (struct)) + (type $92 (struct)) + ;; CHECK: (type $382 (struct (field f32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $383 (struct (field (mut f64)))) + + ;; CHECK: (type $93 (struct)) + (type $93 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $94 (struct)) + (type $94 (struct)) + ;; CHECK: (type $386 (struct (field (mut f64)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $387 (struct (field f64))) + + ;; CHECK: (type $95 (struct)) + (type $95 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $96 (struct)) + (type $96 (struct)) + ;; CHECK: (type $390 (struct (field f64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $391 (struct (field (mut anyref)))) + + ;; CHECK: (type $97 (struct)) + (type $97 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $98 (struct)) + (type $98 (struct)) + ;; CHECK: (type $394 (struct (field (mut anyref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $395 (struct (field anyref))) + + ;; CHECK: (type $99 (struct)) + (type $99 (struct)) + (type $100 (struct)) + (type $101 (struct)) + (type $102 (struct)) + (type $103 (struct)) + (type $104 (struct)) + (type $105 (struct)) + (type $106 (struct)) + (type $107 (struct)) + (type $108 (struct)) + (type $109 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $110 (struct)) + (type $110 (struct)) + ;; CHECK: (type $398 (struct (field anyref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $399 (struct (field (mut funcref)))) + + ;; CHECK: (type $111 (struct)) + (type $111 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $112 (struct)) + (type $112 (struct)) + ;; CHECK: (type $402 (struct (field (mut funcref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $403 (struct (field funcref))) + + ;; CHECK: (type $113 (struct)) + (type $113 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $114 (struct)) + (type $114 (struct)) + ;; CHECK: (type $406 (struct (field funcref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $407 (struct (field (mut externref)))) + + ;; CHECK: (type $115 (struct)) + (type $115 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $116 (struct)) + (type $116 (struct)) + ;; CHECK: (type $410 (struct (field (mut externref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $411 (struct (field externref))) + + ;; CHECK: (type $117 (struct)) + (type $117 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $118 (struct)) + (type $118 (struct)) + ;; CHECK: (type $414 (struct (field externref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $415 (struct (field (mut nullref)))) + + ;; CHECK: (type $119 (struct)) + (type $119 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $120 (struct)) + (type $120 (struct)) + ;; CHECK: (type $418 (struct (field (mut nullref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $419 (struct (field nullref))) + + ;; CHECK: (type $121 (struct)) + (type $121 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $122 (struct)) + (type $122 (struct)) + ;; CHECK: (type $422 (struct (field nullref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $423 (struct (field (mut nullfuncref)))) + + ;; CHECK: (type $123 (struct)) + (type $123 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $124 (struct)) + (type $124 (struct)) + ;; CHECK: (type $426 (struct (field (mut nullfuncref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $427 (struct (field nullfuncref))) + + ;; CHECK: (type $125 (struct)) + (type $125 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $126 (struct)) + (type $126 (struct)) + ;; CHECK: (type $430 (struct (field nullfuncref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $431 (struct (field (mut nullexternref)))) + + ;; CHECK: (type $127 (struct)) + (type $127 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $128 (struct)) + (type $128 (struct)) + ;; CHECK: (type $434 (struct (field (mut nullexternref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $435 (struct (field nullexternref))) + + ;; CHECK: (type $129 (struct)) + (type $129 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $130 (struct)) + (type $130 (struct)) + ;; CHECK: (type $438 (struct (field nullexternref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $439 (struct (field (mut (ref any))))) + + ;; CHECK: (type $131 (struct)) + (type $131 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $132 (struct)) + (type $132 (struct)) + ;; CHECK: (type $442 (struct (field (mut (ref any))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $443 (struct (field (ref any)))) + + ;; CHECK: (type $133 (struct)) + (type $133 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $134 (struct)) + (type $134 (struct)) + ;; CHECK: (type $446 (struct (field (ref any)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $447 (struct (field (mut (ref func))))) + + ;; CHECK: (type $135 (struct)) + (type $135 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $136 (struct)) + (type $136 (struct)) + ;; CHECK: (type $450 (struct (field (mut (ref func))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $451 (struct (field (ref func)))) + + ;; CHECK: (type $137 (struct)) + (type $137 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $138 (struct)) + (type $138 (struct)) + ;; CHECK: (type $454 (struct (field (ref func)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $455 (struct (field (mut (ref extern))))) + + ;; CHECK: (type $139 (struct)) + (type $139 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $140 (struct)) + (type $140 (struct)) + ;; CHECK: (type $458 (struct (field (mut (ref extern))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $459 (struct (field (ref extern)))) + + ;; CHECK: (type $141 (struct)) + (type $141 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $142 (struct)) + (type $142 (struct)) + ;; CHECK: (type $462 (struct (field (ref extern)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $463 (struct (field (mut (ref none))))) + + ;; CHECK: (type $143 (struct)) + (type $143 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $144 (struct)) + (type $144 (struct)) + ;; CHECK: (type $466 (struct (field (mut (ref none))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $467 (struct (field (ref none)))) + + ;; CHECK: (type $145 (struct)) + (type $145 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $146 (struct)) + (type $146 (struct)) + ;; CHECK: (type $470 (struct (field (ref none)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $471 (struct (field (mut (ref nofunc))))) + + ;; CHECK: (type $147 (struct)) + (type $147 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $148 (struct)) + (type $148 (struct)) + ;; CHECK: (type $474 (struct (field (mut (ref nofunc))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $475 (struct (field (ref nofunc)))) + + ;; CHECK: (type $149 (struct)) + (type $149 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $150 (struct)) + (type $150 (struct)) + ;; CHECK: (type $478 (struct (field (ref nofunc)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $479 (struct (field (mut (ref noextern))))) + + ;; CHECK: (type $151 (struct)) + (type $151 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $152 (struct)) + (type $152 (struct)) + ;; CHECK: (type $482 (struct (field (mut (ref noextern))))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $483 (struct (field (ref noextern)))) + + ;; CHECK: (type $153 (struct)) + (type $153 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $154 (struct)) + (type $154 (struct)) + ;; CHECK: (type $486 (struct (field (ref noextern)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $487 (struct (field (mut i8)) (field (mut i8)))) + + ;; CHECK: (type $155 (struct)) + (type $155 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $156 (struct)) + (type $156 (struct)) + ;; CHECK: (type $490 (struct (field (mut i8)) (field (mut i8)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $491 (struct (field (mut i8)) (field i8))) + + ;; CHECK: (type $157 (struct)) + (type $157 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $158 (struct)) + (type $158 (struct)) + ;; CHECK: (type $494 (struct (field (mut i8)) (field i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $495 (struct (field (mut i8)) (field (mut i16)))) + + ;; CHECK: (type $159 (struct)) + (type $159 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $160 (struct)) + (type $160 (struct)) + ;; CHECK: (type $498 (struct (field (mut i8)) (field (mut i16)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $499 (struct (field (mut i8)) (field i16))) + + ;; CHECK: (type $161 (struct)) + (type $161 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $162 (struct)) + (type $162 (struct)) + ;; CHECK: (type $502 (struct (field (mut i8)) (field i16))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $503 (struct (field (mut i8)) (field (mut i32)))) + + ;; CHECK: (type $163 (struct)) + (type $163 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $164 (struct)) + (type $164 (struct)) + ;; CHECK: (type $506 (struct (field (mut i8)) (field (mut i32)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $507 (struct (field (mut i8)) (field i32))) + + ;; CHECK: (type $165 (struct)) + (type $165 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $166 (struct)) + (type $166 (struct)) + ;; CHECK: (type $510 (struct (field (mut i8)) (field i32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $511 (struct (field (mut i8)) (field (mut i64)))) + + ;; CHECK: (type $167 (struct)) + (type $167 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $168 (struct)) + (type $168 (struct)) + ;; CHECK: (type $514 (struct (field (mut i8)) (field (mut i64)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $515 (struct (field (mut i8)) (field i64))) + + ;; CHECK: (type $169 (struct)) + (type $169 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $170 (struct)) + (type $170 (struct)) + ;; CHECK: (type $518 (struct (field (mut i8)) (field i64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $519 (struct (field (mut i8)) (field (mut f32)))) + + ;; CHECK: (type $171 (struct)) + (type $171 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $172 (struct)) + (type $172 (struct)) + ;; CHECK: (type $522 (struct (field (mut i8)) (field (mut f32)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $523 (struct (field (mut i8)) (field f32))) + + ;; CHECK: (type $173 (struct)) + (type $173 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $174 (struct)) + (type $174 (struct)) + ;; CHECK: (type $526 (struct (field (mut i8)) (field f32))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $527 (struct (field (mut i8)) (field (mut f64)))) + + ;; CHECK: (type $175 (struct)) + (type $175 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $176 (struct)) + (type $176 (struct)) + ;; CHECK: (type $530 (struct (field (mut i8)) (field (mut f64)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $531 (struct (field (mut i8)) (field f64))) + + ;; CHECK: (type $177 (struct)) + (type $177 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $178 (struct)) + (type $178 (struct)) + ;; CHECK: (type $534 (struct (field (mut i8)) (field f64))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $535 (struct (field (mut i8)) (field (mut anyref)))) + + ;; CHECK: (type $179 (struct)) + (type $179 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $180 (struct)) + (type $180 (struct)) + ;; CHECK: (type $538 (struct (field (mut i8)) (field (mut anyref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $539 (struct (field (mut i8)) (field anyref))) + + ;; CHECK: (type $181 (struct)) + (type $181 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $182 (struct)) + (type $182 (struct)) + ;; CHECK: (type $542 (struct (field (mut i8)) (field anyref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $543 (struct (field (mut i8)) (field (mut funcref)))) + + ;; CHECK: (type $183 (struct)) + (type $183 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $184 (struct)) + (type $184 (struct)) + ;; CHECK: (type $546 (struct (field (mut i8)) (field (mut funcref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $547 (struct (field (mut i8)) (field funcref))) + + ;; CHECK: (type $185 (struct)) + (type $185 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $186 (struct)) + (type $186 (struct)) + ;; CHECK: (type $550 (struct (field (mut i8)) (field funcref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $551 (struct (field (mut i8)) (field (mut externref)))) + + ;; CHECK: (type $187 (struct)) + (type $187 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $188 (struct)) + (type $188 (struct)) + ;; CHECK: (type $554 (struct (field (mut i8)) (field (mut externref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $555 (struct (field (mut i8)) (field externref))) + + ;; CHECK: (type $189 (struct)) + (type $189 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $190 (struct)) + (type $190 (struct)) + ;; CHECK: (type $558 (struct (field (mut i8)) (field externref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $559 (struct (field (mut i8)) (field (mut nullref)))) + + ;; CHECK: (type $191 (struct)) + (type $191 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $192 (struct)) + (type $192 (struct)) + ;; CHECK: (type $562 (struct (field (mut i8)) (field (mut nullref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $563 (struct (field (mut i8)) (field nullref))) + + ;; CHECK: (type $193 (struct)) + (type $193 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $194 (struct)) + (type $194 (struct)) + ;; CHECK: (type $566 (struct (field (mut i8)) (field nullref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $567 (struct (field (mut i8)) (field (mut nullfuncref)))) + + ;; CHECK: (type $195 (struct)) + (type $195 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $196 (struct)) + (type $196 (struct)) + ;; CHECK: (type $570 (struct (field (mut i8)) (field (mut nullfuncref)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $571 (struct (field (mut i8)) (field nullfuncref))) + + ;; CHECK: (type $197 (struct)) + (type $197 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $198 (struct)) + (type $198 (struct)) + ;; CHECK: (type $574 (struct (field (mut i8)) (field nullfuncref))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $575 (struct (field (mut i8)) (field (mut nullexternref)))) + + ;; CHECK: (type $199 (struct)) + (type $199 (struct)) + ) + + ;; CHECK: (global $0 (ref null $0) (ref.null none)) + (global $0 (ref null $0) (ref.null none)) + ;; CHECK: (global $1 (ref null $1) (ref.null none)) + (global $1 (ref null $1) (ref.null none)) + ;; CHECK: (global $2 (ref null $2) (ref.null none)) + (global $2 (ref null $2) (ref.null none)) + ;; CHECK: (global $3 (ref null $3) (ref.null none)) + (global $3 (ref null $3) (ref.null none)) + ;; CHECK: (global $4 (ref null $4) (ref.null none)) + (global $4 (ref null $4) (ref.null none)) + ;; CHECK: (global $5 (ref null $5) (ref.null none)) + (global $5 (ref null $5) (ref.null none)) + ;; CHECK: (global $6 (ref null $6) (ref.null none)) + (global $6 (ref null $6) (ref.null none)) + ;; CHECK: (global $7 (ref null $7) (ref.null none)) + (global $7 (ref null $7) (ref.null none)) + ;; CHECK: (global $8 (ref null $8) (ref.null none)) + (global $8 (ref null $8) (ref.null none)) + ;; CHECK: (global $9 (ref null $9) (ref.null none)) + (global $9 (ref null $9) (ref.null none)) + ;; CHECK: (global $10 (ref null $10) (ref.null none)) + (global $10 (ref null $10) (ref.null none)) + ;; CHECK: (global $11 (ref null $11) (ref.null none)) + (global $11 (ref null $11) (ref.null none)) + ;; CHECK: (global $12 (ref null $12) (ref.null none)) + (global $12 (ref null $12) (ref.null none)) + ;; CHECK: (global $13 (ref null $13) (ref.null none)) + (global $13 (ref null $13) (ref.null none)) + ;; CHECK: (global $14 (ref null $14) (ref.null none)) + (global $14 (ref null $14) (ref.null none)) + ;; CHECK: (global $15 (ref null $15) (ref.null none)) + (global $15 (ref null $15) (ref.null none)) + ;; CHECK: (global $16 (ref null $16) (ref.null none)) + (global $16 (ref null $16) (ref.null none)) + ;; CHECK: (global $17 (ref null $17) (ref.null none)) + (global $17 (ref null $17) (ref.null none)) + ;; CHECK: (global $18 (ref null $18) (ref.null none)) + (global $18 (ref null $18) (ref.null none)) + ;; CHECK: (global $19 (ref null $19) (ref.null none)) + (global $19 (ref null $19) (ref.null none)) + ;; CHECK: (global $20 (ref null $20) (ref.null none)) + (global $20 (ref null $20) (ref.null none)) + ;; CHECK: (global $21 (ref null $21) (ref.null none)) + (global $21 (ref null $21) (ref.null none)) + ;; CHECK: (global $22 (ref null $22) (ref.null none)) + (global $22 (ref null $22) (ref.null none)) + ;; CHECK: (global $23 (ref null $23) (ref.null none)) + (global $23 (ref null $23) (ref.null none)) + ;; CHECK: (global $24 (ref null $24) (ref.null none)) + (global $24 (ref null $24) (ref.null none)) + ;; CHECK: (global $25 (ref null $25) (ref.null none)) + (global $25 (ref null $25) (ref.null none)) + ;; CHECK: (global $26 (ref null $26) (ref.null none)) + (global $26 (ref null $26) (ref.null none)) + ;; CHECK: (global $27 (ref null $27) (ref.null none)) + (global $27 (ref null $27) (ref.null none)) + ;; CHECK: (global $28 (ref null $28) (ref.null none)) + (global $28 (ref null $28) (ref.null none)) + ;; CHECK: (global $29 (ref null $29) (ref.null none)) + (global $29 (ref null $29) (ref.null none)) + ;; CHECK: (global $30 (ref null $30) (ref.null none)) + (global $30 (ref null $30) (ref.null none)) + ;; CHECK: (global $31 (ref null $31) (ref.null none)) + (global $31 (ref null $31) (ref.null none)) + ;; CHECK: (global $32 (ref null $32) (ref.null none)) + (global $32 (ref null $32) (ref.null none)) + ;; CHECK: (global $33 (ref null $33) (ref.null none)) + (global $33 (ref null $33) (ref.null none)) + ;; CHECK: (global $34 (ref null $34) (ref.null none)) + (global $34 (ref null $34) (ref.null none)) + ;; CHECK: (global $35 (ref null $35) (ref.null none)) + (global $35 (ref null $35) (ref.null none)) + ;; CHECK: (global $36 (ref null $36) (ref.null none)) + (global $36 (ref null $36) (ref.null none)) + ;; CHECK: (global $37 (ref null $37) (ref.null none)) + (global $37 (ref null $37) (ref.null none)) + ;; CHECK: (global $38 (ref null $38) (ref.null none)) + (global $38 (ref null $38) (ref.null none)) + ;; CHECK: (global $39 (ref null $39) (ref.null none)) + (global $39 (ref null $39) (ref.null none)) + ;; CHECK: (global $40 (ref null $40) (ref.null none)) + (global $40 (ref null $40) (ref.null none)) + ;; CHECK: (global $41 (ref null $41) (ref.null none)) + (global $41 (ref null $41) (ref.null none)) + ;; CHECK: (global $42 (ref null $42) (ref.null none)) + (global $42 (ref null $42) (ref.null none)) + ;; CHECK: (global $43 (ref null $43) (ref.null none)) + (global $43 (ref null $43) (ref.null none)) + ;; CHECK: (global $44 (ref null $44) (ref.null none)) + (global $44 (ref null $44) (ref.null none)) + ;; CHECK: (global $45 (ref null $45) (ref.null none)) + (global $45 (ref null $45) (ref.null none)) + ;; CHECK: (global $46 (ref null $46) (ref.null none)) + (global $46 (ref null $46) (ref.null none)) + ;; CHECK: (global $47 (ref null $47) (ref.null none)) + (global $47 (ref null $47) (ref.null none)) + ;; CHECK: (global $48 (ref null $48) (ref.null none)) + (global $48 (ref null $48) (ref.null none)) + ;; CHECK: (global $49 (ref null $49) (ref.null none)) + (global $49 (ref null $49) (ref.null none)) + ;; CHECK: (global $50 (ref null $50) (ref.null none)) + (global $50 (ref null $50) (ref.null none)) + ;; CHECK: (global $51 (ref null $51) (ref.null none)) + (global $51 (ref null $51) (ref.null none)) + ;; CHECK: (global $52 (ref null $52) (ref.null none)) + (global $52 (ref null $52) (ref.null none)) + ;; CHECK: (global $53 (ref null $53) (ref.null none)) + (global $53 (ref null $53) (ref.null none)) + ;; CHECK: (global $54 (ref null $54) (ref.null none)) + (global $54 (ref null $54) (ref.null none)) + ;; CHECK: (global $55 (ref null $55) (ref.null none)) + (global $55 (ref null $55) (ref.null none)) + ;; CHECK: (global $56 (ref null $56) (ref.null none)) + (global $56 (ref null $56) (ref.null none)) + ;; CHECK: (global $57 (ref null $57) (ref.null none)) + (global $57 (ref null $57) (ref.null none)) + ;; CHECK: (global $58 (ref null $58) (ref.null none)) + (global $58 (ref null $58) (ref.null none)) + ;; CHECK: (global $59 (ref null $59) (ref.null none)) + (global $59 (ref null $59) (ref.null none)) + ;; CHECK: (global $60 (ref null $60) (ref.null none)) + (global $60 (ref null $60) (ref.null none)) + ;; CHECK: (global $61 (ref null $61) (ref.null none)) + (global $61 (ref null $61) (ref.null none)) + ;; CHECK: (global $62 (ref null $62) (ref.null none)) + (global $62 (ref null $62) (ref.null none)) + ;; CHECK: (global $63 (ref null $63) (ref.null none)) + (global $63 (ref null $63) (ref.null none)) + ;; CHECK: (global $64 (ref null $64) (ref.null none)) + (global $64 (ref null $64) (ref.null none)) + ;; CHECK: (global $65 (ref null $65) (ref.null none)) + (global $65 (ref null $65) (ref.null none)) + ;; CHECK: (global $66 (ref null $66) (ref.null none)) + (global $66 (ref null $66) (ref.null none)) + ;; CHECK: (global $67 (ref null $67) (ref.null none)) + (global $67 (ref null $67) (ref.null none)) + ;; CHECK: (global $68 (ref null $68) (ref.null none)) + (global $68 (ref null $68) (ref.null none)) + ;; CHECK: (global $69 (ref null $69) (ref.null none)) + (global $69 (ref null $69) (ref.null none)) + ;; CHECK: (global $70 (ref null $70) (ref.null none)) + (global $70 (ref null $70) (ref.null none)) + ;; CHECK: (global $71 (ref null $71) (ref.null none)) + (global $71 (ref null $71) (ref.null none)) + ;; CHECK: (global $72 (ref null $72) (ref.null none)) + (global $72 (ref null $72) (ref.null none)) + ;; CHECK: (global $73 (ref null $73) (ref.null none)) + (global $73 (ref null $73) (ref.null none)) + ;; CHECK: (global $74 (ref null $74) (ref.null none)) + (global $74 (ref null $74) (ref.null none)) + ;; CHECK: (global $75 (ref null $75) (ref.null none)) + (global $75 (ref null $75) (ref.null none)) + ;; CHECK: (global $76 (ref null $76) (ref.null none)) + (global $76 (ref null $76) (ref.null none)) + ;; CHECK: (global $77 (ref null $77) (ref.null none)) + (global $77 (ref null $77) (ref.null none)) + ;; CHECK: (global $78 (ref null $78) (ref.null none)) + (global $78 (ref null $78) (ref.null none)) + ;; CHECK: (global $79 (ref null $79) (ref.null none)) + (global $79 (ref null $79) (ref.null none)) + ;; CHECK: (global $80 (ref null $80) (ref.null none)) + (global $80 (ref null $80) (ref.null none)) + ;; CHECK: (global $81 (ref null $81) (ref.null none)) + (global $81 (ref null $81) (ref.null none)) + ;; CHECK: (global $82 (ref null $82) (ref.null none)) + (global $82 (ref null $82) (ref.null none)) + ;; CHECK: (global $83 (ref null $83) (ref.null none)) + (global $83 (ref null $83) (ref.null none)) + ;; CHECK: (global $84 (ref null $84) (ref.null none)) + (global $84 (ref null $84) (ref.null none)) + ;; CHECK: (global $85 (ref null $85) (ref.null none)) + (global $85 (ref null $85) (ref.null none)) + ;; CHECK: (global $86 (ref null $86) (ref.null none)) + (global $86 (ref null $86) (ref.null none)) + ;; CHECK: (global $87 (ref null $87) (ref.null none)) + (global $87 (ref null $87) (ref.null none)) + ;; CHECK: (global $88 (ref null $88) (ref.null none)) + (global $88 (ref null $88) (ref.null none)) + ;; CHECK: (global $89 (ref null $89) (ref.null none)) + (global $89 (ref null $89) (ref.null none)) + ;; CHECK: (global $90 (ref null $90) (ref.null none)) + (global $90 (ref null $90) (ref.null none)) + ;; CHECK: (global $91 (ref null $91) (ref.null none)) + (global $91 (ref null $91) (ref.null none)) + ;; CHECK: (global $92 (ref null $92) (ref.null none)) + (global $92 (ref null $92) (ref.null none)) + ;; CHECK: (global $93 (ref null $93) (ref.null none)) + (global $93 (ref null $93) (ref.null none)) + ;; CHECK: (global $94 (ref null $94) (ref.null none)) + (global $94 (ref null $94) (ref.null none)) + ;; CHECK: (global $95 (ref null $95) (ref.null none)) + (global $95 (ref null $95) (ref.null none)) + ;; CHECK: (global $96 (ref null $96) (ref.null none)) + (global $96 (ref null $96) (ref.null none)) + ;; CHECK: (global $97 (ref null $97) (ref.null none)) + (global $97 (ref null $97) (ref.null none)) + ;; CHECK: (global $98 (ref null $98) (ref.null none)) + (global $98 (ref null $98) (ref.null none)) + ;; CHECK: (global $99 (ref null $99) (ref.null none)) + (global $99 (ref null $99) (ref.null none)) + ;; CHECK: (global $100 (ref null $10) (ref.null none)) + (global $100 (ref null $10) (ref.null none)) + ;; CHECK: (global $101 (ref null $11) (ref.null none)) + (global $101 (ref null $11) (ref.null none)) + ;; CHECK: (global $102 (ref null $12) (ref.null none)) + (global $102 (ref null $12) (ref.null none)) + ;; CHECK: (global $103 (ref null $13) (ref.null none)) + (global $103 (ref null $13) (ref.null none)) + ;; CHECK: (global $104 (ref null $14) (ref.null none)) + (global $104 (ref null $14) (ref.null none)) + ;; CHECK: (global $105 (ref null $15) (ref.null none)) + (global $105 (ref null $15) (ref.null none)) + ;; CHECK: (global $106 (ref null $16) (ref.null none)) + (global $106 (ref null $16) (ref.null none)) + ;; CHECK: (global $107 (ref null $17) (ref.null none)) + (global $107 (ref null $17) (ref.null none)) + ;; CHECK: (global $108 (ref null $18) (ref.null none)) + (global $108 (ref null $18) (ref.null none)) + ;; CHECK: (global $109 (ref null $19) (ref.null none)) + (global $109 (ref null $19) (ref.null none)) + ;; CHECK: (global $110 (ref null $110) (ref.null none)) + (global $110 (ref null $110) (ref.null none)) + ;; CHECK: (global $111 (ref null $111) (ref.null none)) + (global $111 (ref null $111) (ref.null none)) + ;; CHECK: (global $112 (ref null $112) (ref.null none)) + (global $112 (ref null $112) (ref.null none)) + ;; CHECK: (global $113 (ref null $113) (ref.null none)) + (global $113 (ref null $113) (ref.null none)) + ;; CHECK: (global $114 (ref null $114) (ref.null none)) + (global $114 (ref null $114) (ref.null none)) + ;; CHECK: (global $115 (ref null $115) (ref.null none)) + (global $115 (ref null $115) (ref.null none)) + ;; CHECK: (global $116 (ref null $116) (ref.null none)) + (global $116 (ref null $116) (ref.null none)) + ;; CHECK: (global $117 (ref null $117) (ref.null none)) + (global $117 (ref null $117) (ref.null none)) + ;; CHECK: (global $118 (ref null $118) (ref.null none)) + (global $118 (ref null $118) (ref.null none)) + ;; CHECK: (global $119 (ref null $119) (ref.null none)) + (global $119 (ref null $119) (ref.null none)) + ;; CHECK: (global $120 (ref null $120) (ref.null none)) + (global $120 (ref null $120) (ref.null none)) + ;; CHECK: (global $121 (ref null $121) (ref.null none)) + (global $121 (ref null $121) (ref.null none)) + ;; CHECK: (global $122 (ref null $122) (ref.null none)) + (global $122 (ref null $122) (ref.null none)) + ;; CHECK: (global $123 (ref null $123) (ref.null none)) + (global $123 (ref null $123) (ref.null none)) + ;; CHECK: (global $124 (ref null $124) (ref.null none)) + (global $124 (ref null $124) (ref.null none)) + ;; CHECK: (global $125 (ref null $125) (ref.null none)) + (global $125 (ref null $125) (ref.null none)) + ;; CHECK: (global $126 (ref null $126) (ref.null none)) + (global $126 (ref null $126) (ref.null none)) + ;; CHECK: (global $127 (ref null $127) (ref.null none)) + (global $127 (ref null $127) (ref.null none)) + ;; CHECK: (global $128 (ref null $128) (ref.null none)) + (global $128 (ref null $128) (ref.null none)) + ;; CHECK: (global $129 (ref null $129) (ref.null none)) + (global $129 (ref null $129) (ref.null none)) + ;; CHECK: (global $130 (ref null $130) (ref.null none)) + (global $130 (ref null $130) (ref.null none)) + ;; CHECK: (global $131 (ref null $131) (ref.null none)) + (global $131 (ref null $131) (ref.null none)) + ;; CHECK: (global $132 (ref null $132) (ref.null none)) + (global $132 (ref null $132) (ref.null none)) + ;; CHECK: (global $133 (ref null $133) (ref.null none)) + (global $133 (ref null $133) (ref.null none)) + ;; CHECK: (global $134 (ref null $134) (ref.null none)) + (global $134 (ref null $134) (ref.null none)) + ;; CHECK: (global $135 (ref null $135) (ref.null none)) + (global $135 (ref null $135) (ref.null none)) + ;; CHECK: (global $136 (ref null $136) (ref.null none)) + (global $136 (ref null $136) (ref.null none)) + ;; CHECK: (global $137 (ref null $137) (ref.null none)) + (global $137 (ref null $137) (ref.null none)) + ;; CHECK: (global $138 (ref null $138) (ref.null none)) + (global $138 (ref null $138) (ref.null none)) + ;; CHECK: (global $139 (ref null $139) (ref.null none)) + (global $139 (ref null $139) (ref.null none)) + ;; CHECK: (global $140 (ref null $140) (ref.null none)) + (global $140 (ref null $140) (ref.null none)) + ;; CHECK: (global $141 (ref null $141) (ref.null none)) + (global $141 (ref null $141) (ref.null none)) + ;; CHECK: (global $142 (ref null $142) (ref.null none)) + (global $142 (ref null $142) (ref.null none)) + ;; CHECK: (global $143 (ref null $143) (ref.null none)) + (global $143 (ref null $143) (ref.null none)) + ;; CHECK: (global $144 (ref null $144) (ref.null none)) + (global $144 (ref null $144) (ref.null none)) + ;; CHECK: (global $145 (ref null $145) (ref.null none)) + (global $145 (ref null $145) (ref.null none)) + ;; CHECK: (global $146 (ref null $146) (ref.null none)) + (global $146 (ref null $146) (ref.null none)) + ;; CHECK: (global $147 (ref null $147) (ref.null none)) + (global $147 (ref null $147) (ref.null none)) + ;; CHECK: (global $148 (ref null $148) (ref.null none)) + (global $148 (ref null $148) (ref.null none)) + ;; CHECK: (global $149 (ref null $149) (ref.null none)) + (global $149 (ref null $149) (ref.null none)) + ;; CHECK: (global $150 (ref null $150) (ref.null none)) + (global $150 (ref null $150) (ref.null none)) + ;; CHECK: (global $151 (ref null $151) (ref.null none)) + (global $151 (ref null $151) (ref.null none)) + ;; CHECK: (global $152 (ref null $152) (ref.null none)) + (global $152 (ref null $152) (ref.null none)) + ;; CHECK: (global $153 (ref null $153) (ref.null none)) + (global $153 (ref null $153) (ref.null none)) + ;; CHECK: (global $154 (ref null $154) (ref.null none)) + (global $154 (ref null $154) (ref.null none)) + ;; CHECK: (global $155 (ref null $155) (ref.null none)) + (global $155 (ref null $155) (ref.null none)) + ;; CHECK: (global $156 (ref null $156) (ref.null none)) + (global $156 (ref null $156) (ref.null none)) + ;; CHECK: (global $157 (ref null $157) (ref.null none)) + (global $157 (ref null $157) (ref.null none)) + ;; CHECK: (global $158 (ref null $158) (ref.null none)) + (global $158 (ref null $158) (ref.null none)) + ;; CHECK: (global $159 (ref null $159) (ref.null none)) + (global $159 (ref null $159) (ref.null none)) + ;; CHECK: (global $160 (ref null $160) (ref.null none)) + (global $160 (ref null $160) (ref.null none)) + ;; CHECK: (global $161 (ref null $161) (ref.null none)) + (global $161 (ref null $161) (ref.null none)) + ;; CHECK: (global $162 (ref null $162) (ref.null none)) + (global $162 (ref null $162) (ref.null none)) + ;; CHECK: (global $163 (ref null $163) (ref.null none)) + (global $163 (ref null $163) (ref.null none)) + ;; CHECK: (global $164 (ref null $164) (ref.null none)) + (global $164 (ref null $164) (ref.null none)) + ;; CHECK: (global $165 (ref null $165) (ref.null none)) + (global $165 (ref null $165) (ref.null none)) + ;; CHECK: (global $166 (ref null $166) (ref.null none)) + (global $166 (ref null $166) (ref.null none)) + ;; CHECK: (global $167 (ref null $167) (ref.null none)) + (global $167 (ref null $167) (ref.null none)) + ;; CHECK: (global $168 (ref null $168) (ref.null none)) + (global $168 (ref null $168) (ref.null none)) + ;; CHECK: (global $169 (ref null $169) (ref.null none)) + (global $169 (ref null $169) (ref.null none)) + ;; CHECK: (global $170 (ref null $170) (ref.null none)) + (global $170 (ref null $170) (ref.null none)) + ;; CHECK: (global $171 (ref null $171) (ref.null none)) + (global $171 (ref null $171) (ref.null none)) + ;; CHECK: (global $172 (ref null $172) (ref.null none)) + (global $172 (ref null $172) (ref.null none)) + ;; CHECK: (global $173 (ref null $173) (ref.null none)) + (global $173 (ref null $173) (ref.null none)) + ;; CHECK: (global $174 (ref null $174) (ref.null none)) + (global $174 (ref null $174) (ref.null none)) + ;; CHECK: (global $175 (ref null $175) (ref.null none)) + (global $175 (ref null $175) (ref.null none)) + ;; CHECK: (global $176 (ref null $176) (ref.null none)) + (global $176 (ref null $176) (ref.null none)) + ;; CHECK: (global $177 (ref null $177) (ref.null none)) + (global $177 (ref null $177) (ref.null none)) + ;; CHECK: (global $178 (ref null $178) (ref.null none)) + (global $178 (ref null $178) (ref.null none)) + ;; CHECK: (global $179 (ref null $179) (ref.null none)) + (global $179 (ref null $179) (ref.null none)) + ;; CHECK: (global $180 (ref null $180) (ref.null none)) + (global $180 (ref null $180) (ref.null none)) + ;; CHECK: (global $181 (ref null $181) (ref.null none)) + (global $181 (ref null $181) (ref.null none)) + ;; CHECK: (global $182 (ref null $182) (ref.null none)) + (global $182 (ref null $182) (ref.null none)) + ;; CHECK: (global $183 (ref null $183) (ref.null none)) + (global $183 (ref null $183) (ref.null none)) + ;; CHECK: (global $184 (ref null $184) (ref.null none)) + (global $184 (ref null $184) (ref.null none)) + ;; CHECK: (global $185 (ref null $185) (ref.null none)) + (global $185 (ref null $185) (ref.null none)) + ;; CHECK: (global $186 (ref null $186) (ref.null none)) + (global $186 (ref null $186) (ref.null none)) + ;; CHECK: (global $187 (ref null $187) (ref.null none)) + (global $187 (ref null $187) (ref.null none)) + ;; CHECK: (global $188 (ref null $188) (ref.null none)) + (global $188 (ref null $188) (ref.null none)) + ;; CHECK: (global $189 (ref null $189) (ref.null none)) + (global $189 (ref null $189) (ref.null none)) + ;; CHECK: (global $190 (ref null $190) (ref.null none)) + (global $190 (ref null $190) (ref.null none)) + ;; CHECK: (global $191 (ref null $191) (ref.null none)) + (global $191 (ref null $191) (ref.null none)) + ;; CHECK: (global $192 (ref null $192) (ref.null none)) + (global $192 (ref null $192) (ref.null none)) + ;; CHECK: (global $193 (ref null $193) (ref.null none)) + (global $193 (ref null $193) (ref.null none)) + ;; CHECK: (global $194 (ref null $194) (ref.null none)) + (global $194 (ref null $194) (ref.null none)) + ;; CHECK: (global $195 (ref null $195) (ref.null none)) + (global $195 (ref null $195) (ref.null none)) + ;; CHECK: (global $196 (ref null $196) (ref.null none)) + (global $196 (ref null $196) (ref.null none)) + ;; CHECK: (global $197 (ref null $197) (ref.null none)) + (global $197 (ref null $197) (ref.null none)) + ;; CHECK: (global $198 (ref null $198) (ref.null none)) + (global $198 (ref null $198) (ref.null none)) + ;; CHECK: (global $199 (ref null $199) (ref.null none)) + (global $199 (ref null $199) (ref.null none)) +) diff --git a/test/lit/passes/minimize-rec-groups.wast b/test/lit/passes/minimize-rec-groups.wast new file mode 100644 index 00000000000..b1c1b1467cb --- /dev/null +++ b/test/lit/passes/minimize-rec-groups.wast @@ -0,0 +1,486 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: foreach %s %t wasm-opt -all --minimize-rec-groups -S -o - | filecheck %s + +;; A module with no heap types at all should be ok. +(module + ;; CHECK: (global $g i32 (i32.const 0)) + (global $g i32 (i32.const 0)) +) + +;; A module with a single heap type should be ok. +(module + ;; CHECK: (type $t (struct)) + (type $t (struct)) + ;; CHECK: (global $g (ref null $t) (ref.null none)) + (global $g (ref null $t) (ref.null none)) +) + +;; Split a rec group containing independent types +(module + (rec + ;; CHECK: (type $a (struct (field i32))) + (type $a (struct (field i32))) + ;; CHECK: (type $b (struct (field i64))) + (type $b (struct (field i64))) + ;; CHECK: (type $c (struct (field f32))) + (type $c (struct (field f32))) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) +) + +;; Split a rec group containing types that depend on each other but belong to +;; different SCCs. +(module + (rec + ;; CHECK: (type $a (struct)) + (type $a (struct)) + ;; CHECK: (type $b (struct (field (ref $a)))) + (type $b (struct (field (ref $a)))) + ;; CHECK: (type $c (struct (field (ref $b)))) + (type $c (struct (field (ref $b)))) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) +) + +;; Reverse the order of the previous case. The output should still be in a valid +;; order. +(module + (rec + ;; CHECK: (type $a (struct)) + + ;; CHECK: (type $b (struct (field (ref $a)))) + + ;; CHECK: (type $c (struct (field (ref $b)))) + (type $c (struct (field (ref $b)))) + (type $b (struct (field (ref $a)))) + (type $a (struct)) + ) + + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) +) + +;; Now all the types are in the same SCC. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $c (struct (field (ref $a)))) + + ;; CHECK: (type $b (struct (field (ref $c)))) + + ;; CHECK: (type $a (struct (field (ref $b)))) + (type $a (struct (field (ref $b)))) + (type $b (struct (field (ref $c)))) + (type $c (struct (field (ref $a)))) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) +) + +;; Only two of the types are in the same SCC. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $b (struct (field (ref $a)))) + + ;; CHECK: (type $a (struct (field (ref $b)))) + (type $a (struct (field (ref $b)))) + (type $b (struct (field (ref $a)))) + ;; CHECK: (type $c (struct (field (ref $a)))) + (type $c (struct (field (ref $a)))) + ) + + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) +) + +;; Same, but change which two are in the SCC. The output order should still be +;; valid. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $c (struct (field (ref $b)))) + + ;; CHECK: (type $b (struct (field (ref $c)))) + + ;; CHECK: (type $a (struct (field (ref $b)))) + (type $a (struct (field (ref $b)))) + (type $b (struct (field (ref $c)))) + (type $c (struct (field (ref $b)))) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) +) + +;; Two types that are in conflicting SCCs should be disambiguated. In this case +;; there are no different permutations, so we use a brand. +(module + (rec + ;; CHECK: (type $a (func)) + (type $a (func)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $1 (struct)) + + ;; CHECK: (type $b (func)) + (type $b (func)) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null nofunc)) + (global $a (ref null $a) (ref.null nofunc)) + ;; CHECK: (global $b (ref null $b) (ref.null nofunc)) + (global $b (ref null $b) (ref.null nofunc)) +) + +;; Same as above, but now the types match the initial brand, so we have to skip +;; to the next one. +(module + (rec + ;; CHECK: (type $a (struct)) + (type $a (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $1 (array (mut i8))) + + ;; CHECK: (type $b (struct)) + (type $b (struct)) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) +) + +;; Now we have groups that match both the initial brand and the next one, so +;; adding the brand will cause a conflict. We will have to go to the next brand. +(module + (rec + ;; CHECK: (type $a1 (struct)) + (type $a1 (struct)) + ;; CHECK: (type $b1 (array (mut i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (array (mut i8))) + + ;; CHECK: (type $a2 (struct)) + (type $a2 (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a3 (struct)) + (type $a3 (struct)) + (type $b1 (array (mut i8))) + ;; CHECK: (type $5 (array (mut i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $6 (array i8)) + + ;; CHECK: (type $b2 (array (mut i8))) + (type $b2 (array (mut i8))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) + ;; CHECK: (global $a3 (ref null $a3) (ref.null none)) + (global $a3 (ref null $a3) (ref.null none)) + ;; CHECK: (global $b1 (ref null $b1) (ref.null none)) + (global $b1 (ref null $b1) (ref.null none)) + ;; CHECK: (global $b2 (ref null $b2) (ref.null none)) + (global $b2 (ref null $b2) (ref.null none)) +) + +;; Now the types have more fields, including one referring to a previous SCC. +(module + (rec + ;; CHECK: (type $other (struct (field i32))) + (type $other (struct (field i32))) + ;; CHECK: (type $a (struct (field anyref) (field i32) (field (ref $other)))) + (type $a (struct (field anyref i32 (ref $other)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (struct)) + + ;; CHECK: (type $b (struct (field anyref) (field i32) (field (ref $other)))) + (type $b (struct (field anyref i32 (ref $other)))) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) +) + +;; Now there is a third type and we can disambiguate it by using a different +;; permutation with the same brand. +(module + (rec + ;; CHECK: (type $a (struct)) + (type $a (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $1 (array (mut i8))) + + ;; CHECK: (type $b (struct)) + (type $b (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $c (struct)) + (type $c (struct)) + ) + + ;; CHECK: (type $4 (array (mut i8))) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) +) + +;; Adding a fourth type requires using yet another brand. +(module + (rec + ;; CHECK: (type $a (struct)) + (type $a (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $1 (array (mut i8))) + + ;; CHECK: (type $b (struct)) + (type $b (struct)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $c (struct)) + (type $c (struct)) + ;; CHECK: (type $4 (array (mut i8))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $5 (array i8)) + + ;; CHECK: (type $d (struct)) + (type $d (struct)) + ) + + ;; CHECK: (global $a (ref null $a) (ref.null none)) + (global $a (ref null $a) (ref.null none)) + ;; CHECK: (global $b (ref null $b) (ref.null none)) + (global $b (ref null $b) (ref.null none)) + ;; CHECK: (global $c (ref null $c) (ref.null none)) + (global $c (ref null $c) (ref.null none)) + ;; CHECK: (global $d (ref null $d) (ref.null none)) + (global $d (ref null $d) (ref.null none)) +) + +;; After $a1 and $a2 are dismabiguated with a brand, $b1 and $b2 require no +;; further disambiguation. +(module + (rec + ;; CHECK: (type $a1 (struct)) + (type $a1 (struct)) + ;; CHECK: (type $b1 (struct (field (ref $a1)))) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (array (mut i8))) + + ;; CHECK: (type $a2 (struct)) + (type $a2 (struct)) + (type $b1 (struct (field (ref $a1)))) + ;; CHECK: (type $b2 (struct (field (ref $a2)))) + (type $b2 (struct (field (ref $a2)))) + ) + + ;; CHECK: (global $b1 (ref null $b1) (ref.null none)) + (global $b1 (ref null $b1) (ref.null none)) + ;; CHECK: (global $b2 (ref null $b2) (ref.null none)) + (global $b2 (ref null $b2) (ref.null none)) +) + +;; Now we can disambiguate by permuting without a brand. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $b1 (struct (field (ref $a1)))) + + ;; CHECK: (type $a1 (struct (field (ref $b1)) (field i32))) + (type $a1 (struct (field (ref $b1) i32))) + (type $b1 (struct (field (ref $a1)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a2 (struct (field (ref $b2)) (field i32))) + (type $a2 (struct (field (ref $b2) i32))) + ;; CHECK: (type $b2 (struct (field (ref $a2)))) + (type $b2 (struct (field (ref $a2)))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) +) + +;; But when we run out of permutations, we need a brand again. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $b1 (struct (field (ref $a1)))) + + ;; CHECK: (type $a1 (struct (field (ref $b1)) (field i32))) + (type $a1 (struct (field (ref $b1) i32))) + (type $b1 (struct (field (ref $a1)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a2 (struct (field (ref $b2)) (field i32))) + (type $a2 (struct (field (ref $b2) i32))) + ;; CHECK: (type $b2 (struct (field (ref $a2)))) + (type $b2 (struct (field (ref $a2)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $4 (struct)) + + ;; CHECK: (type $b3 (struct (field (ref $a3)))) + + ;; CHECK: (type $a3 (struct (field (ref $b3)) (field i32))) + (type $a3 (struct (field (ref $b3) i32))) + (type $b3 (struct (field (ref $a3)))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) + ;; CHECK: (global $a3 (ref null $a3) (ref.null none)) + (global $a3 (ref null $a3) (ref.null none)) +) + +;; Same as above, except the middle global now refers to $b2 instead of $a2, +;; changing the initial order of types in the middle SCC. We arrive at the same +;; result by a different path. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $b1 (struct (field (ref $a1)))) + + ;; CHECK: (type $a1 (struct (field (ref $b1)) (field i32))) + (type $a1 (struct (field (ref $b1) i32))) + (type $b1 (struct (field (ref $a1)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a2 (struct (field (ref $b2)) (field i32))) + (type $a2 (struct (field (ref $b2) i32))) + ;; CHECK: (type $b2 (struct (field (ref $a2)))) + (type $b2 (struct (field (ref $a2)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $4 (struct)) + + ;; CHECK: (type $b3 (struct (field (ref $a3)))) + + ;; CHECK: (type $a3 (struct (field (ref $b3)) (field i32))) + (type $a3 (struct (field (ref $b3) i32))) + (type $b3 (struct (field (ref $a3)))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $b2 (ref null $b2) (ref.null none)) + (global $b2 (ref null $b2) (ref.null none)) + ;; CHECK: (global $a3 (ref null $a3) (ref.null none)) + (global $a3 (ref null $a3) (ref.null none)) +) + +;; Now we can't differentiate by permutation because of automorphisms. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $b1 (struct (field (ref $a1)))) + + ;; CHECK: (type $a1 (struct (field (ref $b1)))) + (type $a1 (struct (field (ref $b1)))) + (type $b1 (struct (field (ref $a1)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (struct)) + + ;; CHECK: (type $b2 (struct (field (ref $a2)))) + + ;; CHECK: (type $a2 (struct (field (ref $b2)))) + (type $a2 (struct (field (ref $b2)))) + (type $b2 (struct (field (ref $a2)))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) +) + +;; Now we can't differentiate by permutation because the subtyping constraint +;; admits only one ordering. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a1 (sub (struct (field (ref $b1))))) + (type $a1 (sub (struct (field (ref $b1))))) + ;; CHECK: (type $b1 (sub $a1 (struct (field (ref $b1))))) + (type $b1 (sub $a1 (struct (field (ref $b1))))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $2 (struct)) + + ;; CHECK: (type $a2 (sub (struct (field (ref $b2))))) + (type $a2 (sub (struct (field (ref $b2))))) + ;; CHECK: (type $b2 (sub $a2 (struct (field (ref $b2))))) + (type $b2 (sub $a2 (struct (field (ref $b2))))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) +) + + +;; Now there are only two possible orderings admitted by the subtyping +;; constraint. +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a1 (sub (struct (field (ref $b1))))) + (type $a1 (sub (struct (field (ref $b1))))) + ;; CHECK: (type $c1 (sub $a1 (struct (field (ref $b1))))) + + ;; CHECK: (type $b1 (sub $a1 (struct (field (ref $b1)) (field (ref $c1))))) + (type $b1 (sub $a1 (struct (field (ref $b1)) (ref $c1)))) + (type $c1 (sub $a1 (struct (field (ref $b1))))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $a2 (sub (struct (field (ref $b2))))) + (type $a2 (sub (struct (field (ref $b2))))) + ;; CHECK: (type $b2 (sub $a2 (struct (field (ref $b2)) (field (ref $c2))))) + (type $b2 (sub $a2 (struct (field (ref $b2)) (ref $c2)))) + ;; CHECK: (type $c2 (sub $a2 (struct (field (ref $b2))))) + (type $c2 (sub $a2 (struct (field (ref $b2))))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $6 (struct)) + + ;; CHECK: (type $a3 (sub (struct (field (ref $b3))))) + (type $a3 (sub (struct (field (ref $b3))))) + ;; CHECK: (type $c3 (sub $a3 (struct (field (ref $b3))))) + + ;; CHECK: (type $b3 (sub $a3 (struct (field (ref $b3)) (field (ref $c3))))) + (type $b3 (sub $a3 (struct (field (ref $b3)) (ref $c3)))) + (type $c3 (sub $a3 (struct (field (ref $b3))))) + ) + + ;; CHECK: (global $a1 (ref null $a1) (ref.null none)) + (global $a1 (ref null $a1) (ref.null none)) + ;; CHECK: (global $a2 (ref null $a2) (ref.null none)) + (global $a2 (ref null $a2) (ref.null none)) + ;; CHECK: (global $a3 (ref null $a3) (ref.null none)) + (global $a3 (ref null $a3) (ref.null none)) +) From 0b05a3ebc7feedfd28f54b6486cf3f2ec1864edb Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 19 Aug 2024 09:23:55 -0700 Subject: [PATCH 527/553] [NFC] Use HeapType::getKind more broadly (#6846) Replace code that checked `isStruct()`, `isArray()`, etc. in sequence with uses of `HeapType::getKind()` and switch statements. This will make it easier to find the code that needs updating if/when we add new heap type kinds in the future. It also makes it much easier to find code that already needs updating to handle continuation types by grepping for "TODO: cont". --- src/ir/gc-type-utils.h | 13 ++- src/ir/subtypes.h | 21 ++-- src/passes/TypeMerging.cpp | 51 ++++++---- src/passes/TypeSSA.cpp | 17 ++-- src/passes/Unsubtyping.cpp | 38 +++++--- src/tools/fuzzing/fuzzing.cpp | 119 +++++++++++++---------- src/tools/fuzzing/heap-types.cpp | 132 ++++++++++++++----------- src/tools/wasm-fuzz-types.cpp | 23 +++-- src/wasm/wasm-binary.cpp | 51 +++++----- src/wasm/wasm-type.cpp | 161 +++++++++++++++++-------------- 10 files changed, 363 insertions(+), 263 deletions(-) diff --git a/src/ir/gc-type-utils.h b/src/ir/gc-type-utils.h index 7c530e1790a..6ac6db3ba06 100644 --- a/src/ir/gc-type-utils.h +++ b/src/ir/gc-type-utils.h @@ -149,10 +149,15 @@ inline EvaluationResult evaluateCastCheck(Type refType, Type castType) { // // TODO: use in more places inline std::optional getField(HeapType type, Index index = 0) { - if (type.isStruct()) { - return type.getStruct().fields[index]; - } else if (type.isArray()) { - return type.getArray().element; + switch (type.getKind()) { + case HeapTypeKind::Struct: + return type.getStruct().fields[index]; + case HeapTypeKind::Array: + return type.getArray().element; + case HeapTypeKind::Func: + case HeapTypeKind::Cont: + case HeapTypeKind::Basic: + break; } return {}; } diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h index 767c79fd7ca..20377205586 100644 --- a/src/ir/subtypes.h +++ b/src/ir/subtypes.h @@ -125,13 +125,20 @@ struct SubTypes { for (auto type : types) { HeapType basic; auto share = type.getShared(); - if (type.isStruct()) { - basic = HeapTypes::struct_.getBasic(share); - } else if (type.isArray()) { - basic = HeapTypes::array.getBasic(share); - } else { - assert(type.isSignature()); - basic = HeapTypes::func.getBasic(share); + switch (type.getKind()) { + case HeapTypeKind::Func: + basic = HeapTypes::func.getBasic(share); + break; + case HeapTypeKind::Struct: + basic = HeapTypes::struct_.getBasic(share); + break; + case HeapTypeKind::Array: + basic = HeapTypes::array.getBasic(share); + break; + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } auto& basicDepth = depths[basic]; basicDepth = std::max(basicDepth, depths[type] + 1); diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index e5ac7888bdd..1cac7732f4e 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -544,14 +544,22 @@ bool shapeEq(HeapType a, HeapType b) { if (a.isShared() != b.isShared()) { return false; } - if (a.isStruct() && b.isStruct()) { - return shapeEq(a.getStruct(), b.getStruct()); - } - if (a.isArray() && b.isArray()) { - return shapeEq(a.getArray(), b.getArray()); + auto aKind = a.getKind(); + auto bKind = b.getKind(); + if (aKind != bKind) { + return false; } - if (a.isSignature() && b.isSignature()) { - return shapeEq(a.getSignature(), b.getSignature()); + switch (aKind) { + case HeapTypeKind::Func: + return shapeEq(a.getSignature(), b.getSignature()); + case HeapTypeKind::Struct: + return shapeEq(a.getStruct(), b.getStruct()); + case HeapTypeKind::Array: + return shapeEq(a.getArray(), b.getArray()); + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } return false; } @@ -559,19 +567,24 @@ bool shapeEq(HeapType a, HeapType b) { size_t shapeHash(HeapType a) { size_t digest = hash(a.isOpen()); rehash(digest, a.isShared()); - if (a.isStruct()) { - rehash(digest, 0); - hash_combine(digest, shapeHash(a.getStruct())); - } else if (a.isArray()) { - rehash(digest, 1); - hash_combine(digest, shapeHash(a.getArray())); - } else if (a.isSignature()) { - rehash(digest, 2); - hash_combine(digest, shapeHash(a.getSignature())); - } else { - WASM_UNREACHABLE("unexpected kind"); + auto kind = a.getKind(); + rehash(digest, kind); + switch (kind) { + case HeapTypeKind::Func: + hash_combine(digest, shapeHash(a.getSignature())); + return digest; + case HeapTypeKind::Struct: + hash_combine(digest, shapeHash(a.getStruct())); + return digest; + case HeapTypeKind::Array: + hash_combine(digest, shapeHash(a.getArray())); + return digest; + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + break; } - return digest; + WASM_UNREACHABLE("unexpected kind"); } bool shapeEq(const Struct& a, const Struct& b) { diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 1355b113e03..8ba6c10c490 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -237,12 +237,17 @@ struct TypeSSA : public Pass { for (Index i = 0; i < num; i++) { auto* curr = newsToModify[i]; auto oldType = curr->type.getHeapType(); - if (oldType.isStruct()) { - builder[i] = oldType.getStruct(); - } else if (oldType.isArray()) { - builder[i] = oldType.getArray(); - } else { - WASM_UNREACHABLE("unexpected type kind"); + switch (oldType.getKind()) { + case HeapTypeKind::Struct: + builder[i] = oldType.getStruct(); + break; + case HeapTypeKind::Array: + builder[i] = oldType.getArray(); + break; + case HeapTypeKind::Func: + case HeapTypeKind::Cont: + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } builder[i].subTypeOf(oldType); builder[i].setShared(oldType.getShared()); diff --git a/src/passes/Unsubtyping.cpp b/src/passes/Unsubtyping.cpp index ccad4ed3d2f..8d76f348a5a 100644 --- a/src/passes/Unsubtyping.cpp +++ b/src/passes/Unsubtyping.cpp @@ -264,21 +264,31 @@ struct Unsubtyping if (super.isBasic()) { continue; } - if (type.isStruct()) { - const auto& fields = type.getStruct().fields; - const auto& superFields = super.getStruct().fields; - for (size_t i = 0, size = superFields.size(); i < size; ++i) { - noteSubtype(fields[i].type, superFields[i].type); + switch (type.getKind()) { + case HeapTypeKind::Func: { + auto sig = type.getSignature(); + auto superSig = super.getSignature(); + noteSubtype(superSig.params, sig.params); + noteSubtype(sig.results, superSig.results); + break; } - } else if (type.isArray()) { - auto elem = type.getArray().element; - noteSubtype(elem.type, super.getArray().element.type); - } else { - assert(type.isSignature()); - auto sig = type.getSignature(); - auto superSig = super.getSignature(); - noteSubtype(superSig.params, sig.params); - noteSubtype(sig.results, superSig.results); + case HeapTypeKind::Struct: { + const auto& fields = type.getStruct().fields; + const auto& superFields = super.getStruct().fields; + for (size_t i = 0, size = superFields.size(); i < size; ++i) { + noteSubtype(fields[i].type, superFields[i].type); + } + break; + } + case HeapTypeKind::Array: { + auto elem = type.getArray().element; + noteSubtype(elem.type, super.getArray().element.type); + break; + } + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 64780696b8f..bebf4f9892c 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -291,28 +291,35 @@ void TranslateToFuzzReader::setupHeapTypes() { auto eq = HeapTypes::eq.getBasic(share); auto any = HeapTypes::any.getBasic(share); auto func = HeapTypes::func.getBasic(share); - if (type.isStruct()) { - interestingHeapSubTypes[struct_].push_back(type); - interestingHeapSubTypes[eq].push_back(type); - interestingHeapSubTypes[any].push_back(type); - - // Note the mutable fields. - auto& fields = type.getStruct().fields; - for (Index i = 0; i < fields.size(); i++) { - if (fields[i].mutable_) { - mutableStructFields.push_back(StructField{type, i}); + switch (type.getKind()) { + case HeapTypeKind::Func: + interestingHeapSubTypes[func].push_back(type); + break; + case HeapTypeKind::Struct: { + interestingHeapSubTypes[struct_].push_back(type); + interestingHeapSubTypes[eq].push_back(type); + interestingHeapSubTypes[any].push_back(type); + // Note the mutable fields. + auto& fields = type.getStruct().fields; + for (Index i = 0; i < fields.size(); i++) { + if (fields[i].mutable_) { + mutableStructFields.push_back(StructField{type, i}); + } } + break; } - } else if (type.isArray()) { - interestingHeapSubTypes[array].push_back(type); - interestingHeapSubTypes[eq].push_back(type); - interestingHeapSubTypes[any].push_back(type); - - if (type.getArray().element.mutable_) { - mutableArrays.push_back(type); - } - } else if (type.isSignature()) { - interestingHeapSubTypes[func].push_back(type); + case HeapTypeKind::Array: + interestingHeapSubTypes[array].push_back(type); + interestingHeapSubTypes[eq].push_back(type); + interestingHeapSubTypes[any].push_back(type); + if (type.getArray().element.mutable_) { + mutableArrays.push_back(type); + } + break; + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } @@ -2757,43 +2764,49 @@ Expression* TranslateToFuzzReader::makeCompoundRef(Type type) { return funcContext ? make(type) : makeTrivial(type); }; - if (heapType.isSignature()) { - return makeRefFuncConst(type); - } else if (type.isStruct()) { - auto& fields = heapType.getStruct().fields; - std::vector values; - // If there is a nondefaultable field, we must provide the value and not - // depend on defaults. Also do that randomly half the time. - if (std::any_of( - fields.begin(), - fields.end(), - [&](const Field& field) { return !field.type.isDefaultable(); }) || - oneIn(2)) { - for (auto& field : fields) { - values.push_back(makeChild(field.type)); - } - // Add more nesting manually, as we can easily get exponential blowup - // here. This nesting makes it much less likely for a recursive data - // structure to end up as a massive tree of struct.news, since the nesting - // limitation code at the top of this function will kick in. - if (!values.empty()) { - // Subtract 1 since if there is a single value there cannot be - // exponential blowup. - nester.add(values.size() - 1); + switch (heapType.getKind()) { + case HeapTypeKind::Func: + return makeRefFuncConst(type); + case HeapTypeKind::Struct: { + auto& fields = heapType.getStruct().fields; + std::vector values; + // If there is a nondefaultable field, we must provide the value and not + // depend on defaults. Also do that randomly half the time. + if (std::any_of( + fields.begin(), + fields.end(), + [&](const Field& field) { return !field.type.isDefaultable(); }) || + oneIn(2)) { + for (auto& field : fields) { + values.push_back(makeChild(field.type)); + } + // Add more nesting manually, as we can easily get exponential blowup + // here. This nesting makes it much less likely for a recursive data + // structure to end up as a massive tree of struct.news, since the + // nesting limitation code at the top of this function will kick in. + if (!values.empty()) { + // Subtract 1 since if there is a single value there cannot be + // exponential blowup. + nester.add(values.size() - 1); + } } + return builder.makeStructNew(heapType, values); } - return builder.makeStructNew(heapType, values); - } else if (type.isArray()) { - auto element = heapType.getArray().element; - Expression* init = nullptr; - if (!element.type.isDefaultable() || oneIn(2)) { - init = makeChild(element.type); + case HeapTypeKind::Array: { + auto element = heapType.getArray().element; + Expression* init = nullptr; + if (!element.type.isDefaultable() || oneIn(2)) { + init = makeChild(element.type); + } + auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE))); + return builder.makeArrayNew(type.getHeapType(), count, init); } - auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE))); - return builder.makeArrayNew(type.getHeapType(), count, init); - } else { - WASM_UNREACHABLE("bad user-defined ref type"); + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + break; } + WASM_UNREACHABLE("unexpected kind"); } Expression* TranslateToFuzzReader::makeStringNewArray() { diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index e4d54ae07b8..b4833475a2c 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -131,14 +131,20 @@ struct HeapTypeGeneratorImpl { } else { // We have a supertype, so create a subtype. HeapType supertype = builder[*supertypeIndices[index]]; - if (supertype.isSignature()) { - builder[index] = generateSubSignature(supertype.getSignature()); - } else if (supertype.isStruct()) { - builder[index] = generateSubStruct(supertype.getStruct(), share); - } else if (supertype.isArray()) { - builder[index] = generateSubArray(supertype.getArray()); - } else { - WASM_UNREACHABLE("unexpected kind"); + switch (supertype.getKind()) { + case wasm::HeapTypeKind::Func: + builder[index] = generateSubSignature(supertype.getSignature()); + break; + case wasm::HeapTypeKind::Struct: + builder[index] = generateSubStruct(supertype.getStruct(), share); + break; + case wasm::HeapTypeKind::Array: + builder[index] = generateSubArray(supertype.getArray()); + break; + case wasm::HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case wasm::HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } } @@ -879,38 +885,44 @@ std::vector Inhabitator::build() { for (size_t i = 0; i < types.size(); ++i) { auto type = types[i]; - if (type.isStruct()) { - Struct copy = type.getStruct(); - for (size_t j = 0; j < copy.fields.size(); ++j) { - updateType({type, j}, copy.fields[j].type); + switch (type.getKind()) { + case HeapTypeKind::Func: { + auto sig = type.getSignature(); + size_t j = 0; + std::vector params; + for (auto param : sig.params) { + params.push_back(param); + updateType({type, j++}, params.back()); + } + std::vector results; + for (auto result : sig.results) { + results.push_back(result); + updateType({type, j++}, results.back()); + } + builder[i] = Signature(builder.getTempTupleType(params), + builder.getTempTupleType(results)); + continue; } - builder[i] = copy; - continue; - } - if (type.isArray()) { - Array copy = type.getArray(); - updateType({type, 0}, copy.element.type); - builder[i] = copy; - continue; - } - if (type.isSignature()) { - auto sig = type.getSignature(); - size_t j = 0; - std::vector params; - for (auto param : sig.params) { - params.push_back(param); - updateType({type, j++}, params.back()); + case HeapTypeKind::Struct: { + Struct copy = type.getStruct(); + for (size_t j = 0; j < copy.fields.size(); ++j) { + updateType({type, j}, copy.fields[j].type); + } + builder[i] = copy; + continue; } - std::vector results; - for (auto result : sig.results) { - results.push_back(result); - updateType({type, j++}, results.back()); + case HeapTypeKind::Array: { + Array copy = type.getArray(); + updateType({type, 0}, copy.element.type); + builder[i] = copy; + continue; } - builder[i] = Signature(builder.getTempTupleType(params), - builder.getTempTupleType(results)); - continue; + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + break; } - WASM_UNREACHABLE("unexpected type kind"); + WASM_UNREACHABLE("unexpected kind"); } // Establish rec groups. @@ -994,35 +1006,43 @@ bool isUninhabitable(Type type, bool isUninhabitable(HeapType type, std::unordered_set& visited, std::unordered_set& visiting) { - if (type.isBasic()) { - return false; - } - if (type.isSignature()) { - // Function types are always inhabitable. - return false; + switch (type.getKind()) { + case HeapTypeKind::Basic: + return false; + case HeapTypeKind::Func: + case HeapTypeKind::Cont: + // Function types are always inhabitable. + return false; + case HeapTypeKind::Struct: + case HeapTypeKind::Array: + break; } if (visited.count(type)) { return false; } - - if (!visiting.insert(type).second) { + auto [it, inserted] = visiting.insert(type); + if (!inserted) { return true; } - - if (type.isStruct()) { - for (auto& field : type.getStruct().fields) { - if (isUninhabitable(field.type, visited, visiting)) { + switch (type.getKind()) { + case HeapTypeKind::Struct: + for (auto& field : type.getStruct().fields) { + if (isUninhabitable(field.type, visited, visiting)) { + return true; + } + } + break; + case HeapTypeKind::Array: + if (isUninhabitable(type.getArray().element.type, visited, visiting)) { return true; } - } - } else if (type.isArray()) { - if (isUninhabitable(type.getArray().element.type, visited, visiting)) { - return true; - } - } else { - WASM_UNREACHABLE("unexpected type kind"); + break; + case HeapTypeKind::Basic: + case HeapTypeKind::Func: + case HeapTypeKind::Cont: + WASM_UNREACHABLE("unexpected kind"); } - visiting.erase(type); + visiting.erase(it); visited.insert(type); return false; } diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp index 074d235c90f..7ba341e09df 100644 --- a/src/tools/wasm-fuzz-types.cpp +++ b/src/tools/wasm-fuzz-types.cpp @@ -297,15 +297,22 @@ void Fuzzer::checkCanonicalization() { // Copy the original types for (; index < types.size(); ++index) { auto type = types[index]; - if (type.isSignature()) { - builder[index] = getSignature(type.getSignature()); - } else if (type.isStruct()) { - builder[index] = getStruct(type.getStruct()); - } else if (type.isArray()) { - builder[index] = getArray(type.getArray()); - } else { - WASM_UNREACHABLE("unexpected type kind"); + switch (type.getKind()) { + case HeapTypeKind::Func: + builder[index] = getSignature(type.getSignature()); + continue; + case HeapTypeKind::Struct: + builder[index] = getStruct(type.getStruct()); + continue; + case HeapTypeKind::Array: + builder[index] = getArray(type.getArray()); + continue; + case HeapTypeKind::Cont: + WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Basic: + break; } + WASM_UNREACHABLE("unexpected type kind"); } } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 2abb32837a0..8565ddaadb1 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -291,30 +291,37 @@ void WasmBinaryWriter::writeTypes() { if (type.isShared()) { o << S32LEB(BinaryConsts::EncodedType::Shared); } - if (type.isSignature()) { - o << S32LEB(BinaryConsts::EncodedType::Func); - auto sig = type.getSignature(); - for (auto& sigType : {sig.params, sig.results}) { - o << U32LEB(sigType.size()); - for (const auto& type : sigType) { - writeType(type); + switch (type.getKind()) { + case HeapTypeKind::Func: { + o << S32LEB(BinaryConsts::EncodedType::Func); + auto sig = type.getSignature(); + for (auto& sigType : {sig.params, sig.results}) { + o << U32LEB(sigType.size()); + for (const auto& type : sigType) { + writeType(type); + } } + break; } - } else if (type.isContinuation()) { - o << S32LEB(BinaryConsts::EncodedType::Cont); - writeHeapType(type.getContinuation().type); - } else if (type.isStruct()) { - o << S32LEB(BinaryConsts::EncodedType::Struct); - auto fields = type.getStruct().fields; - o << U32LEB(fields.size()); - for (const auto& field : fields) { - writeField(field); - } - } else if (type.isArray()) { - o << S32LEB(BinaryConsts::EncodedType::Array); - writeField(type.getArray().element); - } else { - WASM_UNREACHABLE("TODO GC type writing"); + case HeapTypeKind::Struct: { + o << S32LEB(BinaryConsts::EncodedType::Struct); + auto fields = type.getStruct().fields; + o << U32LEB(fields.size()); + for (const auto& field : fields) { + writeField(field); + } + break; + } + case HeapTypeKind::Array: + o << S32LEB(BinaryConsts::EncodedType::Array); + writeField(type.getArray().element); + break; + case HeapTypeKind::Cont: + o << S32LEB(BinaryConsts::EncodedType::Cont); + writeHeapType(type.getContinuation().type); + break; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } } finishSection(start); diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 34299a9a1ef..84ae515214f 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1233,42 +1233,46 @@ size_t HeapType::getDepth() const { // In addition to the explicit supertypes we just traversed over, there is // implicit supertyping wrt basic types. A signature type always has one more // super, HeapType::func, etc. - if (!isBasic()) { - if (isFunction() || isContinuation()) { - depth++; - } else if (isStruct()) { + switch (getKind()) { + case HeapTypeKind::Basic: + // Some basic types have supers. + switch (getBasic(Unshared)) { + case HeapType::ext: + case HeapType::func: + case HeapType::cont: + case HeapType::any: + case HeapType::exn: + break; + case HeapType::eq: + depth++; + break; + case HeapType::i31: + case HeapType::struct_: + case HeapType::array: + case HeapType::string: + depth += 2; + break; + case HeapType::none: + case HeapType::nofunc: + case HeapType::nocont: + case HeapType::noext: + case HeapType::noexn: + // Bottom types are infinitely deep. + depth = size_t(-1l); + } + break; + case HeapTypeKind::Func: + case HeapTypeKind::Cont: + ++depth; + break; + case HeapTypeKind::Struct: // specific struct types <: struct <: eq <: any depth += 3; - } else if (isArray()) { + break; + case HeapTypeKind::Array: // specific array types <: array <: eq <: any depth += 3; - } - } else { - // Some basic types have supers. - switch (getBasic(Unshared)) { - case HeapType::ext: - case HeapType::func: - case HeapType::cont: - case HeapType::any: - case HeapType::exn: - break; - case HeapType::eq: - depth++; - break; - case HeapType::i31: - case HeapType::struct_: - case HeapType::array: - case HeapType::string: - depth += 2; - break; - case HeapType::none: - case HeapType::nofunc: - case HeapType::nocont: - case HeapType::noext: - case HeapType::noexn: - // Bottom types are infinitely deep. - depth = size_t(-1l); - } + break; } return depth; } @@ -1353,31 +1357,30 @@ bool HeapType::isSubType(HeapType left, HeapType right) { } std::vector HeapType::getTypeChildren() const { - if (isBasic()) { - return {}; - } - if (isStruct()) { - std::vector children; - for (auto& field : getStruct().fields) { - children.push_back(field.type); + switch (getKind()) { + case HeapTypeKind::Basic: + return {}; + case HeapTypeKind::Func: { + std::vector children; + auto sig = getSignature(); + for (auto tuple : {sig.params, sig.results}) { + for (auto t : tuple) { + children.push_back(t); + } + } + return children; } - return children; - } - if (isArray()) { - return {getArray().element.type}; - } - if (isSignature()) { - std::vector children; - auto sig = getSignature(); - for (auto tuple : {sig.params, sig.results}) { - for (auto t : tuple) { - children.push_back(t); + case HeapTypeKind::Struct: { + std::vector children; + for (auto& field : getStruct().fields) { + children.push_back(field.type); } + return children; } - return children; - } - if (isContinuation()) { - return {}; + case HeapTypeKind::Array: + return {getArray().element.type}; + case HeapTypeKind::Cont: + return {}; } WASM_UNREACHABLE("unexpected kind"); } @@ -1586,16 +1589,21 @@ TypeNames DefaultTypeNameGenerator::getNames(HeapType type) { if (inserted) { // Generate a new name for this type we have not previously seen. std::stringstream stream; - if (type.isSignature()) { - stream << "func." << funcCount++; - } else if (type.isContinuation()) { - stream << "cont." << contCount++; - } else if (type.isStruct()) { - stream << "struct." << structCount++; - } else if (type.isArray()) { - stream << "array." << arrayCount++; - } else { - WASM_UNREACHABLE("unexpected kind"); + switch (type.getKind()) { + case HeapTypeKind::Func: + stream << "func." << funcCount++; + break; + case HeapTypeKind::Struct: + stream << "struct." << structCount++; + break; + case HeapTypeKind::Array: + stream << "array." << arrayCount++; + break; + case HeapTypeKind::Cont: + stream << "cont." << contCount++; + break; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } it->second = {stream.str(), {}}; } @@ -1972,16 +1980,21 @@ std::ostream& TypePrinter::print(HeapType type) { if (type.isShared()) { os << "(shared "; } - if (type.isSignature()) { - print(type.getSignature()); - } else if (type.isContinuation()) { - print(type.getContinuation()); - } else if (type.isStruct()) { - print(type.getStruct(), names.fieldNames); - } else if (type.isArray()) { - print(type.getArray()); - } else { - WASM_UNREACHABLE("unexpected type"); + switch (type.getKind()) { + case HeapTypeKind::Func: + print(type.getSignature()); + break; + case HeapTypeKind::Struct: + print(type.getStruct(), names.fieldNames); + break; + case HeapTypeKind::Array: + print(type.getArray()); + break; + case HeapTypeKind::Cont: + print(type.getContinuation()); + break; + case HeapTypeKind::Basic: + WASM_UNREACHABLE("unexpected kind"); } if (type.isShared()) { os << ')'; From 127844ca1f6d182797e925b3d062c3484aaf5c23 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 19 Aug 2024 14:23:29 -0700 Subject: [PATCH 528/553] Print explicit typeuses for non-MVP function types (#6851) We previously printed explicit typeuses (e.g. `(type $f)`) in function signatures when GC was enabled. But even when GC is not enabled, function types may use non-MVP features that require the explicit typeuse to be printed. Fix the printer to always print the explicit type use for such types. Fixes #6850. --- src/passes/Print.cpp | 13 +++++- test/lit/basic/print-explicit-typeuse.wast | 51 ++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 test/lit/basic/print-explicit-typeuse.wast diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 3abe1f73821..6350347c46d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2804,13 +2804,21 @@ bool PrintSExpression::maybePrintUnreachableOrNullReplacement(Expression* curr, return maybePrintUnreachableReplacement(curr, type); } +static bool requiresExplicitFuncType(HeapType type) { + // When the `(type $f)` in a function's typeuse is omitted, the typeuse + // matches or declares an MVP function type. When the intended type is not an + // MVP function type, we therefore need the explicit `(type $f)`. + return type.isOpen() || type.isShared() || type.getRecGroup().size() > 1; +} + void PrintSExpression::handleSignature(HeapType curr, Name name) { Signature sig = curr.getSignature(); o << "(func"; if (name.is()) { o << ' '; name.print(o); - if (currModule && currModule->features.hasGC()) { + if ((currModule && currModule->features.hasGC()) || + requiresExplicitFuncType(curr)) { o << " (type "; printHeapType(curr) << ')'; } @@ -2947,7 +2955,8 @@ void PrintSExpression::visitDefinedFunction(Function* curr) { o << '('; printMajor(o, "func "); curr->name.print(o); - if (currModule && currModule->features.hasGC()) { + if ((currModule && currModule->features.hasGC()) || + requiresExplicitFuncType(curr->type)) { o << " (type "; printHeapType(curr->type) << ')'; } diff --git a/test/lit/basic/print-explicit-typeuse.wast b/test/lit/basic/print-explicit-typeuse.wast new file mode 100644 index 00000000000..d299a3eb430 --- /dev/null +++ b/test/lit/basic/print-explicit-typeuse.wast @@ -0,0 +1,51 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s --no-validation -S -o - | filecheck %s + +;; Check that we print explicit type uses for function signatures when the +;; function type uses non-MVP features, whether or not those features are +;; actually enabled. + +(module + ;; CHECK: (type $mvp (func)) + (type $mvp (func)) + ;; CHECK: (type $open (sub (func))) + (type $open (sub (func))) + ;; CHECK: (type $shared (shared (func))) + (type $shared (shared (func))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $rec (func)) + (type $rec (func)) + ;; CHECK: (type $other (struct)) + (type $other (struct)) + ) + + ;; CHECK: (import "" "" (func $mvp-import)) + (import "" "" (func $mvp-import)) + + ;; CHECK: (import "" "" (func $open-import (type $open))) + (import "" "" (func $open-import (type $open))) + + ;; CHECK: (import "" "" (func $shared-import (type $shared))) + (import "" "" (func $shared-import (type $shared))) + + ;; CHECK: (import "" "" (func $rec-import (type $rec))) + (import "" "" (func $rec-import (type $rec))) + + ;; CHECK: (func $mvp + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $mvp (type $mvp)) + ;; CHECK: (func $open (type $open) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $open (type $open)) + ;; CHECK: (func $shared (type $shared) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $shared (type $shared)) + ;; CHECK: (func $rec (type $rec) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $rec (type $rec)) +) From 2c9c74d8b64e1776c6c374af8631995b0be606f1 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 19 Aug 2024 16:07:11 -0700 Subject: [PATCH 529/553] Validate array.init_elem segment in IRBuilder (#6852) IRBuilder is responsible for validation involving type annotations on GC instructions because those type annotations may not be preserved in the built IR to be used by the main validator. For `array.init_elem`, we were not using the type annotation to validate the element segment, which allowed us to parse invalid modules when the reference operand was a nullref. Add the missing validation in IRBuilder and fix a relevant spec test. --- src/wasm/wasm-ir-builder.cpp | 10 ++++++++++ test/spec/shared-array.wast | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 2f2f3b595fe..b238a926c42 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1801,6 +1801,16 @@ Result<> IRBuilder::makeArrayInitData(HeapType type, Name data) { } Result<> IRBuilder::makeArrayInitElem(HeapType type, Name elem) { + // Validate the elem type, too, before we potentially forget the type + // annotation. + if (!type.isArray()) { + return Err{"expected array type annotation on array.init_elem"}; + } + if (!Type::isSubType(wasm.getElementSegment(elem)->type, + type.getArray().element.type)) { + return Err{"element segment type must be a subtype of array element type " + "on array.init_elem"}; + } ArrayInitElem curr; CHECK_ERR(ChildPopper{*this}.visitArrayInitElem(&curr, type)); CHECK_ERR(validateTypeAnnotation(type, curr.ref)); diff --git a/test/spec/shared-array.wast b/test/spec/shared-array.wast index 8c748fd20f0..f06fad2a756 100644 --- a/test/spec/shared-array.wast +++ b/test/spec/shared-array.wast @@ -122,7 +122,7 @@ (type $funcs (shared (array (mut (ref null (shared func)))))) (data) - (elem (ref null (shared any))) + (elem (ref null (shared func))) (func (array.get_s $i8 (ref.null (shared none)) (i32.const 0)) (drop)) (func (array.get_u $i8 (ref.null (shared none)) (i32.const 0)) (drop)) @@ -137,3 +137,13 @@ (func (array.init_data $i8 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) (func (array.init_elem $funcs 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) ) + +;; Check validation of element segments +(assert_invalid + (module + (type $array (shared (array (mut (ref null (shared any)))))) + (elem (ref null (shared func))) + (func (array.init_elem $array 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) + ) + "invalid field type" +) From 340ad71810484c279b1a36a9a7e458c9b18855b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 21 Aug 2024 00:43:25 +0200 Subject: [PATCH 530/553] [Exceptions] Finish interpreter + optimizer support for try_table. (#6814) * Add interpreter support for exnref values. * Fix optimization passes to support try_table. * Enable the interpreter (but not in V8, see code) on exceptions. --- scripts/fuzz_opt.py | 13 +- src/ir/ReFinalize.cpp | 7 +- src/ir/effects.h | 26 + src/ir/linear-execution.h | 6 + src/ir/possible-contents.cpp | 34 +- src/ir/possible-contents.h | 16 + src/literal.h | 19 + src/passes/CodeFolding.cpp | 21 +- src/passes/DeadCodeElimination.cpp | 6 + src/passes/SimplifyLocals.cpp | 6 +- src/passes/Vacuum.cpp | 11 +- src/wasm-interpreter.h | 70 ++- src/wasm-type.h | 2 + src/wasm/literal.cpp | 18 +- src/wasm/wasm-interpreter.cpp | 3 +- src/wasm/wasm-type.cpp | 2 + test/lit/basic/reference-types.wast | 228 ++++++++ test/lit/exec/eh-gc.wast | 27 + .../{eh-legacy-print.wast => eh-print.wast} | 0 test/lit/exec/eh.wast | 45 ++ test/lit/merge/renamings.wat | 48 ++ test/lit/merge/renamings.wat.second | 16 + .../lit/passes/coalesce-locals-eh-legacy.wast | 6 +- test/lit/passes/coalesce-locals-eh.wast | 84 +++ test/lit/passes/code-folding-eh-legacy.wast | 5 + test/lit/passes/code-folding-eh.wast | 296 ++++++++++ test/lit/passes/code-pushing-eh-legacy.wast | 139 ----- test/lit/passes/code-pushing-eh.wast | 300 +++++++++++ test/lit/passes/dce-eh-legacy.wast | 26 - test/lit/passes/dce-eh.wast | 145 +++++ test/lit/passes/global-effects-eh-legacy.wast | 507 ++++++++++++++++++ test/lit/passes/global-effects.wast | 157 +++--- test/lit/passes/gufa-eh.wast | 60 +++ test/lit/passes/local-subtyping.wast | 52 +- .../lit/passes/simplify-locals-eh-legacy.wast | 105 +--- test/lit/passes/simplify-locals-eh.wast | 226 ++++++++ test/lit/passes/vacuum-eh-legacy.wast | 3 +- test/lit/passes/vacuum-eh.wast | 235 ++++++++ test/spec/exception-handling.wast | 150 ++++++ test/spec/return_call_eh-legacy.wast | 35 ++ test/spec/return_call_eh.wast | 29 +- 41 files changed, 2764 insertions(+), 420 deletions(-) create mode 100644 test/lit/exec/eh-gc.wast rename test/lit/exec/{eh-legacy-print.wast => eh-print.wast} (100%) create mode 100644 test/lit/exec/eh.wast create mode 100644 test/lit/passes/coalesce-locals-eh.wast create mode 100644 test/lit/passes/code-folding-eh.wast create mode 100644 test/lit/passes/code-pushing-eh.wast create mode 100644 test/lit/passes/dce-eh.wast create mode 100644 test/lit/passes/global-effects-eh-legacy.wast create mode 100644 test/lit/passes/gufa-eh.wast create mode 100644 test/lit/passes/simplify-locals-eh.wast create mode 100644 test/lit/passes/vacuum-eh.wast create mode 100644 test/spec/return_call_eh-legacy.wast diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 28426f7734c..e06e13b72d8 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -352,10 +352,6 @@ def is_git_repo(): 'typed_continuations_contnew.wast', 'typed_continuations_contbind.wast', 'typed_continuations_suspend.wast', - # New EH implementation is in progress - 'exception-handling.wast', - 'translate-to-new-eh.wast', - 'rse-eh.wast', ] @@ -841,7 +837,9 @@ def can_run(self, wasm): # V8 does not support shared memories when running with # shared-everything enabled, so do not fuzz shared-everything # for now. - return all_disallowed(['shared-everything']) + # Due to the V8 bug https://issues.chromium.org/issues/332931390 + # we do not fuzz exception-handling either. + return all_disallowed(['shared-everything', 'exception-handling']) def can_compare_to_self(self): # With nans, VM differences can confuse us, so only very simple VMs @@ -1649,6 +1647,9 @@ def get_random_opts(): print('avoiding --flatten due to multivalue + reference types not supporting it (spilling of non-nullable tuples)') print('TODO: Resolving https://github.com/WebAssembly/binaryen/issues/4824 may fix this') continue + if '--enable-exception-handling' in FEATURE_OPTS: + print('avoiding --flatten due to exception-handling not supporting it (requires blocks with results)') + continue if '--gc' not in FEATURE_OPTS: print('avoiding --flatten due to GC not supporting it (spilling of non-nullable locals)') continue @@ -1707,7 +1708,7 @@ def get_random_opts(): # some features depend on other features, so if a required feature is # disabled, its dependent features need to be disabled as well. IMPLIED_FEATURE_OPTS = { - '--disable-reference-types': ['--disable-gc', '--disable-strings'], + '--disable-reference-types': ['--disable-gc', '--disable-exception-handling', '--disable-strings'], '--disable-gc': ['--disable-strings'], } diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 0f78d37b7e9..c32d6efbf4c 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -128,7 +128,12 @@ void ReFinalize::visitTableFill(TableFill* curr) { curr->finalize(); } void ReFinalize::visitTableCopy(TableCopy* curr) { curr->finalize(); } void ReFinalize::visitTableInit(TableInit* curr) { curr->finalize(); } void ReFinalize::visitTry(Try* curr) { curr->finalize(); } -void ReFinalize::visitTryTable(TryTable* curr) { curr->finalize(); } +void ReFinalize::visitTryTable(TryTable* curr) { + curr->finalize(); + for (size_t i = 0; i < curr->catchDests.size(); i++) { + updateBreakValueType(curr->catchDests[i], curr->sentTypes[i]); + } +} void ReFinalize::visitThrow(Throw* curr) { curr->finalize(); } void ReFinalize::visitRethrow(Rethrow* curr) { curr->finalize(); } void ReFinalize::visitThrowRef(ThrowRef* curr) { curr->finalize(); } diff --git a/src/ir/effects.h b/src/ir/effects.h index fee8b344174..716624d6455 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -431,6 +431,14 @@ class EffectAnalyzer { self->pushTask(doStartTry, currp); return; } + if (auto* tryTable = curr->dynCast()) { + // We need to increment try depth before starting. + self->pushTask(doEndTryTable, currp); + self->pushTask(doVisitTryTable, currp); + self->pushTask(scan, &tryTable->body); + self->pushTask(doStartTryTable, currp); + return; + } PostWalker>::scan( self, currp); } @@ -472,6 +480,24 @@ class EffectAnalyzer { self->parent.catchDepth--; } + static void doStartTryTable(InternalAnalyzer* self, Expression** currp) { + auto* curr = (*currp)->cast(); + // We only count 'try_table's with a 'catch_all' because instructions + // within a 'try_table' without a 'catch_all' can still throw outside of + // the try. + if (curr->hasCatchAll()) { + self->parent.tryDepth++; + } + } + + static void doEndTryTable(InternalAnalyzer* self, Expression** currp) { + auto* curr = (*currp)->cast(); + if (curr->hasCatchAll()) { + assert(self->parent.tryDepth > 0 && "try depth cannot be negative"); + self->parent.tryDepth--; + } + } + void visitBlock(Block* curr) { if (curr->name.is()) { parent.breakTargets.erase(curr->name); // these were internal breaks diff --git a/src/ir/linear-execution.h b/src/ir/linear-execution.h index c6593bd64c8..e8b1923aacf 100644 --- a/src/ir/linear-execution.h +++ b/src/ir/linear-execution.h @@ -171,6 +171,12 @@ struct LinearExecutionWalker : public PostWalker { self->pushTask(SubType::scan, &curr->cast()->body); break; } + case Expression::Id::TryTableId: { + self->pushTask(SubType::doVisitTryTable, currp); + self->pushTask(SubType::doNoteNonLinear, currp); + self->pushTask(SubType::scan, &curr->cast()->body); + break; + } case Expression::Id::ThrowId: { self->pushTask(SubType::doVisitThrow, currp); self->pushTask(SubType::doNoteNonLinear, currp); diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index e7454c7c6d5..e5e6cf659a7 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1135,8 +1135,38 @@ struct InfoCollector } } void visitTryTable(TryTable* curr) { - // TODO: optimize when possible - addRoot(curr); + receiveChildValue(curr->body, curr); + + // Connect caught tags with their branch targets, and materialize non-null + // exnref values. + auto numTags = curr->catchTags.size(); + for (Index tagIndex = 0; tagIndex < numTags; tagIndex++) { + auto tag = curr->catchTags[tagIndex]; + auto target = curr->catchDests[tagIndex]; + + Index exnrefIndex = 0; + if (tag.is()) { + auto params = getModule()->getTag(tag)->sig.params; + + for (Index i = 0; i < params.size(); i++) { + if (isRelevant(params[i])) { + info.links.push_back( + {TagLocation{tag, i}, + BreakTargetLocation{getFunction(), target, i}}); + } + } + + exnrefIndex = params.size(); + } + + if (curr->catchRefs[tagIndex]) { + auto location = CaughtExnRefLocation{}; + addRoot(location, + PossibleContents::fromType(Type(HeapType::exn, NonNullable))); + info.links.push_back( + {location, BreakTargetLocation{getFunction(), target, exnrefIndex}}); + } + } } void visitThrow(Throw* curr) { auto& operands = curr->operands; diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h index 5ec4f758f61..7b88483cf8c 100644 --- a/src/ir/possible-contents.h +++ b/src/ir/possible-contents.h @@ -473,6 +473,15 @@ struct TagLocation { } }; +// The location of an exnref materialized by a catch_ref or catch_all_ref clause +// of a try_table. No data is stored here. exnrefs contain a tag and a payload +// at run-time, as well as potential metadata such as stack traces, but we don't +// track that. So this is the same as NullLocation in a way: we just need *a* +// source of contents for places that receive an exnref. +struct CaughtExnRefLocation { + bool operator==(const CaughtExnRefLocation& other) const { return true; } +}; + // A null value. This is used as the location of the default value of a var in a // function, a null written to a struct field in struct.new_with_default, etc. struct NullLocation { @@ -520,6 +529,7 @@ using Location = std::variant; @@ -608,6 +618,12 @@ template<> struct hash { } }; +template<> struct hash { + size_t operator()(const wasm::CaughtExnRefLocation& loc) const { + return std::hash()("caught-exnref-location"); + } +}; + template<> struct hash { size_t operator()(const wasm::NullLocation& loc) const { return std::hash{}(loc.type); diff --git a/src/literal.h b/src/literal.h index d247b0c845a..dd6247d001c 100644 --- a/src/literal.h +++ b/src/literal.h @@ -32,6 +32,7 @@ namespace wasm { class Literals; struct GCData; +struct ExnData; class Literal { // store only integers, whose bits are deterministic. floats @@ -44,6 +45,7 @@ class Literal { int64_t i64; uint8_t v128[16]; // funcref function name. `isNull()` indicates a `null` value. + // TODO: handle cross-module calls using something other than a Name here. Name func; // A reference to GC data, either a Struct or an Array. For both of those we // store the referred data as a Literals object (which is natural for an @@ -56,6 +58,8 @@ class Literal { // reference as its sole value even though internal i31 references do not // have a gcData. std::shared_ptr gcData; + // A reference to Exn data. + std::shared_ptr exnData; }; public: @@ -85,6 +89,7 @@ class Literal { assert(type.isSignature()); } explicit Literal(std::shared_ptr gcData, HeapType type); + explicit Literal(std::shared_ptr exnData); explicit Literal(std::string_view string); Literal(const Literal& other); Literal& operator=(const Literal& other); @@ -96,6 +101,7 @@ class Literal { // Whether this is GC data, that is, something stored on the heap (aside from // a null or i31). This includes structs, arrays, and also strings. bool isData() const { return type.isData(); } + bool isExn() const { return type.isExn(); } bool isString() const { return type.isString(); } bool isNull() const { return type.isNull(); } @@ -303,6 +309,7 @@ class Literal { return func; } std::shared_ptr getGCData() const; + std::shared_ptr getExnData() const; // careful! int32_t* geti32Ptr() { @@ -742,6 +749,18 @@ struct GCData { GCData(HeapType type, Literals values) : type(type), values(values) {} }; +// The data of a (ref exn) literal. +struct ExnData { + // The tag of this exn data. + // TODO: handle cross-module calls using something other than a Name here. + Name tag; + + // The payload of this exn data. + Literals payload; + + ExnData(Name tag, Literals payload) : tag(tag), payload(payload) {} +}; + } // namespace wasm namespace std { diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp index dc2301f9c0c..2d17f6d3188 100644 --- a/src/passes/CodeFolding.cpp +++ b/src/passes/CodeFolding.cpp @@ -343,15 +343,18 @@ struct CodeFolding : public WalkerPass> { if (effects.danglingPop) { return false; } - // When an expression can throw and it is within a try scope, taking it - // out of the try scope changes the program's behavior, because the - // expression that would otherwise have been caught by the try now - // throws up to the next try scope or even up to the caller. We restrict - // the move if 'outOf' contains a 'try' anywhere in it. This is a - // conservative approximation because there can be cases that 'try' is - // within the expression that may throw so it is safe to take the - // expression out. - if (effects.throws() && !FindAll(outOf).list.empty()) { + // When an expression can throw and it is within a try/try_table scope, + // taking it out of the try/try_table scope changes the program's + // behavior, because the expression that would otherwise have been + // caught by the try/try_table now throws up to the next try/try_table + // scope or even up to the caller. We restrict the move if 'outOf' + // contains a 'try' or 'try_table' anywhere in it. This is a + // conservative approximation because there can be cases that + // 'try'/'try_table' is within the expression that may throw so it is + // safe to take the expression out. + // TODO: optimize this check to avoid two FindAlls. + if (effects.throws() && + (FindAll(outOf).has() || FindAll(outOf).has())) { return false; } } diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index 996133ad589..f8acde7b0fc 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -185,6 +185,12 @@ struct DeadCodeElimination tryy->body->type == Type::unreachable && allCatchesUnreachable) { typeUpdater.changeType(tryy, Type::unreachable); } + } else if (auto* tryTable = curr->dynCast()) { + // try_table can finish normally only if its body finishes normally. + if (tryTable->type != Type::unreachable && + tryTable->body->type == Type::unreachable) { + typeUpdater.changeType(tryTable, Type::unreachable); + } } else { WASM_UNREACHABLE("unimplemented DCE control flow structure"); } diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 28b13980b2a..eca503ad4c4 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -321,9 +321,9 @@ struct SimplifyLocals Expression** currp) { Expression* curr = *currp; - // Certain expressions cannot be sinked into 'try', and so at the start of - // 'try' we forget about them. - if (curr->is()) { + // Certain expressions cannot be sinked into 'try'/'try_table', and so at + // the start of 'try'/'try_table' we forget about them. + if (curr->is() || curr->is()) { std::vector invalidated; for (auto& [index, info] : self->sinkables) { // Expressions that may throw cannot be moved into a try (which might diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 4a4963291c9..0e49f19c89f 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -87,7 +87,7 @@ struct Vacuum : public WalkerPass> { // Some instructions have special handling in visit*, and we should do // nothing for them here. if (curr->is() || curr->is() || curr->is() || - curr->is() || curr->is()) { + curr->is() || curr->is() || curr->is()) { return curr; } // Check if this expression itself has side effects, ignoring children. @@ -435,6 +435,15 @@ struct Vacuum : public WalkerPass> { } } + void visitTryTable(TryTable* curr) { + // If try_table's body does not throw, the whole try_table can be replaced + // with the try_table's body. + if (!EffectAnalyzer(getPassOptions(), *getModule(), curr->body).throws()) { + replaceCurrent(curr->body); + return; + } + } + void visitFunction(Function* curr) { auto* optimized = optimize(curr->body, curr->getResults() != Type::none, true); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 644a141a227..1bf135c403e 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -47,8 +47,7 @@ namespace wasm { struct WasmException { - Name tag; - Literals values; + Literal exn; }; std::ostream& operator<<(std::ostream& o, const WasmException& exn); @@ -204,6 +203,15 @@ class ExpressionRunner : public OverriddenVisitor { return Literal(allocation, type.getHeapType()); } + // Same as makeGCData but for ExnData. + Literal makeExnData(Name tag, const Literals& payload) { + auto allocation = std::make_shared(tag, payload); +#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer) + __lsan_ignore_object(allocation.get()); +#endif + return Literal(allocation); + } + public: // Indicates no limit of maxDepth or maxLoopIterations. static const Index NO_LIMIT = 0; @@ -1428,16 +1436,25 @@ class ExpressionRunner : public OverriddenVisitor { return flow; } NOTE_EVAL1(curr->tag); - WasmException exn; - exn.tag = curr->tag; - for (auto item : arguments) { - exn.values.push_back(item); - } - throwException(exn); + throwException(WasmException{makeExnData(curr->tag, arguments)}); WASM_UNREACHABLE("throw"); } Flow visitRethrow(Rethrow* curr) { WASM_UNREACHABLE("unimp"); } - Flow visitThrowRef(ThrowRef* curr) { WASM_UNREACHABLE("unimp"); } + Flow visitThrowRef(ThrowRef* curr) { + NOTE_ENTER("ThrowRef"); + Flow flow = visit(curr->exnref); + if (flow.breaking()) { + return flow; + } + const auto& exnref = flow.getSingleValue(); + NOTE_EVAL1(exnref); + if (exnref.isNull()) { + trap("null ref"); + } + assert(exnref.isExn()); + throwException(WasmException{exnref}); + WASM_UNREACHABLE("throw"); + } Flow visitRefI31(RefI31* curr) { NOTE_ENTER("RefI31"); Flow flow = visit(curr->value); @@ -2455,6 +2472,10 @@ class ConstantExpressionRunner : public ExpressionRunner { NOTE_ENTER("Try"); return Flow(NONCONSTANT_FLOW); } + Flow visitTryTable(TryTable* curr) { + NOTE_ENTER("TryTable"); + return Flow(NONCONSTANT_FLOW); + } Flow visitRethrow(Rethrow* curr) { NOTE_ENTER("Rethrow"); return Flow(NONCONSTANT_FLOW); @@ -4103,9 +4124,10 @@ class ModuleRunnerBase : public ExpressionRunner { return ret; }; + auto exnData = e.exn.getExnData(); for (size_t i = 0; i < curr->catchTags.size(); i++) { - if (curr->catchTags[i] == e.tag) { - multiValues.push_back(e.values); + if (curr->catchTags[i] == exnData->tag) { + multiValues.push_back(exnData->payload); return processCatchBody(curr->catchBodies[i]); } } @@ -4119,6 +4141,32 @@ class ModuleRunnerBase : public ExpressionRunner { throw; } } + Flow visitTryTable(TryTable* curr) { + NOTE_ENTER("TryTable"); + try { + return self()->visit(curr->body); + } catch (const WasmException& e) { + auto exnData = e.exn.getExnData(); + for (size_t i = 0; i < curr->catchTags.size(); i++) { + auto catchTag = curr->catchTags[i]; + if (!catchTag.is() || catchTag == exnData->tag) { + Flow ret; + ret.breakTo = curr->catchDests[i]; + if (catchTag.is()) { + for (auto item : exnData->payload) { + ret.values.push_back(item); + } + } + if (curr->catchRefs[i]) { + ret.values.push_back(e.exn); + } + return ret; + } + } + // This exception is not caught by this try_table. Rethrow it. + throw; + } + } Flow visitRethrow(Rethrow* curr) { for (int i = exceptionStack.size() - 1; i >= 0; i--) { if (exceptionStack[i].second == curr->target) { diff --git a/src/wasm-type.h b/src/wasm-type.h index ff1358a122d..03c4f8e772c 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -170,6 +170,7 @@ class Type { bool isSignature() const; bool isStruct() const; bool isArray() const; + bool isExn() const; bool isString() const; bool isDefaultable() const; @@ -388,6 +389,7 @@ class HeapType { bool isContinuation() const { return getKind() == HeapTypeKind::Cont; } bool isStruct() const { return getKind() == HeapTypeKind::Struct; } bool isArray() const { return getKind() == HeapTypeKind::Array; } + bool isExn() const { return isMaybeShared(HeapType::exn); } bool isString() const { return isMaybeShared(HeapType::string); } bool isBottom() const; bool isOpen() const; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 9d659f753c9..650318be3c5 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -80,6 +80,12 @@ Literal::Literal(std::shared_ptr gcData, HeapType type) (type.isBottom() && !gcData)); } +Literal::Literal(std::shared_ptr exnData) + : exnData(exnData), type(HeapType::exn, NonNullable) { + // The data must not be null. + assert(exnData); +} + Literal::Literal(std::string_view string) : gcData(nullptr), type(Type(HeapType::string, NonNullable)) { // TODO: we could in theory internalize strings @@ -133,6 +139,9 @@ Literal::Literal(const Literal& other) : type(other.type) { case HeapType::i31: i32 = other.i32; return; + case HeapType::exn: + new (&exnData) std::shared_ptr(other.exnData); + return; case HeapType::ext: WASM_UNREACHABLE("handled above with isData()"); case HeapType::none: @@ -147,7 +156,6 @@ Literal::Literal(const Literal& other) : type(other.type) { case HeapType::cont: case HeapType::struct_: case HeapType::array: - case HeapType::exn: WASM_UNREACHABLE("invalid type"); case HeapType::string: WASM_UNREACHABLE("TODO: string literals"); @@ -161,6 +169,8 @@ Literal::~Literal() { } if (isNull() || isData() || type.getHeapType().isMaybeShared(HeapType::ext)) { gcData.~shared_ptr(); + } else if (isExn()) { + exnData.~shared_ptr(); } } @@ -328,6 +338,12 @@ std::shared_ptr Literal::getGCData() const { return gcData; } +std::shared_ptr Literal::getExnData() const { + assert(isExn()); + assert(exnData); + return exnData; +} + Literal Literal::castToF32() { assert(type == Type::i32); Literal ret(Type::f32); diff --git a/src/wasm/wasm-interpreter.cpp b/src/wasm/wasm-interpreter.cpp index b49eeef4b1b..cd6c232b5fb 100644 --- a/src/wasm/wasm-interpreter.cpp +++ b/src/wasm/wasm-interpreter.cpp @@ -20,7 +20,8 @@ void Indenter::print() { #endif // WASM_INTERPRETER_DEBUG std::ostream& operator<<(std::ostream& o, const WasmException& exn) { - return o << exn.tag << " " << exn.values; + auto exnData = exn.exn.getExnData(); + return o << exnData->tag << " " << exnData->payload; } } // namespace wasm diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 84ae515214f..1730f1b85b9 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -814,6 +814,8 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); } bool Type::isArray() const { return isRef() && getHeapType().isArray(); } +bool Type::isExn() const { return isRef() && getHeapType().isExn(); } + bool Type::isString() const { return isRef() && getHeapType().isString(); } bool Type::isDefaultable() const { diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast index 7f9ba4219eb..33593957382 100644 --- a/test/lit/basic/reference-types.wast +++ b/test/lit/basic/reference-types.wast @@ -642,6 +642,62 @@ ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $tryend (result eqref) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $catch (result i32) + ;; CHECK-TEXT-NEXT: (br $tryend + ;; CHECK-TEXT-NEXT: (try_table (result eqref) (catch $e-i32 $catch) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $tryend0 (result funcref) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $catch0 (result i32) + ;; CHECK-TEXT-NEXT: (br $tryend0 + ;; CHECK-TEXT-NEXT: (try_table (result funcref) (catch $e-i32 $catch0) + ;; CHECK-TEXT-NEXT: (ref.func $foo) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null nofunc) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $tryend1 (result anyref) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $catch1 (result i32) + ;; CHECK-TEXT-NEXT: (br $tryend1 + ;; CHECK-TEXT-NEXT: (try_table (result anyref) (catch $e-i32 $catch1) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $tryend2 (result anyref) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (block $catch2 (result i32) + ;; CHECK-TEXT-NEXT: (br $tryend2 + ;; CHECK-TEXT-NEXT: (try_table (result anyref) (catch $e-i32 $catch2) + ;; CHECK-TEXT-NEXT: (ref.null none) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (local.get $local_eqref) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: (drop ;; CHECK-TEXT-NEXT: (select (result eqref) ;; CHECK-TEXT-NEXT: (local.get $local_eqref) ;; CHECK-TEXT-NEXT: (ref.null none) @@ -1189,6 +1245,62 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$50 (result eqref) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$51 (result i32) + ;; CHECK-BIN-NEXT: (br $label$50 + ;; CHECK-BIN-NEXT: (try_table (result eqref) (catch $e-i32 $label$51) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$53 (result funcref) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$54 (result i32) + ;; CHECK-BIN-NEXT: (br $label$53 + ;; CHECK-BIN-NEXT: (try_table (result funcref) (catch $e-i32 $label$54) + ;; CHECK-BIN-NEXT: (ref.func $foo) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null nofunc) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$56 (result anyref) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$57 (result i32) + ;; CHECK-BIN-NEXT: (br $label$56 + ;; CHECK-BIN-NEXT: (try_table (result anyref) (catch $e-i32 $label$57) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$59 (result anyref) + ;; CHECK-BIN-NEXT: (drop + ;; CHECK-BIN-NEXT: (block $label$60 (result i32) + ;; CHECK-BIN-NEXT: (br $label$59 + ;; CHECK-BIN-NEXT: (try_table (result anyref) (catch $e-i32 $label$60) + ;; CHECK-BIN-NEXT: (ref.null none) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (local.get $local_eqref) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (select (result eqref) ;; CHECK-BIN-NEXT: (local.get $local_eqref) ;; CHECK-BIN-NEXT: (ref.null none) @@ -1597,6 +1709,66 @@ ) ) + ;; Test try_table return type + (drop + (block $tryend (result eqref) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result eqref) (catch $e-i32 $catch) + (local.get $local_eqref) + ) + ) + ) + ) + (ref.null eq) + ) + ) + (drop + (block $tryend (result funcref) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result funcref) (catch $e-i32 $catch) + (ref.func $foo) + ) + ) + ) + ) + (ref.null func) + ) + ) + + ;; Test subtype relationship for try_table return type + (drop + (block $tryend (result anyref) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result anyref) (catch $e-i32 $catch) + (local.get $local_eqref) + ) + ) + ) + ) + (ref.null any) + ) + ) + (drop + (block $tryend (result anyref) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result anyref) (catch $e-i32 $catch) + (ref.null eq) + ) + ) + ) + ) + (local.get $local_eqref) + ) + ) + ;; Test typed select (drop (select (result eqref) @@ -2416,6 +2588,62 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$50 (result eqref) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$51 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$50 +;; CHECK-BIN-NODEBUG-NEXT: (try_table (result eqref) (catch $tag$0 $label$51) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$53 (result funcref) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$54 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$53 +;; CHECK-BIN-NODEBUG-NEXT: (try_table (result funcref) (catch $tag$0 $label$54) +;; CHECK-BIN-NODEBUG-NEXT: (ref.func $3) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$56 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$57 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$56 +;; CHECK-BIN-NODEBUG-NEXT: (try_table (result anyref) (catch $tag$0 $label$57) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$59 (result anyref) +;; CHECK-BIN-NODEBUG-NEXT: (drop +;; CHECK-BIN-NODEBUG-NEXT: (block $label$60 (result i32) +;; CHECK-BIN-NODEBUG-NEXT: (br $label$59 +;; CHECK-BIN-NODEBUG-NEXT: (try_table (result anyref) (catch $tag$0 $label$60) +;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (select (result eqref) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) diff --git a/test/lit/exec/eh-gc.wast b/test/lit/exec/eh-gc.wast new file mode 100644 index 00000000000..6f97f44f849 --- /dev/null +++ b/test/lit/exec/eh-gc.wast @@ -0,0 +1,27 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. + +;; RUN: wasm-opt %s -all --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s + +(module + (tag $tag (param externref)) + + ;; CHECK: [fuzz-exec] calling catch-null + (func $catch-null (export "catch-null") + (block $tryend + ;; The actual resulting value type is more refined than externref (it is a + ;; bottom type) which we should not error on. + (drop + (block $catch (result externref) + (try_table (catch $tag $catch) + (throw $tag + (ref.null noextern) + ) + ) + (br $tryend) + ) + ) + ) + ) +) +;; CHECK: [fuzz-exec] calling catch-null +;; CHECK-NEXT: [fuzz-exec] comparing catch-null diff --git a/test/lit/exec/eh-legacy-print.wast b/test/lit/exec/eh-print.wast similarity index 100% rename from test/lit/exec/eh-legacy-print.wast rename to test/lit/exec/eh-print.wast diff --git a/test/lit/exec/eh.wast b/test/lit/exec/eh.wast new file mode 100644 index 00000000000..45215b04868 --- /dev/null +++ b/test/lit/exec/eh.wast @@ -0,0 +1,45 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. + +;; RUN: wasm-opt %s -all --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s + +(module + (tag $e-i32 (param i32)) + + ;; CHECK: [fuzz-exec] calling throw + ;; CHECK-NEXT: [exception thrown: e-i32 1] + (func $throw (export "throw") + (throw $e-i32 (i32.const 1)) + ) + + ;; CHECK: [fuzz-exec] calling try_table-catch + (func $try_table-catch (export "try_table-catch") + (block $tryend + (drop + (block $catch (result i32) + (try_table (catch $e-i32 $catch) + (throw $e-i32 (i32.const 2)) + ) + (br $tryend) + ) + ) + ) + ) + + ;; CHECK: [fuzz-exec] calling catchless-try_table + ;; CHECK-NEXT: [exception thrown: e-i32 3] + (func $catchless-try_table (export "catchless-try_table") + (try_table + (throw $e-i32 (i32.const 3)) + ) + ) +) +;; CHECK: [fuzz-exec] calling throw +;; CHECK-NEXT: [exception thrown: e-i32 1] + +;; CHECK: [fuzz-exec] calling try_table-catch + +;; CHECK: [fuzz-exec] calling catchless-try_table +;; CHECK-NEXT: [exception thrown: e-i32 3] +;; CHECK-NEXT: [fuzz-exec] comparing catchless-try_table +;; CHECK-NEXT: [fuzz-exec] comparing throw +;; CHECK-NEXT: [fuzz-exec] comparing try_table-catch diff --git a/test/lit/merge/renamings.wat b/test/lit/merge/renamings.wat index c6a22542ac5..9c54f3514ec 100644 --- a/test/lit/merge/renamings.wat +++ b/test/lit/merge/renamings.wat @@ -160,6 +160,22 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result i32) + ;; CHECK-NEXT: (try_table (catch $foo $catch) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch0 (result i64) + ;; CHECK-NEXT: (try_table (catch $bar $catch0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load $foo ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -220,6 +236,22 @@ ) ) ) + (drop + (block $catch (result i32) + (try_table (catch $foo $catch) + (nop) + ) + (i32.const 0) + ) + ) + (drop + (block $catch (result i64) + (try_table (catch $bar $catch) + (nop) + ) + (i64.const 0) + ) + ) ;; Memories (drop @@ -310,6 +342,22 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop +;; CHECK-NEXT: (block $catch (result f32) +;; CHECK-NEXT: (try_table (catch $foo_2 $catch) +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (f32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (block $catch0 (result f64) +;; CHECK-NEXT: (try_table (catch $other $catch0) +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (f64.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.load $foo_2 ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) diff --git a/test/lit/merge/renamings.wat.second b/test/lit/merge/renamings.wat.second index 25d3d5e81dd..c17b00cc504 100644 --- a/test/lit/merge/renamings.wat.second +++ b/test/lit/merge/renamings.wat.second @@ -70,6 +70,22 @@ ) ) ) + (drop + (block $catch (result f32) + (try_table (catch $foo $catch) + (nop) + ) + (f32.const 0.0) + ) + ) + (drop + (block $catch (result f64) + (try_table (catch $other $catch) + (nop) + ) + (f64.const 0.0) + ) + ) ;; Memories (drop diff --git a/test/lit/passes/coalesce-locals-eh-legacy.wast b/test/lit/passes/coalesce-locals-eh-legacy.wast index 63b1445dd69..9091fdcb960 100644 --- a/test/lit/passes/coalesce-locals-eh-legacy.wast +++ b/test/lit/passes/coalesce-locals-eh-legacy.wast @@ -3,8 +3,10 @@ (module ;; CHECK: (tag $e) + (tag $e) ;; CHECK: (tag $any (param (ref any))) + (tag $any (param (ref any))) ;; CHECK: (func $bar (type $2) (result i32) ;; CHECK-NEXT: (i32.const 1984) @@ -13,10 +15,6 @@ (i32.const 1984) ) - (tag $e) - - (tag $any (param (ref any))) - ;; CHECK: (func $bug-cfg-traversal (type $3) (param $0 i32) (result i32) ;; CHECK-NEXT: (try ;; CHECK-NEXT: (do diff --git a/test/lit/passes/coalesce-locals-eh.wast b/test/lit/passes/coalesce-locals-eh.wast new file mode 100644 index 00000000000..90458f32fef --- /dev/null +++ b/test/lit/passes/coalesce-locals-eh.wast @@ -0,0 +1,84 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --coalesce-locals -all -S -o - | filecheck %s + +(module + ;; CHECK: (tag $e) + (tag $e) + + ;; CHECK: (tag $any (param (ref any))) + (tag $any (param (ref any))) + + ;; CHECK: (func $bar (type $2) (result i32) + ;; CHECK-NEXT: (i32.const 1984) + ;; CHECK-NEXT: ) + (func $bar (result i32) + (i32.const 1984) + ) + + ;; CHECK: (func $bug-cfg-traversal (type $3) (param $0 i32) (result i32) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (call $bar) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + (func $bug-cfg-traversal (param $0 i32) (result i32) + (local $x i32) + ;; This is a regression test case for a bug in cfg-traversal for EH. + ;; See https://github.com/WebAssembly/binaryen/pull/3594 + (block $tryend + (block $catch + (try_table (catch_all $catch) + (local.set $x + ;; the call may or may not throw, so we may reach the get of $x + (call $bar) + ) + ) + (br $tryend) + ) + (unreachable) + ) + (local.get $x) + ) + + ;; CHECK: (func $0 (type $0) + ;; CHECK-NEXT: (local $0 anyref) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result anyref) + ;; CHECK-NEXT: (block $catch (result (ref any)) + ;; CHECK-NEXT: (try_table (catch $any $catch) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $0 + (local $0 (ref null any)) + (block $tryend + (drop + ;; There is a difference between the type of the value here and the type + ;; of the local, due to the local being nullable. We should not error on + ;; that as we replace the tee with a drop (as it has no gets). + (local.tee $0 + (block $catch (result (ref any)) + (try_table (catch $any $catch) + (nop) + ) + (br $tryend) + ) + ) + ) + ) + ) +) diff --git a/test/lit/passes/code-folding-eh-legacy.wast b/test/lit/passes/code-folding-eh-legacy.wast index 05cd8db8b66..852ec126a92 100644 --- a/test/lit/passes/code-folding-eh-legacy.wast +++ b/test/lit/passes/code-folding-eh-legacy.wast @@ -96,6 +96,7 @@ (func $try-call-optimize-terminating-tails-success (result i32) (try (do + ;; Expressions that cannot throw can be taken out of 'try' scope. (drop (i32.const 1)) (drop (i32.const 1)) (return (i32.const 0)) @@ -243,6 +244,9 @@ (drop (i32.const 1)) (drop (i32.const 1)) (drop (i32.const 1)) + ;; return_call executes the call after returning from this function. + ;; This try cannot catch exceptions it throws, so we can fold it out of + ;; the try. (return_call $foo-i32) ) (catch_all @@ -281,6 +285,7 @@ (block $x (try (do + ;; Expressions that cannot throw can be taken out of 'try' scope. (drop (i32.const 1)) (drop (i32.const 1)) (drop (i32.const 1)) diff --git a/test/lit/passes/code-folding-eh.wast b/test/lit/passes/code-folding-eh.wast new file mode 100644 index 00000000000..5a7cd68c783 --- /dev/null +++ b/test/lit/passes/code-folding-eh.wast @@ -0,0 +1,296 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --remove-unused-names --code-folding -all -S -o - \ +;; RUN: | filecheck %s + +(module + ;; CHECK: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + + ;; CHECK: (func $try_table-call-optimize-terminating-tails-success (type $0) (result i32) + ;; CHECK-NEXT: (block $folding-inner0 + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-terminating-tails-success (result i32) + (block $tryend + (block $catch + (try_table (catch_all $catch) + ;; Expressions that cannot throw can be taken out of 'try' scope. + (drop (i32.const 1)) + (drop (i32.const 1)) + (return (i32.const 0)) + ) + (br $tryend) + ) + (drop (i32.const 1)) + (drop (i32.const 1)) + (return (i32.const 0)) + ) + (i32.const 0) + ) + + + ;; CHECK: (func $foo (type $1) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo) + + ;; CHECK: (func $try_table-call-optimize-terminating-tails (type $0) (result i32) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-terminating-tails (result i32) + (block $tryend + (block $catch + (try_table (catch_all $catch) + ;; Expressions that can throw should NOT be taken out of 'try' scope. + (call $foo) + (call $foo) + (call $foo) + (call $foo) + (return (i32.const 0)) + ) + (br $tryend) + ) + (call $foo) + (call $foo) + (call $foo) + (call $foo) + (return (i32.const 0)) + ) + (i32.const 0) + ) + + ;; CHECK: (func $foo-i32 (type $0) (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $foo-i32 (result i32) + (i32.const 0) + ) + + ;; CHECK: (func $try_table-call-optimize-terminating-tails-call-return (type $0) (result i32) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (call $foo-i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (call $foo-i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-terminating-tails-call-return (result i32) + (block $tryend + (block $catch + (try_table (catch_all $catch) + (drop (i32.const 1)) + (drop (i32.const 1)) + ;; Cannot be folded out of the try because it might throw. + (return (call $foo-i32)) + ) + (br $tryend) + ) + (drop (i32.const 1)) + (drop (i32.const 1)) + (return (call $foo-i32)) + ) + (i32.const 0) + ) + + ;; CHECK: (func $try_table-call-optimize-terminating-tails-return-call (type $0) (result i32) + ;; CHECK-NEXT: (block $folding-inner0 + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call $foo-i32) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-terminating-tails-return-call (result i32) + (block $tryend + (block $catch + (try_table (catch_all $catch) + (drop (i32.const 1)) + (drop (i32.const 1)) + (drop (i32.const 1)) + ;; return_call executes the call after returning from this function. + ;; This try_table cannot catch exceptions it throws, so we can fold it + ;; out of the try_table. + (return_call $foo-i32) + ) + (br $tryend) + ) + (drop (i32.const 1)) + (drop (i32.const 1)) + (drop (i32.const 1)) + (return_call $foo-i32) + ) + (i32.const 0) + ) + + ;; CHECK: (func $try_table-call-optimize-expression-tails-success (type $1) + ;; CHECK-NEXT: (block $x + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-expression-tails-success + (block $x + (block $tryend + (block $catch + (try_table (catch_all $catch) + ;; Expressions that cannot throw can be taken out of 'try_table' + ;; scope. + (drop (i32.const 1)) + (drop (i32.const 1)) + (drop (i32.const 1)) + (br $x) + ) + (br $tryend) + ) + (drop (i32.const 1)) + (drop (i32.const 1)) + (drop (i32.const 1)) + (br $x) + ) + (unreachable) + ) + ) + + ;; CHECK: (func $try_table-call-optimize-expression-tails (type $1) + ;; CHECK-NEXT: (block $x + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: (br $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-call-optimize-expression-tails + (block $x + (block $tryend + (block $catch + (try_table (catch_all $catch) + ;; Expressions that can throw should NOT be taken out of 'try' scope. + (call $foo) + (call $foo) + (call $foo) + (br $x) + ) + (br $tryend) + ) + (call $foo) + (call $foo) + (call $foo) + (br $x) + ) + (unreachable) + ) + ) +) diff --git a/test/lit/passes/code-pushing-eh-legacy.wast b/test/lit/passes/code-pushing-eh-legacy.wast index 8fc0d423d89..9511d244a41 100644 --- a/test/lit/passes/code-pushing-eh-legacy.wast +++ b/test/lit/passes/code-pushing-eh-legacy.wast @@ -7,69 +7,6 @@ ;; CHECK: (tag $e (param i32)) (tag $e (param i32)) - ;; CHECK: (func $cannot-push-past-call (type $0) - ;; CHECK-NEXT: (local $x i32) - ;; CHECK-NEXT: (block $out - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $cannot-push-past-call) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $out - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $cannot-push-past-call - (local $x i32) - (block $out - ;; This local.set cannot be pushed down, because the call below can throw - (local.set $x (i32.const 1)) - (call $cannot-push-past-call) - (drop (i32.const 1)) - (br_if $out (i32.const 2)) - (drop (local.get $x)) - ) - ) - - ;; CHECK: (func $cannot-push-past-throw (type $0) - ;; CHECK-NEXT: (local $x i32) - ;; CHECK-NEXT: (block $out - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (br_if $out - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $cannot-push-past-throw - (local $x i32) - (block $out - ;; This local.set cannot be pushed down, because there is 'throw' below. - ;; This pass only pushes past conditional control flow atm. - (local.set $x (i32.const 1)) - (throw $e (i32.const 0)) - (drop (i32.const 1)) - (br_if $out (i32.const 2)) - (drop (local.get $x)) - ) - ) - ;; CHECK: (func $can-push-past-try (type $0) ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (block $out @@ -323,80 +260,4 @@ (drop (local.get $x)) ) ) - - ;; CHECK: (func $can-push-past-conditional-throw (type $1) (param $param i32) - ;; CHECK-NEXT: (local $x i32) - ;; CHECK-NEXT: (block $block - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $can-push-past-conditional-throw (param $param i32) - (local $x i32) - (block $block - ;; We can push past an if containing a throw. The if is conditional - ;; control flow, which is what we look for in this optimization, and a - ;; throw is like a break - it will jump out of the current block - so we - ;; can push the set past it, as the set is only needed in this block. - (local.set $x (i32.const 1)) - (if - (local.get $param) - (then - (throw $e (i32.const 0)) - ) - ) - (drop (local.get $x)) - ) - ) - - ;; CHECK: (func $cannot-push-past-conditional-throw-extra-use (type $1) (param $param i32) - ;; CHECK-NEXT: (local $x i32) - ;; CHECK-NEXT: (block $block - ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (i32.const 1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $param) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (throw $e - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $cannot-push-past-conditional-throw-extra-use (param $param i32) - (local $x i32) - ;; As above, but now there is another local.get outside of the block. That - ;; means the local.set cannot be pushed to a place it might not execute. - (block $block - (local.set $x (i32.const 1)) - (if - (local.get $param) - (then - (throw $e (i32.const 0)) - ) - ) - (drop (local.get $x)) - ) - (drop (local.get $x)) - ) ) diff --git a/test/lit/passes/code-pushing-eh.wast b/test/lit/passes/code-pushing-eh.wast new file mode 100644 index 00000000000..ee2798c4605 --- /dev/null +++ b/test/lit/passes/code-pushing-eh.wast @@ -0,0 +1,300 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --code-pushing -all -S -o - | filecheck %s + +;; The tests in this file test EffectAnalyzer, which is used by CodePushing. + +(module + ;; CHECK: (tag $e (param i32)) + (tag $e (param i32)) + + ;; CHECK: (func $cannot-push-past-call (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $cannot-push-past-call) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cannot-push-past-call + (local $x i32) + (block $out + ;; This local.set cannot be pushed down, because the call below can throw. + (local.set $x (i32.const 1)) + (call $cannot-push-past-call) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $cannot-push-past-throw (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cannot-push-past-throw + (local $x i32) + (block $out + ;; This local.set cannot be pushed down, because there is 'throw' below. + ;; This pass only pushes past conditional control flow atm. + (local.set $x (i32.const 1)) + (throw $e (i32.const 0)) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $can-push-past-try_table (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $can-push-past-try_table + (local $x i32) + (block $out + ;; This local.set can be pushed down, because the 'throw' below is going + ;; to be caught by the inner catch_all. + (local.set $x (i32.const 1)) + (block $tryend + (block $catch + (try_table (catch_all $catch) + (throw $e (i32.const 0)) + ) + (br $tryend) + ) + ) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $foo (type $0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo) + + ;; CHECK: (func $cannot-push-past-try_table (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e $catch) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cannot-push-past-try_table + (local $x i32) + (block $out + ;; This local.set cannot be pushed down, because the exception thrown by + ;; 'call $foo' below may not be caught by 'catch $e'. + (local.set $x (i32.const 1)) + (block $tryend + (drop + (block $catch (result i32) + (try_table (catch $e $catch) + (call $foo) + ) + (br $tryend) + ) + ) + ) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $cannot-push-past-throw_ref-within-catch (type $0) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (throw_ref + ;; CHECK-NEXT: (block $catch (result exnref) + ;; CHECK-NEXT: (try_table (catch_all_ref $catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cannot-push-past-throw_ref-within-catch + (local $x i32) + (block $out + ;; This local.set cannot be pushed down, because there is 'throw_ref' + ;; within the catch handler. + (local.set $x (i32.const 1)) + (block $tryend + (throw_ref + (block $catch (result exnref) + (try_table (catch_all_ref $catch) + (throw $e (i32.const 0)) + ) + (br $tryend) + ) + ) + ) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $can-push-past-conditional-throw (type $1) (param $param i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $param) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $can-push-past-conditional-throw (param $param i32) + (local $x i32) + (block $block + ;; We can push past an if containing a throw. The if is conditional + ;; control flow, which is what we look for in this optimization, and a + ;; throw is like a break - it will jump out of the current block - so we + ;; can push the set past it, as the set is only needed in this block. + (local.set $x (i32.const 1)) + (if + (local.get $param) + (then + (throw $e (i32.const 0)) + ) + ) + (drop (local.get $x)) + ) + ) + + ;; CHECK: (func $cannot-push-past-conditional-throw-extra-use (type $1) (param $param i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $param) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $cannot-push-past-conditional-throw-extra-use (param $param i32) + (local $x i32) + ;; As above, but now there is another local.get outside of the block. That + ;; means the local.set cannot be pushed to a place it might not execute. + (block $block + (local.set $x (i32.const 1)) + (if + (local.get $param) + (then + (throw $e (i32.const 0)) + ) + ) + (drop (local.get $x)) + ) + (drop (local.get $x)) + ) +) diff --git a/test/lit/passes/dce-eh-legacy.wast b/test/lit/passes/dce-eh-legacy.wast index 120ec4e117d..ef6d569d69b 100644 --- a/test/lit/passes/dce-eh-legacy.wast +++ b/test/lit/passes/dce-eh-legacy.wast @@ -79,32 +79,6 @@ (call $foo) ;; should be dce'd ) - ;; CHECK: (func $throw (type $0) - ;; CHECK-NEXT: (block $label$0 - ;; CHECK-NEXT: (block $label$1 - ;; CHECK-NEXT: (throw $e) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $throw - ;; All these wrapping expressions before 'throw' will be dce'd - (drop - (block $label$0 (result externref) - (if - (i32.clz - (block $label$1 (result i32) - (throw $e) - ) - ) - (then - (nop) - ) - ) - (ref.null extern) - ) - ) - ) - ;; CHECK: (func $rethrow (type $0) ;; CHECK-NEXT: (try $l0 ;; CHECK-NEXT: (do diff --git a/test/lit/passes/dce-eh.wast b/test/lit/passes/dce-eh.wast new file mode 100644 index 00000000000..413a278d0b8 --- /dev/null +++ b/test/lit/passes/dce-eh.wast @@ -0,0 +1,145 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --dce -all -S -o - | filecheck %s + +;; If either try_table body or any of catch handler is reachable, the whole +;; try_table construct is reachable. +(module + ;; CHECK: (tag $e) + (tag $e) + + ;; CHECK: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + + ;; CHECK: (func $foo (type $0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $foo) + + ;; CHECK: (func $try_table_unreachable (type $0) + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: ) + (func $try_table_unreachable + (block $catch + (try_table (catch_all $catch) + (unreachable) + ) + ) + (call $foo) ;; shouldn't be dce'd + ) + + ;; CHECK: (func $catch_unreachable (type $0) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $foo) + ;; CHECK-NEXT: ) + (func $catch_unreachable + (block $tryend + (block $catch + (try_table (catch_all $catch) + (br $tryend) + ) + ) + (unreachable) + ) + (call $foo) ;; shouldn't be dce'd + ) + + ;; CHECK: (func $both_unreachable (type $0) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $both_unreachable + (block $tryend + (block $catch + (try_table (catch_all $catch) + (unreachable) + ) + ) + (unreachable) + ) + (call $foo) ;; should be dce'd + ) + + ;; CHECK: (func $throw (type $0) + ;; CHECK-NEXT: (block $label$0 + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (throw $e) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $throw + ;; All these wrapping expressions before 'throw' will be dce'd. + (drop + (block $label$0 (result externref) + (if + (i32.clz + (block $label$1 (result i32) + (throw $e) + ) + ) + (then + (nop) + ) + ) + (ref.null extern) + ) + ) + ) + + ;; CHECK: (func $throw_ref (type $0) + ;; CHECK-NEXT: (local $ex exnref) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (local.set $ex + ;; CHECK-NEXT: (block $catch (result exnref) + ;; CHECK-NEXT: (try_table (catch_all_ref $catch) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (throw_ref + ;; CHECK-NEXT: (local.get $ex) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $throw_ref + (local $ex exnref) + (block $tryend + (local.set $ex + (block $catch (result exnref) + (try_table (catch_all_ref $catch) + (br $tryend) + ) + ) + ) + (drop + ;; This i32.add will be dce'd. + (i32.add + (i32.const 0) + (throw_ref (local.get $ex)) + ) + ) + ) + ) +) diff --git a/test/lit/passes/global-effects-eh-legacy.wast b/test/lit/passes/global-effects-eh-legacy.wast new file mode 100644 index 00000000000..7390f996d8d --- /dev/null +++ b/test/lit/passes/global-effects-eh-legacy.wast @@ -0,0 +1,507 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Run without global effects, and run with, and also run with but discard them +;; first (to check that discard works; that should be the same as without). + +;; RUN: foreach %s %t wasm-opt -all --vacuum -S -o - | filecheck %s --check-prefix WITHOUT +;; RUN: foreach %s %t wasm-opt -all --generate-global-effects --vacuum -S -o - | filecheck %s --check-prefix INCLUDE +;; RUN: foreach %s %t wasm-opt -all --generate-global-effects --discard-global-effects --vacuum -S -o - | filecheck %s --check-prefix WITHOUT + +(module + + ;; WITHOUT: (type $void (func)) + ;; INCLUDE: (type $void (func)) + (type $void (func)) + + ;; WITHOUT: (type $1 (func (result i32))) + + ;; WITHOUT: (type $2 (func (param i32))) + + ;; WITHOUT: (import "a" "b" (func $import (type $void))) + ;; INCLUDE: (type $1 (func (result i32))) + + ;; INCLUDE: (type $2 (func (param i32))) + + ;; INCLUDE: (import "a" "b" (func $import (type $void))) + (import "a" "b" (func $import)) + + ;; WITHOUT: (table $t 0 funcref) + ;; INCLUDE: (table $t 0 funcref) + (table $t 0 funcref) + + ;; WITHOUT: (elem declare func $throw) + + ;; WITHOUT: (tag $tag) + ;; INCLUDE: (elem declare func $throw) + + ;; INCLUDE: (tag $tag) + (tag $tag) + + ;; WITHOUT: (func $main (type $void) + ;; WITHOUT-NEXT: (call $nop) + ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: (call $call-nop) + ;; WITHOUT-NEXT: (call $call-unreachable) + ;; WITHOUT-NEXT: (drop + ;; WITHOUT-NEXT: (call $unimportant-effects) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (call $throw) + ;; WITHOUT-NEXT: (call $throw-and-import) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $main (type $void) + ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: (call $call-unreachable) + ;; INCLUDE-NEXT: (call $throw) + ;; INCLUDE-NEXT: (call $throw-and-import) + ;; INCLUDE-NEXT: ) + (func $main + ;; Calling a function with no effects can be optimized away in INCLUDE (but + ;; not WITHOUT or DISCARD, where the global effect info is not available). + (call $nop) + ;; Calling a function with effects cannot. + (call $unreachable) + ;; Calling something that calls something with no effects can be optimized + ;; away, since we compute transitive effects + (call $call-nop) + ;; Calling something that calls something with effects cannot. + (call $call-unreachable) + ;; Calling something that only has unimportant effects can be optimized + ;; (see below for details). + (drop + (call $unimportant-effects) + ) + ;; A throwing function cannot be removed. + (call $throw) + ;; A function that throws and calls an import definitely cannot be removed. + (call $throw-and-import) + ) + + ;; WITHOUT: (func $cycle (type $void) + ;; WITHOUT-NEXT: (call $cycle) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $cycle (type $void) + ;; INCLUDE-NEXT: (call $cycle) + ;; INCLUDE-NEXT: ) + (func $cycle + ;; Calling a function with no effects in a cycle cannot be optimized out - + ;; this must keep hanging forever. + (call $cycle) + ) + + ;; WITHOUT: (func $cycle-1 (type $void) + ;; WITHOUT-NEXT: (call $cycle-2) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $cycle-1 (type $void) + ;; INCLUDE-NEXT: (call $cycle-2) + ;; INCLUDE-NEXT: ) + (func $cycle-1 + ;; $cycle-1 and -2 form a cycle together, in which no call can be removed. + (call $cycle-2) + ) + + ;; WITHOUT: (func $cycle-2 (type $void) + ;; WITHOUT-NEXT: (call $cycle-1) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $cycle-2 (type $void) + ;; INCLUDE-NEXT: (call $cycle-1) + ;; INCLUDE-NEXT: ) + (func $cycle-2 + (call $cycle-1) + ) + + ;; WITHOUT: (func $nop (type $void) + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $nop (type $void) + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + (func $nop + (nop) + ) + + ;; WITHOUT: (func $unreachable (type $void) + ;; WITHOUT-NEXT: (unreachable) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $unreachable (type $void) + ;; INCLUDE-NEXT: (unreachable) + ;; INCLUDE-NEXT: ) + (func $unreachable + (unreachable) + ) + + ;; WITHOUT: (func $call-nop (type $void) + ;; WITHOUT-NEXT: (call $nop) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-nop (type $void) + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + (func $call-nop + ;; This call to a nop can be optimized out, as above, in INCLUDE. + (call $nop) + ) + + ;; WITHOUT: (func $call-unreachable (type $void) + ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-unreachable (type $void) + ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: ) + (func $call-unreachable + (call $unreachable) + ) + + ;; WITHOUT: (func $unimportant-effects (type $1) (result i32) + ;; WITHOUT-NEXT: (local $x i32) + ;; WITHOUT-NEXT: (local.set $x + ;; WITHOUT-NEXT: (i32.const 100) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (return + ;; WITHOUT-NEXT: (local.get $x) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $unimportant-effects (type $1) (result i32) + ;; INCLUDE-NEXT: (local $x i32) + ;; INCLUDE-NEXT: (local.set $x + ;; INCLUDE-NEXT: (i32.const 100) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (return + ;; INCLUDE-NEXT: (local.get $x) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + (func $unimportant-effects (result i32) + (local $x i32) + ;; Operations on locals should not prevent optimization, as when we return + ;; from the function they no longer matter. + (local.set $x + (i32.const 100) + ) + ;; A return is an effect that no longer matters once we exit the function. + (return + (local.get $x) + ) + ) + + ;; WITHOUT: (func $call-throw-and-catch (type $void) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $throw) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $throw-and-import) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-throw-and-catch (type $void) + ;; INCLUDE-NEXT: (try + ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (call $throw-and-import) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (catch_all + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + (func $call-throw-and-catch + (try + (do + ;; This call cannot be optimized out, as the target throws. However, the + ;; entire try-catch can be, since the call's only effect is to throw, + ;; and the catch_all catches that. + (call $throw) + ) + (catch_all) + ) + (try + (do + ;; This call both throws and calls an import, and cannot be removed. + (call $throw-and-import) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $return-call-throw-and-catch (type $void) + ;; WITHOUT-NEXT: (return_call $throw) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $return-call-throw-and-catch (type $void) + ;; INCLUDE-NEXT: (return_call $throw) + ;; INCLUDE-NEXT: ) + (func $return-call-throw-and-catch + (try + (do + ;; This call cannot be optimized out, as the target throws. However, the + ;; surrounding try-catch can be removed even without global effects + ;; because the throw from the return_call is never observed by this + ;; try-catch. + (return_call $throw) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $return-call-indirect-throw-and-catch (type $void) + ;; WITHOUT-NEXT: (return_call_indirect $t (type $void) + ;; WITHOUT-NEXT: (i32.const 0) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $return-call-indirect-throw-and-catch (type $void) + ;; INCLUDE-NEXT: (return_call_indirect $t (type $void) + ;; INCLUDE-NEXT: (i32.const 0) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + (func $return-call-indirect-throw-and-catch + (try + (do + ;; This call cannot be optimized out, as the target may throw. However, + ;; the surrounding try-catch can be removed even without global effects + ;; because the throw from the return_call is never observed by this + ;; try-catch. + (return_call_indirect + (i32.const 0) + ) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $return-call-ref-throw-and-catch (type $void) + ;; WITHOUT-NEXT: (return_call_ref $void + ;; WITHOUT-NEXT: (ref.func $throw) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $return-call-ref-throw-and-catch (type $void) + ;; INCLUDE-NEXT: (return_call_ref $void + ;; INCLUDE-NEXT: (ref.func $throw) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + (func $return-call-ref-throw-and-catch + (try + (do + ;; This call cannot be optimized out, as the target may throw. However, + ;; the surrounding try-catch can be removed even without global effects + ;; because the throw from the return_call is never observed by this + ;; try-catch. + (return_call_ref $void + (ref.func $throw) + ) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $call-return-call-throw-and-catch (type $void) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $return-call-throw-and-catch) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (call $return-call-throw-and-catch) + ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch) + ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-return-call-throw-and-catch (type $void) + ;; INCLUDE-NEXT: (try + ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (catch_all + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (try + ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (catch_all + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (call $return-call-throw-and-catch) + ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch) + ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch) + ;; INCLUDE-NEXT: ) + (func $call-return-call-throw-and-catch + (try + (do + ;; Even though the body of the previous function is a try-catch_all, the + ;; function still throws because of its return_call, so this cannot be + ;; optimized out, but once again the entire try-catch can be. + (call $return-call-throw-and-catch) + ) + (catch_all) + ) + (try + (do + ;; This would be the same, except since it performs an indirect call, we + ;; conservatively assume it could have any effect, so we can't optimize. + (call $return-call-indirect-throw-and-catch) + ) + (catch_all) + ) + (try + (do + ;; Same here. + (call $return-call-ref-throw-and-catch) + ) + (catch_all) + ) + + ;; These cannot be optimized out at all. + (call $return-call-throw-and-catch) + (call $return-call-indirect-throw-and-catch) + (call $return-call-ref-throw-and-catch) + ) + + ;; WITHOUT: (func $call-unreachable-and-catch (type $void) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-unreachable-and-catch (type $void) + ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: ) + (func $call-unreachable-and-catch + (try + (do + ;; This call has a non-throw effect. We can optimize away the try-catch + ;; (since no exception can be thrown anyhow), but we must leave the + ;; call. + (call $unreachable) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $call-throw-or-unreachable-and-catch (type $2) (param $x i32) + ;; WITHOUT-NEXT: (try + ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (if + ;; WITHOUT-NEXT: (local.get $x) + ;; WITHOUT-NEXT: (then + ;; WITHOUT-NEXT: (call $throw) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (else + ;; WITHOUT-NEXT: (call $unreachable) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: (catch_all + ;; WITHOUT-NEXT: (nop) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $call-throw-or-unreachable-and-catch (type $2) (param $x i32) + ;; INCLUDE-NEXT: (try + ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (if + ;; INCLUDE-NEXT: (local.get $x) + ;; INCLUDE-NEXT: (then + ;; INCLUDE-NEXT: (call $throw) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (else + ;; INCLUDE-NEXT: (call $unreachable) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (catch_all + ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: ) + (func $call-throw-or-unreachable-and-catch (param $x i32) + ;; This try-catch-all's body will either call a throw or an unreachable. + ;; Since we have both possible effects, we cannot optimize anything here. + (try + (do + (if + (local.get $x) + (then + (call $throw) + ) + (else + (call $unreachable) + ) + ) + ) + (catch_all) + ) + ) + + ;; WITHOUT: (func $throw (type $void) + ;; WITHOUT-NEXT: (throw $tag) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $throw (type $void) + ;; INCLUDE-NEXT: (throw $tag) + ;; INCLUDE-NEXT: ) + (func $throw + (throw $tag) + ) + + ;; WITHOUT: (func $throw-and-import (type $void) + ;; WITHOUT-NEXT: (throw $tag) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $throw-and-import (type $void) + ;; INCLUDE-NEXT: (throw $tag) + ;; INCLUDE-NEXT: ) + (func $throw-and-import + (if + (i32.const 1) + (then + (throw $tag) + ) + (else + (call $import) + ) + ) + ) + + ;; WITHOUT: (func $cycle-with-unknown-call (type $void) + ;; WITHOUT-NEXT: (call $cycle-with-unknown-call) + ;; WITHOUT-NEXT: (call $import) + ;; WITHOUT-NEXT: ) + ;; INCLUDE: (func $cycle-with-unknown-call (type $void) + ;; INCLUDE-NEXT: (call $cycle-with-unknown-call) + ;; INCLUDE-NEXT: (call $import) + ;; INCLUDE-NEXT: ) + (func $cycle-with-unknown-call + ;; This function can not only call itself recursively, but also calls an + ;; import. We should not remove anything here, and not error during the + ;; analysis (this guards against a bug where the import would make us toss + ;; away the effects object, and the infinite loop makes us set a property on + ;; that object, so it must check the object still exists). + (call $cycle-with-unknown-call) + (call $import) + ) +) diff --git a/test/lit/passes/global-effects.wast b/test/lit/passes/global-effects.wast index 7390f996d8d..c3c6d207370 100644 --- a/test/lit/passes/global-effects.wast +++ b/test/lit/passes/global-effects.wast @@ -182,49 +182,44 @@ ) ;; WITHOUT: (func $call-throw-and-catch (type $void) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend + ;; WITHOUT-NEXT: (try_table (catch_all $tryend) ;; WITHOUT-NEXT: (call $throw) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend0 + ;; WITHOUT-NEXT: (try_table (catch_all $tryend0) ;; WITHOUT-NEXT: (call $throw-and-import) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; INCLUDE: (func $call-throw-and-catch (type $void) - ;; INCLUDE-NEXT: (try - ;; INCLUDE-NEXT: (do - ;; INCLUDE-NEXT: (call $throw-and-import) + ;; INCLUDE-NEXT: (block $tryend + ;; INCLUDE-NEXT: (try_table (catch_all $tryend) + ;; INCLUDE-NEXT: (call $throw) ;; INCLUDE-NEXT: ) - ;; INCLUDE-NEXT: (catch_all - ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (block $tryend0 + ;; INCLUDE-NEXT: (try_table (catch_all $tryend0) + ;; INCLUDE-NEXT: (call $throw-and-import) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) (func $call-throw-and-catch - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call cannot be optimized out, as the target throws. However, the - ;; entire try-catch can be, since the call's only effect is to throw, - ;; and the catch_all catches that. + ;; entire try_table could be, since the call's only effect is to throw, + ;; and the catch_all catches that. We do this for `try` but not yet for + ;; `try_table`. (call $throw) ) - (catch_all) ) - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call both throws and calls an import, and cannot be removed. (call $throw-and-import) ) - (catch_all) ) ) @@ -235,15 +230,14 @@ ;; INCLUDE-NEXT: (return_call $throw) ;; INCLUDE-NEXT: ) (func $return-call-throw-and-catch - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call cannot be optimized out, as the target throws. However, the - ;; surrounding try-catch can be removed even without global effects + ;; surrounding try_table can be removed even without global effects ;; because the throw from the return_call is never observed by this - ;; try-catch. + ;; try_table. (return_call $throw) ) - (catch_all) ) ) @@ -258,17 +252,16 @@ ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) (func $return-call-indirect-throw-and-catch - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call cannot be optimized out, as the target may throw. However, - ;; the surrounding try-catch can be removed even without global effects + ;; the surrounding try_table can be removed even without global effects ;; because the throw from the return_call is never observed by this ;; try-catch. (return_call_indirect (i32.const 0) ) ) - (catch_all) ) ) @@ -283,94 +276,81 @@ ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) (func $return-call-ref-throw-and-catch - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call cannot be optimized out, as the target may throw. However, - ;; the surrounding try-catch can be removed even without global effects + ;; the surrounding try_table can be removed even without global effects ;; because the throw from the return_call is never observed by this ;; try-catch. (return_call_ref $void (ref.func $throw) ) ) - (catch_all) ) ) ;; WITHOUT: (func $call-return-call-throw-and-catch (type $void) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend + ;; WITHOUT-NEXT: (try_table (catch_all $tryend) ;; WITHOUT-NEXT: (call $return-call-throw-and-catch) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend0 + ;; WITHOUT-NEXT: (try_table (catch_all $tryend0) ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend1 + ;; WITHOUT-NEXT: (try_table (catch_all $tryend1) ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: (call $return-call-throw-and-catch) ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch) ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch) ;; WITHOUT-NEXT: ) ;; INCLUDE: (func $call-return-call-throw-and-catch (type $void) - ;; INCLUDE-NEXT: (try - ;; INCLUDE-NEXT: (do - ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch) + ;; INCLUDE-NEXT: (block $tryend + ;; INCLUDE-NEXT: (try_table (catch_all $tryend) + ;; INCLUDE-NEXT: (call $return-call-throw-and-catch) ;; INCLUDE-NEXT: ) - ;; INCLUDE-NEXT: (catch_all - ;; INCLUDE-NEXT: (nop) + ;; INCLUDE-NEXT: ) + ;; INCLUDE-NEXT: (block $tryend0 + ;; INCLUDE-NEXT: (try_table (catch_all $tryend0) + ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) - ;; INCLUDE-NEXT: (try - ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (block $tryend1 + ;; INCLUDE-NEXT: (try_table (catch_all $tryend1) ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch) ;; INCLUDE-NEXT: ) - ;; INCLUDE-NEXT: (catch_all - ;; INCLUDE-NEXT: (nop) - ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: (call $return-call-throw-and-catch) ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch) ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch) ;; INCLUDE-NEXT: ) (func $call-return-call-throw-and-catch - (try - (do - ;; Even though the body of the previous function is a try-catch_all, the + (block $tryend + (try_table (catch_all $tryend) + ;; Even though the body of the previous function has a catch_all, the ;; function still throws because of its return_call, so this cannot be - ;; optimized out, but once again the entire try-catch can be. + ;; optimized out, but once again the entire try_table could be. Again, + ;; this is something we do for `try` for not yet for `try_table`. (call $return-call-throw-and-catch) ) - (catch_all) ) - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This would be the same, except since it performs an indirect call, we ;; conservatively assume it could have any effect, so we can't optimize. (call $return-call-indirect-throw-and-catch) ) - (catch_all) ) - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; Same here. (call $return-call-ref-throw-and-catch) ) - (catch_all) ) ;; These cannot be optimized out at all. @@ -380,33 +360,29 @@ ) ;; WITHOUT: (func $call-unreachable-and-catch (type $void) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend + ;; WITHOUT-NEXT: (try_table (catch_all $tryend) ;; WITHOUT-NEXT: (call $unreachable) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; INCLUDE: (func $call-unreachable-and-catch (type $void) ;; INCLUDE-NEXT: (call $unreachable) ;; INCLUDE-NEXT: ) (func $call-unreachable-and-catch - (try - (do + (block $tryend + (try_table (catch_all $tryend) ;; This call has a non-throw effect. We can optimize away the try-catch ;; (since no exception can be thrown anyhow), but we must leave the ;; call. (call $unreachable) ) - (catch_all) ) ) ;; WITHOUT: (func $call-throw-or-unreachable-and-catch (type $2) (param $x i32) - ;; WITHOUT-NEXT: (try - ;; WITHOUT-NEXT: (do + ;; WITHOUT-NEXT: (block $tryend + ;; WITHOUT-NEXT: (try_table (catch_all $tryend) ;; WITHOUT-NEXT: (if ;; WITHOUT-NEXT: (local.get $x) ;; WITHOUT-NEXT: (then @@ -417,14 +393,11 @@ ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) - ;; WITHOUT-NEXT: (catch_all - ;; WITHOUT-NEXT: (nop) - ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; WITHOUT-NEXT: ) ;; INCLUDE: (func $call-throw-or-unreachable-and-catch (type $2) (param $x i32) - ;; INCLUDE-NEXT: (try - ;; INCLUDE-NEXT: (do + ;; INCLUDE-NEXT: (block $tryend + ;; INCLUDE-NEXT: (try_table (catch_all $tryend) ;; INCLUDE-NEXT: (if ;; INCLUDE-NEXT: (local.get $x) ;; INCLUDE-NEXT: (then @@ -435,16 +408,13 @@ ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) - ;; INCLUDE-NEXT: (catch_all - ;; INCLUDE-NEXT: (nop) - ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) ;; INCLUDE-NEXT: ) (func $call-throw-or-unreachable-and-catch (param $x i32) - ;; This try-catch-all's body will either call a throw or an unreachable. + ;; This try_table's body will either call a throw or an unreachable. ;; Since we have both possible effects, we cannot optimize anything here. - (try - (do + (block $tryend + (try_table (catch_all $tryend) (if (local.get $x) (then @@ -455,7 +425,6 @@ ) ) ) - (catch_all) ) ) diff --git a/test/lit/passes/gufa-eh.wast b/test/lit/passes/gufa-eh.wast new file mode 100644 index 00000000000..79265a31825 --- /dev/null +++ b/test/lit/passes/gufa-eh.wast @@ -0,0 +1,60 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: foreach %s %t wasm-opt -all --gufa -S -o - | filecheck %s + +(module + ;; CHECK: (type $0 (func (param i32))) + + ;; CHECK: (type $1 (func (result i32))) + + ;; CHECK: (type $2 (func)) + + ;; CHECK: (tag $e (param i32)) + (tag $e (param i32)) + + ;; CHECK: (func $try_table-target-block-is-not-unreachable (type $1) (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e $catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $try_table-target-block-is-not-unreachable (result i32) + ;; Ensure that try_table connects caught tags with their branch targets. + (block $catch (result i32) + (try_table (catch $e $catch) + (throw $e (i32.const 0)) + ) + ) + ) + + ;; CHECK: (func $try_table-materializes-exnref (type $2) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result exnref) + ;; CHECK-NEXT: (try_table (catch_all_ref $catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-materializes-exnref + ;; Ensure that catch_all_ref materializes a non-null exnref value. If we do + ;; not connect a non-null exnref value to the branch target, GUFA will think + ;; no value can possibly get out of that block, and will insert an + ;; unreachable instruction after the block. + (drop + (block $catch (result exnref) + (try_table (catch_all_ref $catch) + (throw $e (i32.const 0)) + ) + ) + ) + ) +) diff --git a/test/lit/passes/local-subtyping.wast b/test/lit/passes/local-subtyping.wast index 582c24f23c7..2985102e192 100644 --- a/test/lit/passes/local-subtyping.wast +++ b/test/lit/passes/local-subtyping.wast @@ -24,6 +24,9 @@ ;; CHECK: (import "out" "i64" (func $i64 (type $6) (result i64))) (import "out" "i64" (func $i64 (result i64))) + ;; CHECK: (tag $e-anyref (param anyref)) + (tag $e-anyref (param anyref)) + ;; Refinalization can find a more specific type, where the declared type was ;; not the optimal LUB. ;; CHECK: (func $refinalize (type $2) (param $x i32) @@ -80,7 +83,7 @@ ;; A simple case where a local has a single assignment that we can use as a ;; more specific type. A similar thing with a parameter, however, is not a ;; thing we can optimize. Also, ignore a local with zero assignments. - ;; CHECK: (func $simple-local-but-not-param (type $7) (param $x funcref) + ;; CHECK: (func $simple-local-but-not-param (type $8) (param $x funcref) ;; CHECK-NEXT: (local $y (ref $1)) ;; CHECK-NEXT: (local $unused funcref) ;; CHECK-NEXT: (local.set $x @@ -101,7 +104,7 @@ ) ) - ;; CHECK: (func $locals-with-multiple-assignments (type $8) (param $struct structref) + ;; CHECK: (func $locals-with-multiple-assignments (type $9) (param $struct structref) ;; CHECK-NEXT: (local $x eqref) ;; CHECK-NEXT: (local $y (ref i31)) ;; CHECK-NEXT: (local $z structref) @@ -568,4 +571,49 @@ (local.get $x) ) ) + + ;; CHECK: (func $try_table-catch-result (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result anyref) + ;; CHECK-NEXT: (try_table (catch $e-anyref $catch) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-catch-result + (drop + ;; Must not be refined to (result nullref). + (block $catch (result anyref) + (try_table (catch $e-anyref $catch) + (nop) + ) + (ref.null none) + ) + ) + ) + + ;; CHECK: (func $try_table-ref (type $0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result exnref) + ;; CHECK-NEXT: (try_table (catch_all_ref $catch) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null noexn) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $try_table-ref + (drop + ;; Must not be refined to nullexnref. + ;; An exnref comes from the catch_all_ref. + (block $catch (result exnref) + (try_table (catch_all_ref $catch) + (nop) + ) + (ref.null exn) + ) + ) + ) ) diff --git a/test/lit/passes/simplify-locals-eh-legacy.wast b/test/lit/passes/simplify-locals-eh-legacy.wast index 7b48707d41b..d7fb757769c 100644 --- a/test/lit/passes/simplify-locals-eh-legacy.wast +++ b/test/lit/passes/simplify-locals-eh-legacy.wast @@ -4,7 +4,7 @@ (module ;; CHECK: (tag $e-i32 (param i32)) (tag $e-i32 (param i32)) - ;; CHECK: (func $foo (type $2) (param $0 i32) (param $1 i32) + ;; CHECK: (func $foo (type $3) (param $0 i32) (param $1 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo (param i32 i32)) @@ -83,7 +83,7 @@ ) ) - ;; CHECK: (func $bar (type $3) (result i32) + ;; CHECK: (func $bar (type $1) (result i32) ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) (func $bar (result i32) (i32.const 3)) @@ -152,7 +152,7 @@ ) ) - ;; CHECK: (func $return-call-can-be-sinked-into-try (type $3) (result i32) + ;; CHECK: (func $return-call-can-be-sinked-into-try (type $1) (result i32) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (try (result i32) @@ -202,103 +202,4 @@ ) ) ) - - ;; CHECK: (func $equivalent-set-removal-call (type $1) (param $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (call $equivalent-set-removal-call - ;; CHECK-NEXT: (i32.const 2) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $equivalent-set-removal-call (param $0 i32) - (local $1 i32) - (local.set $1 (local.get $0)) - (drop (local.get $0)) - (drop (local.get $1)) - ;; Even with EH enabled we can look past the call and optimize the final 1 - ;; to a 0, since they contain the same (and while the call might branch, - ;; such a branch does not cause a problem here, as if we branch we just - ;; don't reach the change later down). - (call $equivalent-set-removal-call - (i32.const 2) - ) - (drop (local.get $0)) - (drop (local.get $1)) - ) - - ;; CHECK: (func $equivalent-set-removal-if (type $2) (param $p i32) (param $0 i32) - ;; CHECK-NEXT: (local $1 i32) - ;; CHECK-NEXT: (nop) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (local.get $p) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (else - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $equivalent-set-removal-if (param $p i32) (param $0 i32) - (local $1 i32) - (local.set $1 (local.get $0)) - (drop (local.get $0)) - ;; This local.get of 1 can be of 0. - (drop (local.get $1)) - (if - (local.get $p) - (then - (block - ;; We also optimize in this block, which is adjacent to the code before - ;; us. It is valid to optimize the 1 to a 0 here, as it is dominated by - ;; the code earlier. - (drop (local.get $0)) - (drop (local.get $1)) - ) - ) - (else - (block - ;; We could also optimize here, but atm just look at code adjacent to - ;; its dominator. TODO - (drop (local.get $0)) - (drop (local.get $1)) - ) - ) - ) - ;; As in the else, this could be optimized. TODO - (drop (local.get $0)) - (drop (local.get $1)) - ) ) diff --git a/test/lit/passes/simplify-locals-eh.wast b/test/lit/passes/simplify-locals-eh.wast new file mode 100644 index 00000000000..f455bd4e5a0 --- /dev/null +++ b/test/lit/passes/simplify-locals-eh.wast @@ -0,0 +1,226 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --simplify-locals -all -S -o - | filecheck %s + +(module + ;; CHECK: (tag $e-i32 (param i32)) + (tag $e-i32 (param i32)) + + ;; CHECK: (func $bar (type $1) (result i32) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + (func $bar (result i32) (i32.const 3)) + + ;; CHECK: (func $call-cannot-be-sinked-into-try_table (type $2) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (call $bar) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e-i32 $catch) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $call-cannot-be-sinked-into-try_table (local $0 i32) + (drop + ;; This local.tee should NOT be sinked into 'try_table' below, because it + ;; may throw + (local.tee $0 (call $bar)) + ) + (block $tryend + (drop + (block $catch (result i32) + (try_table (catch $e-i32 $catch) + (drop (local.get $0)) + ) + (br $tryend) + ) + ) + ) + ) + + ;; CHECK: (func $non-call-can-be-sinked-into-try_table (type $2) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (block $tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e-i32 $catch) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $non-call-can-be-sinked-into-try_table (local $0 i32) + (drop + ;; This local.tee can be sinked into 'try_table' below, because it cannot + ;; throw + (local.tee $0 (i32.const 3)) + ) + (block $tryend + (drop + (block $catch (result i32) + (try_table (catch $e-i32 $catch) + (drop (local.get $0)) + ) + (br $tryend) + ) + ) + ) + ) + + ;; CHECK: (func $return-call-can-be-sinked-into-try_table (type $1) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (block $tryend (result i32) + ;; CHECK-NEXT: (try_table (result i32) (catch $e-i32 $tryend) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return_call $return-call-can-be-sinked-into-try_table) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-call-can-be-sinked-into-try_table (result i32) + (local $0 i32) + (drop + ;; This cannot throw either, so it can be sunk. Wrap the return_call in an + ;; if so the whole expression does not return unconditionally. + (local.tee $0 + (if (result i32) + (i32.const 0) + (then + (return_call $return-call-can-be-sinked-into-try_table) + ) + (else + (i32.const 1) + ) + ) + ) + ) + (block $tryend (result i32) + (try_table (result i32) (catch $e-i32 $tryend) + (drop (local.get $0)) + (i32.const 0) + ) + ) + ) + + ;; CHECK: (func $equivalent-set-removal-call (type $0) (param $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (call $equivalent-set-removal-call + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $equivalent-set-removal-call (param $0 i32) + (local $1 i32) + (local.set $1 (local.get $0)) + (drop (local.get $0)) + (drop (local.get $1)) + ;; Even with EH enabled we can look past the call and optimize the final 1 + ;; to a 0, since they contain the same (and while the call might branch, + ;; such a branch does not cause a problem here, as if we branch we just + ;; don't reach the change later down). + (call $equivalent-set-removal-call + (i32.const 2) + ) + (drop (local.get $0)) + (drop (local.get $1)) + ) + + ;; CHECK: (func $equivalent-set-removal-if (type $3) (param $p i32) (param $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $p) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $equivalent-set-removal-if (param $p i32) (param $0 i32) + (local $1 i32) + (local.set $1 (local.get $0)) + (drop (local.get $0)) + ;; This local.get of 1 can be of 0. + (drop (local.get $1)) + (if + (local.get $p) + (then + (block + ;; We also optimize in this block, which is adjacent to the code before + ;; us. It is valid to optimize the 1 to a 0 here, as it is dominated by + ;; the code earlier. + (drop (local.get $0)) + (drop (local.get $1)) + ) + ) + (else + (block + ;; We could also optimize here, but atm just look at code adjacent to + ;; its dominator. TODO + (drop (local.get $0)) + (drop (local.get $1)) + ) + ) + ) + ;; As in the else, this could be optimized. TODO + (drop (local.get $0)) + (drop (local.get $1)) + ) +) diff --git a/test/lit/passes/vacuum-eh-legacy.wast b/test/lit/passes/vacuum-eh-legacy.wast index 125475e26f5..0eb53bb56e3 100644 --- a/test/lit/passes/vacuum-eh-legacy.wast +++ b/test/lit/passes/vacuum-eh-legacy.wast @@ -6,14 +6,13 @@ (type $void (func)) ;; CHECK: (table $t 0 funcref) + (table $t 0 funcref) ;; CHECK: (tag $e (param i32)) (tag $e (param i32)) ;; CHECK: (tag $e2 (param i32)) (tag $e2 (param i32)) - (table $t 0 funcref) - ;; CHECK: (func $try-test (type $void) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/vacuum-eh.wast b/test/lit/passes/vacuum-eh.wast new file mode 100644 index 00000000000..ec62f3c58df --- /dev/null +++ b/test/lit/passes/vacuum-eh.wast @@ -0,0 +1,235 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --vacuum -all -S -o - | filecheck %s + +(module + ;; CHECK: (type $void (func)) + (type $void (func)) + + ;; CHECK: (table $t 0 funcref) + (table $t 0 funcref) + + ;; CHECK: (tag $e (param i32)) + (tag $e (param i32)) + ;; CHECK: (tag $e2 (param i32)) + (tag $e2 (param i32)) + + ;; CHECK: (func $try_table-test (type $void) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $try_table-test + ;; When try_table body does not throw, the try_table can be replaced with + ;; its body + (block $tryend + (drop + (block $catch (result i32) + (try_table (catch $e $catch) + (drop (i32.const 0)) + ) + (br $tryend) + ) + ) + ) + ) + + ;; CHECK: (func $inner-try_table-catch_all-test (type $2) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $inner-catch + ;; CHECK-NEXT: (try_table (catch_all $inner-catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + (func $inner-try_table-catch_all-test (result i32) + (local $0 i32) + ;; The exception thrown in the inner try_table is caught by the inner + ;; catch_all, so the outer try_table body does not throw and the outer + ;; try_table can be removed + (block $outer-tryend + (drop + (block $outer-catch (result i32) + (try_table (catch $e $outer-catch) + (block $inner-catch + (try_table (catch_all $inner-catch) + (throw $e (i32.const 0)) + ) + (unreachable) + ) + (return (i32.const 1)) + ) + (br $outer-tryend) + ) + ) + ) + (i32.const 2) + ) + + ;; CHECK: (func $inner-try_table-catch-test (type $void) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $outer-tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $outer-catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e $outer-catch) + ;; CHECK-NEXT: (block $inner-tryend + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $inner-catch (result i32) + ;; CHECK-NEXT: (try_table (catch $e $inner-catch) + ;; CHECK-NEXT: (throw $e2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $outer-tryend) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $inner-try_table-catch-test (local $0 i32) + ;; The exception thrown in the inner try_table will not be caught by the + ;; inner catch, so the outer try_table cannot be removed. + (block $outer-tryend + (drop + (block $outer-catch (result i32) + (try_table (catch $e $outer-catch) + (block $inner-tryend + (drop + (block $inner-catch (result i32) + (try_table (catch $e $inner-catch) + (throw $e2 (i32.const 0)) + ) + (br $inner-tryend) + ) + ) + (local.set $0 (i32.const 1)) + ) + ) + (br $outer-tryend) + ) + ) + ) + ) + + ;; CHECK: (func $trivial-catch-all-of-throw (type $void) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $catch + ;; CHECK-NEXT: (try_table (catch_all $catch) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $catch0 + ;; CHECK-NEXT: (try_table (catch_all $catch0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $trivial-catch-all-of-throw (local $0 i32) + ;; This try_table's body throws, but the catch_all catches it, so the entire + ;; try_table could be optimized out. We do this for `try` but not yet for + ;; `try_table`. + (block $catch + (try_table (catch_all $catch) + (throw $e (i32.const 0)) + ) + ) + ;; Here we also have a possible trap, so we can't do it. + (block $catch + (try_table (catch_all $catch) + (if + (local.get $0) + (then + (throw $e (i32.const 0)) + ) + (else + (unreachable) + ) + ) + ) + ) + ) + + ;; CHECK: (func $throw (type $void) + ;; CHECK-NEXT: (throw $e + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $throw + ;; Helper for the tail call tests below. + (throw $e + (i32.const 0) + ) + ) + + ;; CHECK: (func $return-call-catch (type $void) + ;; CHECK-NEXT: (return_call $throw) + ;; CHECK-NEXT: ) + (func $return-call-catch + (block $catch + (try_table (catch_all $catch) + ;; This returns before it throws, so we can optimize out the surrounding + ;; try_table. + (return_call $throw) + ) + ) + ) + + ;; CHECK: (func $return-call-indirect-catch (type $void) + ;; CHECK-NEXT: (return_call_indirect $t (type $void) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-call-indirect-catch + (block $catch + (try_table (catch_all $catch) + ;; This returns before it throws, so we can optimize out the surrounding + ;; try_table. + (return_call_indirect + (i32.const 0) + ) + ) + ) + ) + + ;; CHECK: (func $return-call-ref-catch (type $void) + ;; CHECK-NEXT: (return_call_ref $void + ;; CHECK-NEXT: (ref.func $throw) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-call-ref-catch + (block $catch + (try_table (catch_all $catch) + ;; This returns before it throws, so we can optimize out the surrounding + ;; try_table. + (return_call_ref $void + (ref.func $throw) + ) + ) + ) + ) +) diff --git a/test/spec/exception-handling.wast b/test/spec/exception-handling.wast index 95350b77b80..c6da12eefa8 100644 --- a/test/spec/exception-handling.wast +++ b/test/spec/exception-handling.wast @@ -1,3 +1,153 @@ +(module + (tag $e-v) + (tag $e-i32 (param i32)) + (tag $e-f32 (param f32)) + (tag $e-i32-f32 (param i32 f32)) + + (func $throw_single_value (export "throw_single_value") + (throw $e-i32 (i32.const 5)) + ) + + (func (export "throw_multiple_values") + (throw $e-i32-f32 (i32.const 3) (f32.const 3.5)) + ) + + (func (export "try_table_nothrow") (result i32) + (block $tryend (result i32) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result i32) (catch $e-i32 $catch) + (i32.const 3) + ) + ) + ) + ) + (i32.const 0) + ) + ) + + (func (export "try_table_throw_catch") (result i32) + (block $tryend (result i32) + (drop + (block $catch (result i32) + (br $tryend + (try_table (result i32) (catch $e-i32 $catch) + (throw $e-i32 (i32.const 5)) + ) + ) + ) + ) + (i32.const 3) + ) + ) + + (func (export "try_table_throw_nocatch") (result i32) + (block $tryend (result i32) + (drop + (block $catch (result f32) + (br $tryend + (try_table (result i32) (catch $e-f32 $catch) + (throw $e-i32 (i32.const 5)) + ) + ) + ) + ) + (i32.const 3) + ) + ) + + (func (export "try_table_throw_catchall") (result i32) + (block $tryend (result i32) + (block $catch-all + (drop + (block $catch-f32 (result f32) + (br $tryend + (try_table (result i32) (catch $e-f32 $catch-f32) (catch_all $catch-all) + (throw $e-i32 (i32.const 5)) + ) + ) + ) + ) + (br $tryend (i32.const 4)) + ) + (i32.const 3) + ) + ) + + (func (export "try_table_call_catch") (result i32) + (block $tryend (result i32) + (block $catch (result i32) + (br $tryend + (try_table (result i32) (catch $e-i32 $catch) + (call $throw_single_value) + (unreachable) + ) + ) + ) + ) + ) + + (func (export "try_table_throw_multivalue_catch") (result i32) (local $x (tuple i32 f32)) + (block $tryend (result i32) + (local.set $x + (block $catch (result i32) (result f32) + (br $tryend + (try_table (result i32) (catch $e-i32-f32 $catch) + (throw $e-i32-f32 (i32.const 5) (f32.const 1.5)) + ) + ) + ) + ) + (tuple.extract 2 0 + (local.get $x) + ) + ) + ) + + (func (export "try_table_throw_throw_ref") (local $x (tuple i32 exnref)) + (block $tryend + (local.set $x + (block $catch (result i32) (result exnref) + (try_table (catch_ref $e-i32 $catch) + (throw $e-i32 (i32.const 5)) + ) + (br $tryend) + ) + ) + (throw_ref + (tuple.extract 2 1 + (local.get $x) + ) + ) + ) + ) + + (func (export "try_table_call_throw_ref") + (block $tryend + (throw_ref + (block $catch (result exnref) + (try_table (catch_all_ref $catch) + (call $throw_single_value) + ) + (br $tryend) + ) + ) + ) + ) +) + +(assert_exception (invoke "throw_single_value")) +(assert_exception (invoke "throw_multiple_values")) +(assert_return (invoke "try_table_nothrow") (i32.const 3)) +(assert_return (invoke "try_table_throw_catch") (i32.const 3)) +(assert_exception (invoke "try_table_throw_nocatch")) +(assert_return (invoke "try_table_throw_catchall") (i32.const 3)) +(assert_return (invoke "try_table_call_catch") (i32.const 5)) +(assert_return (invoke "try_table_throw_multivalue_catch") (i32.const 5)) +(assert_exception (invoke "try_table_throw_throw_ref")) +(assert_exception (invoke "try_table_call_throw_ref")) + (assert_invalid (module (tag $e-i32 (param i32)) diff --git a/test/spec/return_call_eh-legacy.wast b/test/spec/return_call_eh-legacy.wast new file mode 100644 index 00000000000..8b0b54ee0be --- /dev/null +++ b/test/spec/return_call_eh-legacy.wast @@ -0,0 +1,35 @@ +;; Test the combination of 'return_call' with legacy exception handling. + +(module + (tag $t) + + (func $test (export "test") (result i32) + (try (result i32) + (do + (call $return-call-in-try) + ) + (catch_all + ;; Catch the exception thrown from $return-callee. + (i32.const 42) + ) + ) + + ) + + (func $return-call-in-try (result i32) + (try (result i32) + (do + (return_call $return-callee) + ) + (catch_all + (unreachable) + ) + ) + ) + + (func $return-callee (result i32) + (throw $t) + ) +) + +(assert_return (invoke "test") (i32.const 42)) diff --git a/test/spec/return_call_eh.wast b/test/spec/return_call_eh.wast index e85fdf7c6a2..11950c4b43e 100644 --- a/test/spec/return_call_eh.wast +++ b/test/spec/return_call_eh.wast @@ -1,34 +1,31 @@ -;; Test the combination of 'return_call' with exception handling +;; Test the combination of 'return_call' with exception handling. (module (tag $t) (func $test (export "test") (result i32) - (try (result i32) - (do - (call $return-call-in-try) - ) - (catch_all - ;; Catch the exception thrown from $return-callee - (i32.const 42) + (block $catch + (return + (try_table (result i32) (catch_all $catch) + (call $return-call-in-try_table) + ) ) ) - + ;; Catch the exception thrown from $return-callee. + (i32.const 42) ) - (func $return-call-in-try (result i32) - (try (result i32) - (do + (func $return-call-in-try_table (result i32) + (block $catch + (try_table (catch_all $catch) (return_call $return-callee) ) - (catch_all - (unreachable) - ) ) + (unreachable) ) (func $return-callee (result i32) - (throw $t) + (throw $t) ) ) From 435eeead73cf02a6fb5bc7d7a36dd45b8d700cb2 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 20 Aug 2024 17:16:44 -0700 Subject: [PATCH 531/553] Add the upstream spec testsuite as a submodule (#6853) Run the upstream tests by default, except for a large list of them that do not successfully run. Remove the local version of those that do successfully run where the local version is entirely subsumed by the upstream version. --- .gitmodules | 3 + scripts/test/shared.py | 96 +- scripts/test/wasm2js.py | 9 +- src/tools/wasm2js.cpp | 3 + test/spec/address64.wast | 582 ------ test/spec/align64.wast | 866 -------- test/spec/br.wast | 606 ------ test/spec/call.wast | 463 ----- test/spec/call_ref.wast | 136 -- test/spec/custom.wast | 120 -- test/spec/endianness.wast | 217 -- test/spec/endianness64.wast | 217 -- test/spec/exports.wast | 198 -- test/spec/f32_bitwise.wast | 376 ---- test/spec/f32_cmp.wast | 2422 ---------------------- test/spec/f64_bitwise.wast | 376 ---- test/spec/f64_cmp.wast | 2422 ---------------------- test/spec/float_literals.wast | 507 ----- test/spec/float_memory.wast | 157 -- test/spec/float_memory64.wast | 157 -- test/spec/forward.wast | 20 - test/spec/func_ptrs.wast | 106 - test/spec/i32.wast | 958 --------- test/spec/i64.wast | 455 ----- test/spec/inline-module.wast | 1 - test/spec/int_exprs.wast | 350 ---- test/spec/int_literals.wast | 151 -- test/spec/labels.wast | 328 --- test/spec/left-to-right.wast | 233 --- test/spec/load.wast | 567 ------ test/spec/load64.wast | 567 ------ test/spec/local_get.wast | 226 --- test/spec/local_set.wast | 362 ---- test/spec/local_tee.wast | 639 ------ test/spec/memory_grow.wast | 355 ---- test/spec/memory_grow64.wast | 95 - test/spec/memory_redundancy.wast | 65 - test/spec/memory_redundancy64.wast | 65 - test/spec/memory_size.wast | 85 - test/spec/memory_trap.wast | 270 --- test/spec/memory_trap64.wast | 269 --- test/spec/names.wast | 1107 ---------- test/spec/nop.wast | 426 ---- test/spec/ref_as_non_null.wast | 28 - test/spec/return.wast | 479 ----- test/spec/return_call.wast | 202 -- test/spec/return_call_ref.wast | 377 ---- test/spec/skip-stack-guard-page.wast | 2284 --------------------- test/spec/stack.wast | 239 --- test/spec/start.wast | 105 - test/spec/store.wast | 417 ---- test/spec/switch.wast | 150 -- test/spec/table_copy.wast | 2216 -------------------- test/spec/table_size.wast | 89 - test/spec/testsuite | 1 + test/spec/traps.wast | 91 - test/spec/type.wast | 50 - test/spec/unreachable.wast | 304 --- test/spec/unwind.wast | 267 --- test/spec/utf8-custom-section-id.wast | 1792 ----------------- test/spec/utf8-import-field.wast | 2672 ------------------------- test/spec/utf8-import-module.wast | 2672 ------------------------- test/spec/utf8-invalid-encoding.wast | 176 -- test/wasm2js/i32.2asm.js | 56 +- 64 files changed, 141 insertions(+), 32159 deletions(-) delete mode 100644 test/spec/address64.wast delete mode 100644 test/spec/align64.wast delete mode 100644 test/spec/br.wast delete mode 100644 test/spec/call.wast delete mode 100644 test/spec/call_ref.wast delete mode 100644 test/spec/custom.wast delete mode 100644 test/spec/endianness.wast delete mode 100644 test/spec/endianness64.wast delete mode 100644 test/spec/exports.wast delete mode 100644 test/spec/f32_bitwise.wast delete mode 100644 test/spec/f32_cmp.wast delete mode 100644 test/spec/f64_bitwise.wast delete mode 100644 test/spec/f64_cmp.wast delete mode 100644 test/spec/float_literals.wast delete mode 100644 test/spec/float_memory.wast delete mode 100644 test/spec/float_memory64.wast delete mode 100644 test/spec/forward.wast delete mode 100644 test/spec/func_ptrs.wast delete mode 100644 test/spec/i32.wast delete mode 100644 test/spec/i64.wast delete mode 100644 test/spec/inline-module.wast delete mode 100644 test/spec/int_exprs.wast delete mode 100644 test/spec/int_literals.wast delete mode 100644 test/spec/labels.wast delete mode 100644 test/spec/left-to-right.wast delete mode 100644 test/spec/load.wast delete mode 100644 test/spec/load64.wast delete mode 100644 test/spec/local_get.wast delete mode 100644 test/spec/local_set.wast delete mode 100644 test/spec/local_tee.wast delete mode 100644 test/spec/memory_grow.wast delete mode 100644 test/spec/memory_grow64.wast delete mode 100644 test/spec/memory_redundancy.wast delete mode 100644 test/spec/memory_redundancy64.wast delete mode 100644 test/spec/memory_size.wast delete mode 100644 test/spec/memory_trap.wast delete mode 100644 test/spec/memory_trap64.wast delete mode 100644 test/spec/names.wast delete mode 100644 test/spec/nop.wast delete mode 100644 test/spec/ref_as_non_null.wast delete mode 100644 test/spec/return.wast delete mode 100644 test/spec/return_call.wast delete mode 100644 test/spec/return_call_ref.wast delete mode 100644 test/spec/skip-stack-guard-page.wast delete mode 100644 test/spec/stack.wast delete mode 100644 test/spec/start.wast delete mode 100644 test/spec/store.wast delete mode 100644 test/spec/switch.wast delete mode 100644 test/spec/table_copy.wast delete mode 100644 test/spec/table_size.wast create mode 160000 test/spec/testsuite delete mode 100644 test/spec/traps.wast delete mode 100644 test/spec/type.wast delete mode 100644 test/spec/unreachable.wast delete mode 100644 test/spec/unwind.wast delete mode 100644 test/spec/utf8-custom-section-id.wast delete mode 100644 test/spec/utf8-import-field.wast delete mode 100644 test/spec/utf8-import-module.wast delete mode 100644 test/spec/utf8-invalid-encoding.wast diff --git a/.gitmodules b/.gitmodules index 5a4e85a5111..671d8041992 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "third_party/googletest"] path = third_party/googletest url = https://github.com/google/googletest.git +[submodule "test/spec/testsuite"] + path = test/spec/testsuite + url = https://github.com/WebAssembly/testsuite.git diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 91612a8d9d9..08aebcdd3a8 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -386,7 +386,7 @@ def get_tests(test_dir, extensions=[], recursive=False): if options.spec_tests: options.spec_tests = [os.path.abspath(t) for t in options.spec_tests] else: - options.spec_tests = get_tests(get_test_dir('spec'), ['.wast']) + options.spec_tests = get_tests(get_test_dir('spec'), ['.wast'], recursive=True) os.chdir(options.out_dir) @@ -411,12 +411,102 @@ def get_tests(test_dir, extensions=[], recursive=False): # Test invalid 'elem.wast', ] +SPEC_TESTSUITE_TESTS_TO_SKIP = [ + 'address.wast', + 'align.wast', + 'binary-leb128.wast', + 'binary.wast', + 'block.wast', + 'br_table.wast', + 'bulk.wast', + 'comments.wast', + 'const.wast', + 'conversions.wast', + 'data.wast', + 'elem.wast', + 'f32.wast', + 'f64.wast', + 'fac.wast', + 'float_exprs.wast', + 'float_misc.wast', + 'func.wast', + 'global.wast', + 'if.wast', + 'imports.wast', + 'linking.wast', + 'loop.wast', + 'memory.wast', + 'annotations.wast', + 'id.wast', + 'throw.wast', + 'try_catch.wast', + 'tag.wast', + 'throw_ref.wast', + 'try_table.wast', + 'br_on_non_null.wast', + 'br_on_null.wast', + 'local_init.wast', + 'ref_func.wast', + 'ref_is_null.wast', + 'ref_null.wast', + 'return_call_indirect.wast', + 'select.wast', + 'table.wast', + 'type-equivalence.wast', + 'unreached-invalid.wast', + 'array.wast', + 'array_init_elem.wast', + 'br_if.wast', + 'br_on_cast.wast', + 'br_on_cast_fail.wast', + 'extern.wast', + 'i31.wast', + 'ref_cast.wast', + 'ref_test.wast', + 'struct.wast', + 'type-rec.wast', + 'type-subtyping.wast', + 'call_indirect.wast', + 'memory64.wast', + 'table_fill.wast', + 'table_get.wast', + 'table_grow.wast', + 'table_init.wast', + 'table_set.wast', + 'imports0.wast', + 'imports2.wast', + 'imports3.wast', + 'linking0.wast', + 'linking3.wast', + 'i16x8_relaxed_q15mulr_s.wast', + 'i32x4_relaxed_trunc.wast', + 'i8x16_relaxed_swizzle.wast', + 'relaxed_dot_product.wast', + 'relaxed_laneselect.wast', + 'relaxed_madd_nmadd.wast', + 'relaxed_min_max.wast', + 'simd_address.wast', + 'simd_boolean.wast', + 'simd_const.wast', + 'simd_conversions.wast', + 'simd_f32x4.wast', + 'simd_f32x4_arith.wast', + 'simd_f32x4_rounding.wast', + 'simd_f64x2.wast', + 'simd_f64x2_arith.wast', + 'simd_f64x2_rounding.wast', + 'simd_i32x4_cmp.wast', # UBSan error on integer overflow + 'simd_i32x4_arith2.wast', # UBSan error on integer overflow + 'simd_i32x4_dot_i16x8.wast', # UBSan error on integer overflow + 'token.wast', +] options.spec_tests = [t for t in options.spec_tests if os.path.basename(t) not - in SPEC_TESTS_TO_SKIP] - + in (SPEC_TESTSUITE_TESTS_TO_SKIP if 'testsuite' in t + else SPEC_TESTS_TO_SKIP)] # check utilities + def binary_format_check(wast, verify_final_result=True, wasm_as_args=['-g'], binary_suffix='.fromBinary'): # checks we can convert the wast to binary and back diff --git a/scripts/test/wasm2js.py b/scripts/test/wasm2js.py index ec2c98124b2..f7c9bd47909 100644 --- a/scripts/test/wasm2js.py +++ b/scripts/test/wasm2js.py @@ -27,7 +27,10 @@ wasm2js_tests = shared.get_tests(shared.get_test_dir('wasm2js'), ['.wast']) assert_tests = ['wasm2js.wast.asserts'] # These tests exercise functionality not supported by wasm2js -wasm2js_blacklist = ['empty_imported_table.wast'] +wasm2js_skipped_tests = [ + 'empty_imported_table.wast', + 'br.wast', # depends on multivalue +] def check_for_stale_files(): @@ -52,7 +55,7 @@ def test_wasm2js_output(): for opt in (0, 1): for t in basic_tests + spec_tests + wasm2js_tests: basename = os.path.basename(t) - if basename in wasm2js_blacklist: + if basename in wasm2js_skipped_tests: continue asm = basename.replace('.wast', '.2asm.js') @@ -158,7 +161,7 @@ def update_wasm2js_tests(): if not wasm.endswith('.wast'): continue - if os.path.basename(wasm) in wasm2js_blacklist: + if os.path.basename(wasm) in wasm2js_skipped_tests: continue asm = os.path.basename(wasm).replace('.wast', '.2asm.js') diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index feba358c483..286f8989079 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -809,6 +809,9 @@ void AssertionEmitter::emit() { // Skip other action assertions. continue; } + } else if (std::get_if(assn)) { + // Skip module assertions + continue; } else { Fatal() << "unsupported assertion on line " << script[i].line; } diff --git a/test/spec/address64.wast b/test/spec/address64.wast deleted file mode 100644 index 29771ae776c..00000000000 --- a/test/spec/address64.wast +++ /dev/null @@ -1,582 +0,0 @@ -;; Load i32 data with different offset/align arguments - -(module - (memory i64 1) - (data (i64.const 0) "abcdefghijklmnopqrstuvwxyz") - - (func (export "8u_good1") (param $i i64) (result i32) - (i32.load8_u offset=0 (local.get $i)) ;; 97 'a' - ) - (func (export "8u_good2") (param $i i64) (result i32) - (i32.load8_u align=1 (local.get $i)) ;; 97 'a' - ) - (func (export "8u_good3") (param $i i64) (result i32) - (i32.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b' - ) - (func (export "8u_good4") (param $i i64) (result i32) - (i32.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c' - ) - (func (export "8u_good5") (param $i i64) (result i32) - (i32.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z' - ) - - (func (export "8s_good1") (param $i i64) (result i32) - (i32.load8_s offset=0 (local.get $i)) ;; 97 'a' - ) - (func (export "8s_good2") (param $i i64) (result i32) - (i32.load8_s align=1 (local.get $i)) ;; 97 'a' - ) - (func (export "8s_good3") (param $i i64) (result i32) - (i32.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b' - ) - (func (export "8s_good4") (param $i i64) (result i32) - (i32.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c' - ) - (func (export "8s_good5") (param $i i64) (result i32) - (i32.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z' - ) - - (func (export "16u_good1") (param $i i64) (result i32) - (i32.load16_u offset=0 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16u_good2") (param $i i64) (result i32) - (i32.load16_u align=1 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16u_good3") (param $i i64) (result i32) - (i32.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc' - ) - (func (export "16u_good4") (param $i i64) (result i32) - (i32.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd' - ) - (func (export "16u_good5") (param $i i64) (result i32) - (i32.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0' - ) - - (func (export "16s_good1") (param $i i64) (result i32) - (i32.load16_s offset=0 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16s_good2") (param $i i64) (result i32) - (i32.load16_s align=1 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16s_good3") (param $i i64) (result i32) - (i32.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc' - ) - (func (export "16s_good4") (param $i i64) (result i32) - (i32.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd' - ) - (func (export "16s_good5") (param $i i64) (result i32) - (i32.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0' - ) - - (func (export "32_good1") (param $i i64) (result i32) - (i32.load offset=0 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32_good2") (param $i i64) (result i32) - (i32.load align=1 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32_good3") (param $i i64) (result i32) - (i32.load offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' - ) - (func (export "32_good4") (param $i i64) (result i32) - (i32.load offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' - ) - (func (export "32_good5") (param $i i64) (result i32) - (i32.load offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' - ) - - (func (export "8u_bad") (param $i i64) - (drop (i32.load8_u offset=4294967295 (local.get $i))) - ) - (func (export "8s_bad") (param $i i64) - (drop (i32.load8_s offset=4294967295 (local.get $i))) - ) - (func (export "16u_bad") (param $i i64) - (drop (i32.load16_u offset=4294967295 (local.get $i))) - ) - (func (export "16s_bad") (param $i i64) - (drop (i32.load16_s offset=4294967295 (local.get $i))) - ) - (func (export "32_bad") (param $i i64) - (drop (i32.load offset=4294967295 (local.get $i))) - ) -) - -(assert_return (invoke "8u_good1" (i64.const 0)) (i32.const 97)) -(assert_return (invoke "8u_good2" (i64.const 0)) (i32.const 97)) -(assert_return (invoke "8u_good3" (i64.const 0)) (i32.const 98)) -(assert_return (invoke "8u_good4" (i64.const 0)) (i32.const 99)) -(assert_return (invoke "8u_good5" (i64.const 0)) (i32.const 122)) - -(assert_return (invoke "8s_good1" (i64.const 0)) (i32.const 97)) -(assert_return (invoke "8s_good2" (i64.const 0)) (i32.const 97)) -(assert_return (invoke "8s_good3" (i64.const 0)) (i32.const 98)) -(assert_return (invoke "8s_good4" (i64.const 0)) (i32.const 99)) -(assert_return (invoke "8s_good5" (i64.const 0)) (i32.const 122)) - -(assert_return (invoke "16u_good1" (i64.const 0)) (i32.const 25185)) -(assert_return (invoke "16u_good2" (i64.const 0)) (i32.const 25185)) -(assert_return (invoke "16u_good3" (i64.const 0)) (i32.const 25442)) -(assert_return (invoke "16u_good4" (i64.const 0)) (i32.const 25699)) -(assert_return (invoke "16u_good5" (i64.const 0)) (i32.const 122)) - -(assert_return (invoke "16s_good1" (i64.const 0)) (i32.const 25185)) -(assert_return (invoke "16s_good2" (i64.const 0)) (i32.const 25185)) -(assert_return (invoke "16s_good3" (i64.const 0)) (i32.const 25442)) -(assert_return (invoke "16s_good4" (i64.const 0)) (i32.const 25699)) -(assert_return (invoke "16s_good5" (i64.const 0)) (i32.const 122)) - -(assert_return (invoke "32_good1" (i64.const 0)) (i32.const 1684234849)) -(assert_return (invoke "32_good2" (i64.const 0)) (i32.const 1684234849)) -(assert_return (invoke "32_good3" (i64.const 0)) (i32.const 1701077858)) -(assert_return (invoke "32_good4" (i64.const 0)) (i32.const 1717920867)) -(assert_return (invoke "32_good5" (i64.const 0)) (i32.const 122)) - -(assert_return (invoke "8u_good1" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8u_good2" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8u_good3" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8u_good4" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8u_good5" (i64.const 65507)) (i32.const 0)) - -(assert_return (invoke "8s_good1" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8s_good2" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8s_good3" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8s_good4" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "8s_good5" (i64.const 65507)) (i32.const 0)) - -(assert_return (invoke "16u_good1" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16u_good2" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16u_good3" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16u_good4" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16u_good5" (i64.const 65507)) (i32.const 0)) - -(assert_return (invoke "16s_good1" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16s_good2" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16s_good3" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16s_good4" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "16s_good5" (i64.const 65507)) (i32.const 0)) - -(assert_return (invoke "32_good1" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "32_good2" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "32_good3" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "32_good4" (i64.const 65507)) (i32.const 0)) -(assert_return (invoke "32_good5" (i64.const 65507)) (i32.const 0)) - -(assert_return (invoke "8u_good1" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8u_good2" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8u_good3" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8u_good4" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8u_good5" (i64.const 65508)) (i32.const 0)) - -(assert_return (invoke "8s_good1" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8s_good2" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8s_good3" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8s_good4" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "8s_good5" (i64.const 65508)) (i32.const 0)) - -(assert_return (invoke "16u_good1" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16u_good2" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16u_good3" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16u_good4" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16u_good5" (i64.const 65508)) (i32.const 0)) - -(assert_return (invoke "16s_good1" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16s_good2" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16s_good3" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16s_good4" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "16s_good5" (i64.const 65508)) (i32.const 0)) - -(assert_return (invoke "32_good1" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "32_good2" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "32_good3" (i64.const 65508)) (i32.const 0)) -(assert_return (invoke "32_good4" (i64.const 65508)) (i32.const 0)) -(assert_trap (invoke "32_good5" (i64.const 65508)) "out of bounds memory access") - -(assert_trap (invoke "8u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "8s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "16u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "16s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "32_bad" (i64.const 0)) "out of bounds memory access") - -(assert_trap (invoke "8u_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "8s_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "16u_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "16s_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "32_bad" (i64.const 1)) "out of bounds memory access") - - -;; Load i64 data with different offset/align arguments - -(module - (memory i64 1) - (data (i64.const 0) "abcdefghijklmnopqrstuvwxyz") - - (func (export "8u_good1") (param $i i64) (result i64) - (i64.load8_u offset=0 (local.get $i)) ;; 97 'a' - ) - (func (export "8u_good2") (param $i i64) (result i64) - (i64.load8_u align=1 (local.get $i)) ;; 97 'a' - ) - (func (export "8u_good3") (param $i i64) (result i64) - (i64.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b' - ) - (func (export "8u_good4") (param $i i64) (result i64) - (i64.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c' - ) - (func (export "8u_good5") (param $i i64) (result i64) - (i64.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z' - ) - - (func (export "8s_good1") (param $i i64) (result i64) - (i64.load8_s offset=0 (local.get $i)) ;; 97 'a' - ) - (func (export "8s_good2") (param $i i64) (result i64) - (i64.load8_s align=1 (local.get $i)) ;; 97 'a' - ) - (func (export "8s_good3") (param $i i64) (result i64) - (i64.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b' - ) - (func (export "8s_good4") (param $i i64) (result i64) - (i64.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c' - ) - (func (export "8s_good5") (param $i i64) (result i64) - (i64.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z' - ) - - (func (export "16u_good1") (param $i i64) (result i64) - (i64.load16_u offset=0 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16u_good2") (param $i i64) (result i64) - (i64.load16_u align=1 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16u_good3") (param $i i64) (result i64) - (i64.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc' - ) - (func (export "16u_good4") (param $i i64) (result i64) - (i64.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd' - ) - (func (export "16u_good5") (param $i i64) (result i64) - (i64.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0' - ) - - (func (export "16s_good1") (param $i i64) (result i64) - (i64.load16_s offset=0 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16s_good2") (param $i i64) (result i64) - (i64.load16_s align=1 (local.get $i)) ;; 25185 'ab' - ) - (func (export "16s_good3") (param $i i64) (result i64) - (i64.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc' - ) - (func (export "16s_good4") (param $i i64) (result i64) - (i64.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd' - ) - (func (export "16s_good5") (param $i i64) (result i64) - (i64.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0' - ) - - (func (export "32u_good1") (param $i i64) (result i64) - (i64.load32_u offset=0 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32u_good2") (param $i i64) (result i64) - (i64.load32_u align=1 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32u_good3") (param $i i64) (result i64) - (i64.load32_u offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' - ) - (func (export "32u_good4") (param $i i64) (result i64) - (i64.load32_u offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' - ) - (func (export "32u_good5") (param $i i64) (result i64) - (i64.load32_u offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' - ) - - (func (export "32s_good1") (param $i i64) (result i64) - (i64.load32_s offset=0 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32s_good2") (param $i i64) (result i64) - (i64.load32_s align=1 (local.get $i)) ;; 1684234849 'abcd' - ) - (func (export "32s_good3") (param $i i64) (result i64) - (i64.load32_s offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' - ) - (func (export "32s_good4") (param $i i64) (result i64) - (i64.load32_s offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' - ) - (func (export "32s_good5") (param $i i64) (result i64) - (i64.load32_s offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' - ) - - (func (export "64_good1") (param $i i64) (result i64) - (i64.load offset=0 (local.get $i)) ;; 0x6867666564636261 'abcdefgh' - ) - (func (export "64_good2") (param $i i64) (result i64) - (i64.load align=1 (local.get $i)) ;; 0x6867666564636261 'abcdefgh' - ) - (func (export "64_good3") (param $i i64) (result i64) - (i64.load offset=1 align=1 (local.get $i)) ;; 0x6968676665646362 'bcdefghi' - ) - (func (export "64_good4") (param $i i64) (result i64) - (i64.load offset=2 align=2 (local.get $i)) ;; 0x6a69686766656463 'cdefghij' - ) - (func (export "64_good5") (param $i i64) (result i64) - (i64.load offset=25 align=8 (local.get $i)) ;; 122 'z\0\0\0\0\0\0\0' - ) - - (func (export "8u_bad") (param $i i64) - (drop (i64.load8_u offset=4294967295 (local.get $i))) - ) - (func (export "8s_bad") (param $i i64) - (drop (i64.load8_s offset=4294967295 (local.get $i))) - ) - (func (export "16u_bad") (param $i i64) - (drop (i64.load16_u offset=4294967295 (local.get $i))) - ) - (func (export "16s_bad") (param $i i64) - (drop (i64.load16_s offset=4294967295 (local.get $i))) - ) - (func (export "32u_bad") (param $i i64) - (drop (i64.load32_u offset=4294967295 (local.get $i))) - ) - (func (export "32s_bad") (param $i i64) - (drop (i64.load32_s offset=4294967295 (local.get $i))) - ) - (func (export "64_bad") (param $i i64) - (drop (i64.load offset=4294967295 (local.get $i))) - ) -) - -(assert_return (invoke "8u_good1" (i64.const 0)) (i64.const 97)) -(assert_return (invoke "8u_good2" (i64.const 0)) (i64.const 97)) -(assert_return (invoke "8u_good3" (i64.const 0)) (i64.const 98)) -(assert_return (invoke "8u_good4" (i64.const 0)) (i64.const 99)) -(assert_return (invoke "8u_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "8s_good1" (i64.const 0)) (i64.const 97)) -(assert_return (invoke "8s_good2" (i64.const 0)) (i64.const 97)) -(assert_return (invoke "8s_good3" (i64.const 0)) (i64.const 98)) -(assert_return (invoke "8s_good4" (i64.const 0)) (i64.const 99)) -(assert_return (invoke "8s_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "16u_good1" (i64.const 0)) (i64.const 25185)) -(assert_return (invoke "16u_good2" (i64.const 0)) (i64.const 25185)) -(assert_return (invoke "16u_good3" (i64.const 0)) (i64.const 25442)) -(assert_return (invoke "16u_good4" (i64.const 0)) (i64.const 25699)) -(assert_return (invoke "16u_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "16s_good1" (i64.const 0)) (i64.const 25185)) -(assert_return (invoke "16s_good2" (i64.const 0)) (i64.const 25185)) -(assert_return (invoke "16s_good3" (i64.const 0)) (i64.const 25442)) -(assert_return (invoke "16s_good4" (i64.const 0)) (i64.const 25699)) -(assert_return (invoke "16s_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "32u_good1" (i64.const 0)) (i64.const 1684234849)) -(assert_return (invoke "32u_good2" (i64.const 0)) (i64.const 1684234849)) -(assert_return (invoke "32u_good3" (i64.const 0)) (i64.const 1701077858)) -(assert_return (invoke "32u_good4" (i64.const 0)) (i64.const 1717920867)) -(assert_return (invoke "32u_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "32s_good1" (i64.const 0)) (i64.const 1684234849)) -(assert_return (invoke "32s_good2" (i64.const 0)) (i64.const 1684234849)) -(assert_return (invoke "32s_good3" (i64.const 0)) (i64.const 1701077858)) -(assert_return (invoke "32s_good4" (i64.const 0)) (i64.const 1717920867)) -(assert_return (invoke "32s_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "64_good1" (i64.const 0)) (i64.const 0x6867666564636261)) -(assert_return (invoke "64_good2" (i64.const 0)) (i64.const 0x6867666564636261)) -(assert_return (invoke "64_good3" (i64.const 0)) (i64.const 0x6968676665646362)) -(assert_return (invoke "64_good4" (i64.const 0)) (i64.const 0x6a69686766656463)) -(assert_return (invoke "64_good5" (i64.const 0)) (i64.const 122)) - -(assert_return (invoke "8u_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8u_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8u_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8u_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8u_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "8s_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8s_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8s_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8s_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "8s_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "16u_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16u_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16u_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16u_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16u_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "16s_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16s_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16s_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16s_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "16s_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "32u_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32u_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32u_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32u_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32u_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "32s_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32s_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32s_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32s_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "32s_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "64_good1" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "64_good2" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "64_good3" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "64_good4" (i64.const 65503)) (i64.const 0)) -(assert_return (invoke "64_good5" (i64.const 65503)) (i64.const 0)) - -(assert_return (invoke "8u_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8u_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8u_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8u_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8u_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "8s_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8s_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8s_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8s_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "8s_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "16u_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16u_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16u_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16u_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16u_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "16s_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16s_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16s_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16s_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "16s_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "32u_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32u_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32u_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32u_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32u_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "32s_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32s_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32s_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32s_good4" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "32s_good5" (i64.const 65504)) (i64.const 0)) - -(assert_return (invoke "64_good1" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "64_good2" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "64_good3" (i64.const 65504)) (i64.const 0)) -(assert_return (invoke "64_good4" (i64.const 65504)) (i64.const 0)) -(assert_trap (invoke "64_good5" (i64.const 65504)) "out of bounds memory access") - -(assert_trap (invoke "8u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "8s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "16u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "16s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "32u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "32s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "64_bad" (i64.const 0)) "out of bounds memory access") - -(assert_trap (invoke "8u_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "8s_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "16u_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "16s_bad" (i64.const 1)) "out of bounds memory access") -(assert_trap (invoke "32u_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "32s_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "64_bad" (i64.const 1)) "out of bounds memory access") - -;; Load f32 data with different offset/align arguments - -(module - (memory i64 1) - (data (i64.const 0) "\00\00\00\00\00\00\a0\7f\01\00\d0\7f") - - (func (export "32_good1") (param $i i64) (result f32) - (f32.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00' - ) - (func (export "32_good2") (param $i i64) (result f32) - (f32.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' - ) - (func (export "32_good3") (param $i i64) (result f32) - (f32.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' - ) - (func (export "32_good4") (param $i i64) (result f32) - (f32.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00' - ) - (func (export "32_good5") (param $i i64) (result f32) - (f32.load offset=8 align=4 (local.get $i)) ;; nan:0x500001 '\01\00\d0\7f' - ) - (func (export "32_bad") (param $i i64) - (drop (f32.load offset=4294967295 (local.get $i))) - ) -) - -(assert_return (invoke "32_good1" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "32_good2" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "32_good3" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "32_good4" (i64.const 0)) (f32.const 0.0)) -(assert_return (invoke "32_good5" (i64.const 0)) (f32.const nan:0x500001)) - -(assert_return (invoke "32_good1" (i64.const 65524)) (f32.const 0.0)) -(assert_return (invoke "32_good2" (i64.const 65524)) (f32.const 0.0)) -(assert_return (invoke "32_good3" (i64.const 65524)) (f32.const 0.0)) -(assert_return (invoke "32_good4" (i64.const 65524)) (f32.const 0.0)) -(assert_return (invoke "32_good5" (i64.const 65524)) (f32.const 0.0)) - -(assert_return (invoke "32_good1" (i64.const 65525)) (f32.const 0.0)) -(assert_return (invoke "32_good2" (i64.const 65525)) (f32.const 0.0)) -(assert_return (invoke "32_good3" (i64.const 65525)) (f32.const 0.0)) -(assert_return (invoke "32_good4" (i64.const 65525)) (f32.const 0.0)) -(assert_trap (invoke "32_good5" (i64.const 65525)) "out of bounds memory access") - -(assert_trap (invoke "32_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "32_bad" (i64.const 1)) "out of bounds memory access") - -;; Load f64 data with different offset/align arguments - -(module - (memory i64 1) - (data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\f4\7f\01\00\00\00\00\00\fc\7f") - - (func (export "64_good1") (param $i i64) (result f64) - (f64.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' - ) - (func (export "64_good2") (param $i i64) (result f64) - (f64.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' - ) - (func (export "64_good3") (param $i i64) (result f64) - (f64.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' - ) - (func (export "64_good4") (param $i i64) (result f64) - (f64.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' - ) - (func (export "64_good5") (param $i i64) (result f64) - (f64.load offset=18 align=8 (local.get $i)) ;; nan:0xc000000000001 '\01\00\00\00\00\00\fc\7f' - ) - (func (export "64_bad") (param $i i64) - (drop (f64.load offset=4294967295 (local.get $i))) - ) -) - -(assert_return (invoke "64_good1" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "64_good2" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "64_good3" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "64_good4" (i64.const 0)) (f64.const 0.0)) -(assert_return (invoke "64_good5" (i64.const 0)) (f64.const nan:0xc000000000001)) - -(assert_return (invoke "64_good1" (i64.const 65510)) (f64.const 0.0)) -(assert_return (invoke "64_good2" (i64.const 65510)) (f64.const 0.0)) -(assert_return (invoke "64_good3" (i64.const 65510)) (f64.const 0.0)) -(assert_return (invoke "64_good4" (i64.const 65510)) (f64.const 0.0)) -(assert_return (invoke "64_good5" (i64.const 65510)) (f64.const 0.0)) - -(assert_return (invoke "64_good1" (i64.const 65511)) (f64.const 0.0)) -(assert_return (invoke "64_good2" (i64.const 65511)) (f64.const 0.0)) -(assert_return (invoke "64_good3" (i64.const 65511)) (f64.const 0.0)) -(assert_return (invoke "64_good4" (i64.const 65511)) (f64.const 0.0)) -(assert_trap (invoke "64_good5" (i64.const 65511)) "out of bounds memory access") - -(assert_trap (invoke "64_bad" (i64.const 0)) "out of bounds memory access") -(assert_trap (invoke "64_bad" (i64.const 1)) "out of bounds memory access") diff --git a/test/spec/align64.wast b/test/spec/align64.wast deleted file mode 100644 index da34947f627..00000000000 --- a/test/spec/align64.wast +++ /dev/null @@ -1,866 +0,0 @@ -;; Test alignment annotation rules - -(module (memory i64 0) (func (drop (i32.load8_s align=1 (i64.const 0))))) -(module (memory i64 0) (func (drop (i32.load8_u align=1 (i64.const 0))))) -(module (memory i64 0) (func (drop (i32.load16_s align=2 (i64.const 0))))) -(module (memory i64 0) (func (drop (i32.load16_u align=2 (i64.const 0))))) -(module (memory i64 0) (func (drop (i32.load align=4 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load8_s align=1 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load8_u align=1 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load16_s align=2 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load16_u align=2 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load32_s align=4 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load32_u align=4 (i64.const 0))))) -(module (memory i64 0) (func (drop (i64.load align=8 (i64.const 0))))) -(module (memory i64 0) (func (drop (f32.load align=4 (i64.const 0))))) -(module (memory i64 0) (func (drop (f64.load align=8 (i64.const 0))))) -(module (memory i64 0) (func (i32.store8 align=1 (i64.const 0) (i32.const 1)))) -(module (memory i64 0) (func (i32.store16 align=2 (i64.const 0) (i32.const 1)))) -(module (memory i64 0) (func (i32.store align=4 (i64.const 0) (i32.const 1)))) -(module (memory i64 0) (func (i64.store8 align=1 (i64.const 0) (i64.const 1)))) -(module (memory i64 0) (func (i64.store16 align=2 (i64.const 0) (i64.const 1)))) -(module (memory i64 0) (func (i64.store32 align=4 (i64.const 0) (i64.const 1)))) -(module (memory i64 0) (func (i64.store align=8 (i64.const 0) (i64.const 1)))) -(module (memory i64 0) (func (f32.store align=4 (i64.const 0) (f32.const 1.0)))) -(module (memory i64 0) (func (f64.store align=8 (i64.const 0) (f64.const 1.0)))) - -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load8_s align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load8_s align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load8_u align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load8_u align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load16_s align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load16_s align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load16_u align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load16_u align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i32.load align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load8_s align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load8_s align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load8_u align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load8_u align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load16_s align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load16_s align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load16_u align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load16_u align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load32_s align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load32_s align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load32_u align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load32_u align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (i64.load align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (f32.load align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (f32.load align=7 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (f64.load align=0 (i64.const 0)))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (drop (f64.load align=7 (i64.const 0)))))" - ) - "alignment" -) - -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store8 align=0 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store8 align=7 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store16 align=0 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store16 align=7 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store align=0 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i32.store align=7 (i64.const 0) (i32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store8 align=0 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store8 align=7 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store16 align=0 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store16 align=7 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store32 align=0 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store32 align=7 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store align=0 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (i64.store align=7 (i64.const 0) (i64.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (f32.store align=0 (i64.const 0) (f32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (f32.store align=7 (i64.const 0) (f32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (f64.store align=0 (i64.const 0) (f32.const 0))))" - ) - "alignment" -) -(assert_malformed - (module quote - "(module (memory i64 0) (func (f64.store align=7 (i64.const 0) (f32.const 0))))" - ) - "alignment" -) - -(assert_invalid - (module (memory i64 0) (func (drop (i32.load8_s align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load8_u align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load16_s align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load16_u align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load8_s align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load8_u align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load16_s align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load16_u align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load32_s align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load32_u align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load align=16 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (f32.load align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (f64.load align=16 (i64.const 0))))) - "alignment must not be larger than natural" -) - -(assert_invalid - (module (memory i64 0) (func (drop (i32.load8_s align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load8_u align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load16_s align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load16_u align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i32.load align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load8_s align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load8_u align=2 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load16_s align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load16_u align=4 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load32_s align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load32_u align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (i64.load align=16 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (f32.load align=8 (i64.const 0))))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (drop (f64.load align=16 (i64.const 0))))) - "alignment must not be larger than natural" -) - -(assert_invalid - (module (memory i64 0) (func (i32.store8 align=2 (i64.const 0) (i32.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i32.store16 align=4 (i64.const 0) (i32.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i32.store align=8 (i64.const 0) (i32.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i64.store8 align=2 (i64.const 0) (i64.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i64.store16 align=4 (i64.const 0) (i64.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i64.store32 align=8 (i64.const 0) (i64.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (i64.store align=16 (i64.const 0) (i64.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (f32.store align=8 (i64.const 0) (f32.const 0)))) - "alignment must not be larger than natural" -) -(assert_invalid - (module (memory i64 0) (func (f64.store align=16 (i64.const 0) (f64.const 0)))) - "alignment must not be larger than natural" -) - -;; Test aligned and unaligned read/write - -(module - (memory i64 1) - - ;; $default: natural alignment, $1: align=1, $2: align=2, $4: align=4, $8: align=8 - - (func (export "f32_align_switch") (param i32) (result f32) - (local f32 f32) - (local.set 1 (f32.const 10.0)) - (block $4 - (block $2 - (block $1 - (block $default - (block $0 - (br_table $0 $default $1 $2 $4 (local.get 0)) - ) ;; 0 - (f32.store (i64.const 0) (local.get 1)) - (local.set 2 (f32.load (i64.const 0))) - (br $4) - ) ;; default - (f32.store align=1 (i64.const 0) (local.get 1)) - (local.set 2 (f32.load align=1 (i64.const 0))) - (br $4) - ) ;; 1 - (f32.store align=2 (i64.const 0) (local.get 1)) - (local.set 2 (f32.load align=2 (i64.const 0))) - (br $4) - ) ;; 2 - (f32.store align=4 (i64.const 0) (local.get 1)) - (local.set 2 (f32.load align=4 (i64.const 0))) - ) ;; 4 - (local.get 2) - ) - - (func (export "f64_align_switch") (param i32) (result f64) - (local f64 f64) - (local.set 1 (f64.const 10.0)) - (block $8 - (block $4 - (block $2 - (block $1 - (block $default - (block $0 - (br_table $0 $default $1 $2 $4 $8 (local.get 0)) - ) ;; 0 - (f64.store (i64.const 0) (local.get 1)) - (local.set 2 (f64.load (i64.const 0))) - (br $8) - ) ;; default - (f64.store align=1 (i64.const 0) (local.get 1)) - (local.set 2 (f64.load align=1 (i64.const 0))) - (br $8) - ) ;; 1 - (f64.store align=2 (i64.const 0) (local.get 1)) - (local.set 2 (f64.load align=2 (i64.const 0))) - (br $8) - ) ;; 2 - (f64.store align=4 (i64.const 0) (local.get 1)) - (local.set 2 (f64.load align=4 (i64.const 0))) - (br $8) - ) ;; 4 - (f64.store align=8 (i64.const 0) (local.get 1)) - (local.set 2 (f64.load align=8 (i64.const 0))) - ) ;; 8 - (local.get 2) - ) - - ;; $8s: i32/i64.load8_s, $8u: i32/i64.load8_u, $16s: i32/i64.load16_s, $16u: i32/i64.load16_u, $32: i32.load - ;; $32s: i64.load32_s, $32u: i64.load32_u, $64: i64.load - - (func (export "i32_align_switch") (param i32 i32) (result i32) - (local i32 i32) - (local.set 2 (i32.const 10)) - (block $32 - (block $16u - (block $16s - (block $8u - (block $8s - (block $0 - (br_table $0 $8s $8u $16s $16u $32 (local.get 0)) - ) ;; 0 - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i32.store8 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load8_s (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i32.store8 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load8_s align=1 (i64.const 0))) - ) - ) - (br $32) - ) ;; 8s - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i32.store8 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load8_u (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i32.store8 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load8_u align=1 (i64.const 0))) - ) - ) - (br $32) - ) ;; 8u - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i32.store16 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_s (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i32.store16 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_s align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i32.store16 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_s align=2 (i64.const 0))) - ) - ) - (br $32) - ) ;; 16s - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i32.store16 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_u (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i32.store16 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_u align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i32.store16 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load16_u align=2 (i64.const 0))) - ) - ) - (br $32) - ) ;; 16u - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i32.store (i64.const 0) (local.get 2)) - (local.set 3 (i32.load (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i32.store align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i32.store align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load align=2 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 4)) - (then - (i32.store align=4 (i64.const 0) (local.get 2)) - (local.set 3 (i32.load align=4 (i64.const 0))) - ) - ) - ) ;; 32 - (local.get 3) - ) - - (func (export "i64_align_switch") (param i32 i32) (result i64) - (local i64 i64) - (local.set 2 (i64.const 10)) - (block $64 - (block $32u - (block $32s - (block $16u - (block $16s - (block $8u - (block $8s - (block $0 - (br_table $0 $8s $8u $16s $16u $32s $32u $64 (local.get 0)) - ) ;; 0 - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store8 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load8_s (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store8 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load8_s align=1 (i64.const 0))) - ) - ) - (br $64) - ) ;; 8s - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store8 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load8_u (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store8 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load8_u align=1 (i64.const 0))) - ) - ) - (br $64) - ) ;; 8u - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store16 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_s (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store16 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_s align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i64.store16 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_s align=2 (i64.const 0))) - ) - ) - (br $64) - ) ;; 16s - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store16 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_u (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store16 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_u align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i64.store16 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load16_u align=2 (i64.const 0))) - ) - ) - (br $64) - ) ;; 16u - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store32 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_s (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store32 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_s align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i64.store32 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_s align=2 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 4)) - (then - (i64.store32 align=4 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_s align=4 (i64.const 0))) - ) - ) - (br $64) - ) ;; 32s - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store32 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_u (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store32 align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_u align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i64.store32 align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_u align=2 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 4)) - (then - (i64.store32 align=4 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load32_u align=4 (i64.const 0))) - ) - ) - (br $64) - ) ;; 32u - (if (i32.eq (local.get 1) (i32.const 0)) - (then - (i64.store (i64.const 0) (local.get 2)) - (local.set 3 (i64.load (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 1)) - (then - (i64.store align=1 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load align=1 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 2)) - (then - (i64.store align=2 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load align=2 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 4)) - (then - (i64.store align=4 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load align=4 (i64.const 0))) - ) - ) - (if (i32.eq (local.get 1) (i32.const 8)) - (then - (i64.store align=8 (i64.const 0) (local.get 2)) - (local.set 3 (i64.load align=8 (i64.const 0))) - ) - ) - ) ;; 64 - (local.get 3) - ) -) - -(assert_return (invoke "f32_align_switch" (i32.const 0)) (f32.const 10.0)) -(assert_return (invoke "f32_align_switch" (i32.const 1)) (f32.const 10.0)) -(assert_return (invoke "f32_align_switch" (i32.const 2)) (f32.const 10.0)) -(assert_return (invoke "f32_align_switch" (i32.const 3)) (f32.const 10.0)) - -(assert_return (invoke "f64_align_switch" (i32.const 0)) (f64.const 10.0)) -(assert_return (invoke "f64_align_switch" (i32.const 1)) (f64.const 10.0)) -(assert_return (invoke "f64_align_switch" (i32.const 2)) (f64.const 10.0)) -(assert_return (invoke "f64_align_switch" (i32.const 3)) (f64.const 10.0)) -(assert_return (invoke "f64_align_switch" (i32.const 4)) (f64.const 10.0)) - -(assert_return (invoke "i32_align_switch" (i32.const 0) (i32.const 0)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 0) (i32.const 1)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 1) (i32.const 0)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 1) (i32.const 1)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 0)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 1)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 2)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 0)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 1)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 2)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 0)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 1)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 2)) (i32.const 10)) -(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 4)) (i32.const 10)) - -(assert_return (invoke "i64_align_switch" (i32.const 0) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 0) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 1) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 1) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 2)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 2)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 2)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 4)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 2)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 4)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 0)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 1)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 2)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 4)) (i64.const 10)) -(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 8)) (i64.const 10)) - -;; Test that an i64 store with 4-byte alignment that's 4 bytes out of bounds traps without storing anything - -(module - (memory i64 1) - (func (export "store") (param i64 i64) - (i64.store align=4 (local.get 0) (local.get 1)) - ) - (func (export "load") (param i64) (result i32) - (i32.load (local.get 0)) - ) -) - -(assert_trap (invoke "store" (i64.const 65532) (i64.const -1)) "out of bounds memory access") -;; No memory was changed -(assert_return (invoke "load" (i64.const 65532)) (i32.const 0)) diff --git a/test/spec/br.wast b/test/spec/br.wast deleted file mode 100644 index 98a3a34bdc8..00000000000 --- a/test/spec/br.wast +++ /dev/null @@ -1,606 +0,0 @@ -;; Test `br` operator - -(module - ;; Auxiliary definition - (func $dummy) - - (func (export "type-i32") (block (drop (i32.ctz (br 0))))) - (func (export "type-i64") (block (drop (i64.ctz (br 0))))) - (func (export "type-f32") (block (drop (f32.neg (br 0))))) - (func (export "type-f64") (block (drop (f64.neg (br 0))))) - - (func (export "type-i32-value") (result i32) - (block (result i32) (i32.ctz (br 0 (i32.const 1)))) - ) - (func (export "type-i64-value") (result i64) - (block (result i64) (i64.ctz (br 0 (i64.const 2)))) - ) - (func (export "type-f32-value") (result f32) - (block (result f32) (f32.neg (br 0 (f32.const 3)))) - ) - (func (export "type-f64-value") (result f64) - (block (result f64) (f64.neg (br 0 (f64.const 4)))) - ) - - (func (export "as-block-first") - (block (br 0) (call $dummy)) - ) - (func (export "as-block-mid") - (block (call $dummy) (br 0) (call $dummy)) - ) - (func (export "as-block-last") - (block (nop) (call $dummy) (br 0)) - ) - (func (export "as-block-value") (result i32) - (block (result i32) (nop) (call $dummy) (br 0 (i32.const 2))) - ) - - (func (export "as-loop-first") (result i32) - (block (result i32) (loop (result i32) (br 1 (i32.const 3)) (i32.const 2))) - ) - (func (export "as-loop-mid") (result i32) - (block (result i32) - (loop (result i32) (call $dummy) (br 1 (i32.const 4)) (i32.const 2)) - ) - ) - (func (export "as-loop-last") (result i32) - (block (result i32) - (loop (result i32) (nop) (call $dummy) (br 1 (i32.const 5))) - ) - ) - - (func (export "as-br-value") (result i32) - (block (result i32) (br 0 (br 0 (i32.const 9)))) - ) - - (func (export "as-br_if-cond") - (block (br_if 0 (br 0))) - ) - (func (export "as-br_if-value") (result i32) - (block (result i32) - (drop (br_if 0 (br 0 (i32.const 8)) (i32.const 1))) (i32.const 7) - ) - ) - (func (export "as-br_if-value-cond") (result i32) - (block (result i32) - (drop (br_if 0 (i32.const 6) (br 0 (i32.const 9)))) (i32.const 7) - ) - ) - - (func (export "as-br_table-index") - (block (br_table 0 0 0 (br 0))) - ) - (func (export "as-br_table-value") (result i32) - (block (result i32) - (br_table 0 0 0 (br 0 (i32.const 10)) (i32.const 1)) (i32.const 7) - ) - ) - (func (export "as-br_table-value-index") (result i32) - (block (result i32) - (br_table 0 0 (i32.const 6) (br 0 (i32.const 11))) (i32.const 7) - ) - ) - - (func (export "as-return-value") (result i64) - (block (result i64) (return (br 0 (i64.const 7)))) - ) - - (func (export "as-if-cond") (result i32) - (block (result i32) - (if (result i32) (br 0 (i32.const 2)) - (then (i32.const 0)) - (else (i32.const 1)) - ) - ) - ) - (func (export "as-if-then") (param i32 i32) (result i32) - (block (result i32) - (if (result i32) (local.get 0) - (then (br 1 (i32.const 3))) - (else (local.get 1)) - ) - ) - ) - (func (export "as-if-else") (param i32 i32) (result i32) - (block (result i32) - (if (result i32) (local.get 0) - (then (local.get 1)) - (else (br 1 (i32.const 4))) - ) - ) - ) - - (func (export "as-select-first") (param i32 i32) (result i32) - (block (result i32) - (select (br 0 (i32.const 5)) (local.get 0) (local.get 1)) - ) - ) - (func (export "as-select-second") (param i32 i32) (result i32) - (block (result i32) - (select (local.get 0) (br 0 (i32.const 6)) (local.get 1)) - ) - ) - (func (export "as-select-cond") (result i32) - (block (result i32) - (select (i32.const 0) (i32.const 1) (br 0 (i32.const 7))) - ) - ) - - (func $f (param i32 i32 i32) (result i32) (i32.const -1)) - (func (export "as-call-first") (result i32) - (block (result i32) - (call $f (br 0 (i32.const 12)) (i32.const 2) (i32.const 3)) - ) - ) - (func (export "as-call-mid") (result i32) - (block (result i32) - (call $f (i32.const 1) (br 0 (i32.const 13)) (i32.const 3)) - ) - ) - (func (export "as-call-last") (result i32) - (block (result i32) - (call $f (i32.const 1) (i32.const 2) (br 0 (i32.const 14))) - ) - ) - - (type $sig (func (param i32 i32 i32) (result i32))) - (table funcref (elem $f)) - (func (export "as-call_indirect-func") (result i32) - (block (result i32) - (call_indirect (type $sig) - (br 0 (i32.const 20)) - (i32.const 1) (i32.const 2) (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-first") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) - (br 0 (i32.const 21)) (i32.const 2) (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-mid") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) - (i32.const 1) (br 0 (i32.const 22)) (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-last") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) - (i32.const 1) (i32.const 2) (br 0 (i32.const 23)) - ) - ) - ) - - (func (export "as-local.set-value") (result i32) (local f32) - (block (result i32) (local.set 0 (br 0 (i32.const 17))) (i32.const -1)) - ) - (func (export "as-local.tee-value") (result i32) (local i32) - (block (result i32) (local.tee 0 (br 0 (i32.const 1)))) - ) - (global $a (mut i32) (i32.const 10)) - (func (export "as-global.set-value") (result i32) - (block (result i32) (global.set $a (br 0 (i32.const 1)))) - ) - - (memory 1) - (func (export "as-load-address") (result f32) - (block (result f32) (f32.load (br 0 (f32.const 1.7)))) - ) - (func (export "as-loadN-address") (result i64) - (block (result i64) (i64.load8_s (br 0 (i64.const 30)))) - ) - - (func (export "as-store-address") (result i32) - (block (result i32) - (f64.store (br 0 (i32.const 30)) (f64.const 7)) (i32.const -1) - ) - ) - (func (export "as-store-value") (result i32) - (block (result i32) - (i64.store (i32.const 2) (br 0 (i32.const 31))) (i32.const -1) - ) - ) - - (func (export "as-storeN-address") (result i32) - (block (result i32) - (i32.store8 (br 0 (i32.const 32)) (i32.const 7)) (i32.const -1) - ) - ) - (func (export "as-storeN-value") (result i32) - (block (result i32) - (i64.store16 (i32.const 2) (br 0 (i32.const 33))) (i32.const -1) - ) - ) - - (func (export "as-unary-operand") (result f32) - (block (result f32) (f32.neg (br 0 (f32.const 3.4)))) - ) - - (func (export "as-binary-left") (result i32) - (block (result i32) (i32.add (br 0 (i32.const 3)) (i32.const 10))) - ) - (func (export "as-binary-right") (result i64) - (block (result i64) (i64.sub (i64.const 10) (br 0 (i64.const 45)))) - ) - - (func (export "as-test-operand") (result i32) - (block (result i32) (i32.eqz (br 0 (i32.const 44)))) - ) - - (func (export "as-compare-left") (result i32) - (block (result i32) (f64.le (br 0 (i32.const 43)) (f64.const 10))) - ) - (func (export "as-compare-right") (result i32) - (block (result i32) (f32.ne (f32.const 10) (br 0 (i32.const 42)))) - ) - - (func (export "as-convert-operand") (result i32) - (block (result i32) (i32.wrap_i64 (br 0 (i32.const 41)))) - ) - - (func (export "as-memory.grow-size") (result i32) - (block (result i32) (memory.grow (br 0 (i32.const 40)))) - ) - - (func (export "nested-block-value") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (call $dummy) - (i32.add (i32.const 4) (br 0 (i32.const 8))) - ) - ) - ) - - (func (export "nested-br-value") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (br 0 (br 1 (i32.const 8))) - ) - ) - (i32.const 16) - ) - ) - ) - - (func (export "nested-br_if-value") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (drop (br_if 0 (br 1 (i32.const 8)) (i32.const 1))) - (i32.const 32) - ) - ) - (i32.const 16) - ) - ) - ) - - (func (export "nested-br_if-value-cond") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop (br_if 0 (i32.const 4) (br 0 (i32.const 8)))) - (i32.const 16) - ) - ) - ) - - (func (export "nested-br_table-value") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (br_table 0 (br 1 (i32.const 8)) (i32.const 1)) - ) - ) - (i32.const 16) - ) - ) - ) - - (func (export "nested-br_table-value-index") (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (br_table 0 (i32.const 4) (br 0 (i32.const 8))) - (i32.const 16) - ) - ) - ) -) - -(assert_return (invoke "type-i32")) -(assert_return (invoke "type-i64")) -(assert_return (invoke "type-f32")) -(assert_return (invoke "type-f64")) - -(assert_return (invoke "type-i32-value") (i32.const 1)) -(assert_return (invoke "type-i64-value") (i64.const 2)) -(assert_return (invoke "type-f32-value") (f32.const 3)) -(assert_return (invoke "type-f64-value") (f64.const 4)) - -(assert_return (invoke "as-block-first")) -(assert_return (invoke "as-block-mid")) -(assert_return (invoke "as-block-last")) -(assert_return (invoke "as-block-value") (i32.const 2)) - -(assert_return (invoke "as-loop-first") (i32.const 3)) -(assert_return (invoke "as-loop-mid") (i32.const 4)) -(assert_return (invoke "as-loop-last") (i32.const 5)) - -(assert_return (invoke "as-br-value") (i32.const 9)) - -(assert_return (invoke "as-br_if-cond")) -(assert_return (invoke "as-br_if-value") (i32.const 8)) -(assert_return (invoke "as-br_if-value-cond") (i32.const 9)) - -(assert_return (invoke "as-br_table-index")) -(assert_return (invoke "as-br_table-value") (i32.const 10)) -(assert_return (invoke "as-br_table-value-index") (i32.const 11)) - -(assert_return (invoke "as-return-value") (i64.const 7)) - -(assert_return (invoke "as-if-cond") (i32.const 2)) -(assert_return (invoke "as-if-then" (i32.const 1) (i32.const 6)) (i32.const 3)) -(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 6)) (i32.const 4)) -(assert_return (invoke "as-if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) - -(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-first" (i32.const 1) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-second" (i32.const 1) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-cond") (i32.const 7)) - -(assert_return (invoke "as-call-first") (i32.const 12)) -(assert_return (invoke "as-call-mid") (i32.const 13)) -(assert_return (invoke "as-call-last") (i32.const 14)) - -(assert_return (invoke "as-call_indirect-func") (i32.const 20)) -(assert_return (invoke "as-call_indirect-first") (i32.const 21)) -(assert_return (invoke "as-call_indirect-mid") (i32.const 22)) -(assert_return (invoke "as-call_indirect-last") (i32.const 23)) - -(assert_return (invoke "as-local.set-value") (i32.const 17)) -(assert_return (invoke "as-local.tee-value") (i32.const 1)) -(assert_return (invoke "as-global.set-value") (i32.const 1)) - -(assert_return (invoke "as-load-address") (f32.const 1.7)) -(assert_return (invoke "as-loadN-address") (i64.const 30)) - -(assert_return (invoke "as-store-address") (i32.const 30)) -(assert_return (invoke "as-store-value") (i32.const 31)) -(assert_return (invoke "as-storeN-address") (i32.const 32)) -(assert_return (invoke "as-storeN-value") (i32.const 33)) - -(assert_return (invoke "as-unary-operand") (f32.const 3.4)) - -(assert_return (invoke "as-binary-left") (i32.const 3)) -(assert_return (invoke "as-binary-right") (i64.const 45)) - -(assert_return (invoke "as-test-operand") (i32.const 44)) - -(assert_return (invoke "as-compare-left") (i32.const 43)) -(assert_return (invoke "as-compare-right") (i32.const 42)) - -(assert_return (invoke "as-convert-operand") (i32.const 41)) - -(assert_return (invoke "as-memory.grow-size") (i32.const 40)) - -(assert_return (invoke "nested-block-value") (i32.const 9)) -(assert_return (invoke "nested-br-value") (i32.const 9)) -(assert_return (invoke "nested-br_if-value") (i32.const 9)) -(assert_return (invoke "nested-br_if-value-cond") (i32.const 9)) -(assert_return (invoke "nested-br_table-value") (i32.const 9)) -(assert_return (invoke "nested-br_table-value-index") (i32.const 9)) - -(assert_invalid - (module (func $type-arg-empty-vs-num (result i32) - (block (result i32) (br 0) (i32.const 1)) - )) - "type mismatch" -) - -(assert_invalid - (module (func $type-arg-void-vs-num (result i32) - (block (result i32) (br 0 (nop)) (i32.const 1)) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-void-vs-num-nested (result i32) - (block (result i32) (i32.const 0) (block (br 1))) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-num-vs-num (result i32) - (block (result i32) (br 0 (i64.const 1)) (i32.const 1)) - )) - "type mismatch" -) - -(assert_invalid - (module - (func $type-arg-empty-in-br - (i32.const 0) - (block (result i32) (br 0 (br 0))) (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-br_if - (i32.const 0) - (block (result i32) (br_if 0 (br 0) (i32.const 1))) (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-br_table - (i32.const 0) - (block (result i32) (br_table 0 (br 0))) (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-return - (block (result i32) - (return (br 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-select - (block (result i32) - (select (br 0) (i32.const 1) (i32.const 2)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-call - (block (result i32) - (call 1 (br 0)) - ) - (i32.eqz) (drop) - ) - (func (param i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-arg-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (br 0) (i32.const 0) - ) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-local.set - (local i32) - (block (result i32) - (local.set 0 (br 0)) (local.get 0) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-empty-in-local.tee - (local i32) - (block (result i32) - (local.tee 0 (br 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (global $x (mut i32) (i32.const 0)) - (func $type-arg-empty-in-global.set - (block (result i32) - (global.set $x (br 0)) (global.get $x) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-arg-empty-in-memory.grow - (block (result i32) - (memory.grow (br 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-arg-empty-in-load - (block (result i32) - (i32.load (br 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-arg-empty-in-store - (block (result i32) - (i32.store (br 0) (i32.const 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) - -(assert_invalid - (module (func $unbound-label (br 1))) - "unknown label" -) -(assert_invalid - (module (func $unbound-nested-label (block (block (br 5))))) - "unknown label" -) -(assert_invalid - (module (func $large-label (br 0x10000001))) - "unknown label" -) diff --git a/test/spec/call.wast b/test/spec/call.wast deleted file mode 100644 index 4d0f1a7c259..00000000000 --- a/test/spec/call.wast +++ /dev/null @@ -1,463 +0,0 @@ -;; Test `call` operator - -(module - ;; Auxiliary definitions - (func $const-i32 (result i32) (i32.const 0x132)) - (func $const-i64 (result i64) (i64.const 0x164)) - (func $const-f32 (result f32) (f32.const 0xf32)) - (func $const-f64 (result f64) (f64.const 0xf64)) - - (func $id-i32 (param i32) (result i32) (local.get 0)) - (func $id-i64 (param i64) (result i64) (local.get 0)) - (func $id-f32 (param f32) (result f32) (local.get 0)) - (func $id-f64 (param f64) (result f64) (local.get 0)) - - (func $f32-i32 (param f32 i32) (result i32) (local.get 1)) - (func $i32-i64 (param i32 i64) (result i64) (local.get 1)) - (func $f64-f32 (param f64 f32) (result f32) (local.get 1)) - (func $i64-f64 (param i64 f64) (result f64) (local.get 1)) - - ;; Typing - - (func (export "type-i32") (result i32) (call $const-i32)) - (func (export "type-i64") (result i64) (call $const-i64)) - (func (export "type-f32") (result f32) (call $const-f32)) - (func (export "type-f64") (result f64) (call $const-f64)) - - (func (export "type-first-i32") (result i32) (call $id-i32 (i32.const 32))) - (func (export "type-first-i64") (result i64) (call $id-i64 (i64.const 64))) - (func (export "type-first-f32") (result f32) (call $id-f32 (f32.const 1.32))) - (func (export "type-first-f64") (result f64) (call $id-f64 (f64.const 1.64))) - - (func (export "type-second-i32") (result i32) - (call $f32-i32 (f32.const 32.1) (i32.const 32)) - ) - (func (export "type-second-i64") (result i64) - (call $i32-i64 (i32.const 32) (i64.const 64)) - ) - (func (export "type-second-f32") (result f32) - (call $f64-f32 (f64.const 64) (f32.const 32)) - ) - (func (export "type-second-f64") (result f64) - (call $i64-f64 (i64.const 64) (f64.const 64.1)) - ) - - ;; Recursion - - (func $fac (export "fac") (param i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 1)) - (else - (i64.mul - (local.get 0) - (call $fac (i64.sub (local.get 0) (i64.const 1))) - ) - ) - ) - ) - - (func $fac-acc (export "fac-acc") (param i64 i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 1)) - (else - (call $fac-acc - (i64.sub (local.get 0) (i64.const 1)) - (i64.mul (local.get 0) (local.get 1)) - ) - ) - ) - ) - - (func $fib (export "fib") (param i64) (result i64) - (if (result i64) (i64.le_u (local.get 0) (i64.const 1)) - (then (i64.const 1)) - (else - (i64.add - (call $fib (i64.sub (local.get 0) (i64.const 2))) - (call $fib (i64.sub (local.get 0) (i64.const 1))) - ) - ) - ) - ) - - (func $even (export "even") (param i64) (result i32) - (if (result i32) (i64.eqz (local.get 0)) - (then (i32.const 44)) - (else (call $odd (i64.sub (local.get 0) (i64.const 1)))) - ) - ) - (func $odd (export "odd") (param i64) (result i32) - (if (result i32) (i64.eqz (local.get 0)) - (then (i32.const 99)) - (else (call $even (i64.sub (local.get 0) (i64.const 1)))) - ) - ) - - ;; Stack exhaustion - - ;; Implementations are required to have every call consume some abstract - ;; resource towards exhausting some abstract finite limit, such that - ;; infinitely recursive test cases reliably trap in finite time. This is - ;; because otherwise applications could come to depend on it on those - ;; implementations and be incompatible with implementations that don't do - ;; it (or don't do it under the same circumstances). - - (func $runaway (export "runaway") (call $runaway)) - - (func $mutual-runaway1 (export "mutual-runaway") (call $mutual-runaway2)) - (func $mutual-runaway2 (call $mutual-runaway1)) - - ;; As parameter of control constructs and instructions - - (memory 1) - - (func (export "as-select-first") (result i32) - (select (call $const-i32) (i32.const 2) (i32.const 3)) - ) - (func (export "as-select-mid") (result i32) - (select (i32.const 2) (call $const-i32) (i32.const 3)) - ) - (func (export "as-select-last") (result i32) - (select (i32.const 2) (i32.const 3) (call $const-i32)) - ) - - (func (export "as-if-condition") (result i32) - (if (result i32) (call $const-i32) (then (i32.const 1)) (else (i32.const 2))) - ) - - (func (export "as-br_if-first") (result i32) - (block (result i32) (br_if 0 (call $const-i32) (i32.const 2))) - ) - (func (export "as-br_if-last") (result i32) - (block (result i32) (br_if 0 (i32.const 2) (call $const-i32))) - ) - - (func (export "as-br_table-first") (result i32) - (block (result i32) (call $const-i32) (i32.const 2) (br_table 0 0)) - ) - (func (export "as-br_table-last") (result i32) - (block (result i32) (i32.const 2) (call $const-i32) (br_table 0 0)) - ) - - (func $func (param i32 i32) (result i32) (local.get 0)) - (type $check (func (param i32 i32) (result i32))) - (table funcref (elem $func)) - (func (export "as-call_indirect-first") (result i32) - (block (result i32) - (call_indirect (type $check) - (call $const-i32) (i32.const 2) (i32.const 0) - ) - ) - ) - (func (export "as-call_indirect-mid") (result i32) - (block (result i32) - (call_indirect (type $check) - (i32.const 2) (call $const-i32) (i32.const 0) - ) - ) - ) - (func (export "as-call_indirect-last") (result i32) - (block (result i32) - (call_indirect (type $check) - (i32.const 1) (i32.const 2) (call $const-i32) - ) - ) - ) - - (func (export "as-store-first") - (call $const-i32) (i32.const 1) (i32.store) - ) - (func (export "as-store-last") - (i32.const 10) (call $const-i32) (i32.store) - ) - - (func (export "as-memory.grow-value") (result i32) - (memory.grow (call $const-i32)) - ) - (func (export "as-return-value") (result i32) - (call $const-i32) (return) - ) - (func (export "as-drop-operand") - (call $const-i32) (drop) - ) - (func (export "as-br-value") (result i32) - (block (result i32) (br 0 (call $const-i32))) - ) - (func (export "as-local.set-value") (result i32) - (local i32) (local.set 0 (call $const-i32)) (local.get 0) - ) - (func (export "as-local.tee-value") (result i32) - (local i32) (local.tee 0 (call $const-i32)) - ) - (global $a (mut i32) (i32.const 10)) - (func (export "as-global.set-value") (result i32) - (global.set $a (call $const-i32)) - (global.get $a) - ) - (func (export "as-load-operand") (result i32) - (i32.load (call $const-i32)) - ) - - (func $dummy (param i32) (result i32) (local.get 0)) - (func $du (param f32) (result f32) (local.get 0)) - (func (export "as-unary-operand") (result f32) - (block (result f32) (f32.sqrt (call $du (f32.const 0x0p+0)))) - ) - - (func (export "as-binary-left") (result i32) - (block (result i32) (i32.add (call $dummy (i32.const 1)) (i32.const 10))) - ) - (func (export "as-binary-right") (result i32) - (block (result i32) (i32.sub (i32.const 10) (call $dummy (i32.const 1)))) - ) - - (func (export "as-test-operand") (result i32) - (block (result i32) (i32.eqz (call $dummy (i32.const 1)))) - ) - - (func (export "as-compare-left") (result i32) - (block (result i32) (i32.le_u (call $dummy (i32.const 1)) (i32.const 10))) - ) - (func (export "as-compare-right") (result i32) - (block (result i32) (i32.ne (i32.const 10) (call $dummy (i32.const 1)))) - ) - - (func (export "as-convert-operand") (result i64) - (block (result i64) (i64.extend_i32_s (call $dummy (i32.const 1)))) - ) - - ;; Test correct argument passing - - (func $return-from-long-argument-list-helper (param f32 i32 i32 f64 f32 f32 f32 f64 f32 i32 i32 f32 f64 i64 i64 i32 i64 i64 f32 i64 i64 i64 i32 f32 f32 f32 f64 f32 i32 i64 f32 f64 f64 f32 i32 f32 f32 f64 i64 f64 i32 i64 f32 f64 i32 i32 i32 i64 f64 i32 i64 i64 f64 f64 f64 f64 f64 f64 i32 f32 f64 f64 i32 i64 f32 f32 f32 i32 f64 f64 f64 f64 f64 f32 i64 i64 i32 i32 i32 f32 f64 i32 i64 f32 f32 f32 i32 i32 f32 f64 i64 f32 f64 f32 f32 f32 i32 f32 i64 i32) (result i32) - (local.get 99) - ) - - (func (export "return-from-long-argument-list") (param i32) (result i32) - (call $return-from-long-argument-list-helper (f32.const 0) (i32.const 0) (i32.const 0) (f64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (i64.const 0) (i64.const 0) (f32.const 0) (i64.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f32.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (f32.const 0) (i64.const 0) (local.get 0)) - ) -) - -(assert_return (invoke "type-i32") (i32.const 0x132)) -(assert_return (invoke "type-i64") (i64.const 0x164)) -(assert_return (invoke "type-f32") (f32.const 0xf32)) -(assert_return (invoke "type-f64") (f64.const 0xf64)) - -(assert_return (invoke "type-first-i32") (i32.const 32)) -(assert_return (invoke "type-first-i64") (i64.const 64)) -(assert_return (invoke "type-first-f32") (f32.const 1.32)) -(assert_return (invoke "type-first-f64") (f64.const 1.64)) - -(assert_return (invoke "type-second-i32") (i32.const 32)) -(assert_return (invoke "type-second-i64") (i64.const 64)) -(assert_return (invoke "type-second-f32") (f32.const 32)) -(assert_return (invoke "type-second-f64") (f64.const 64.1)) - -(assert_return (invoke "fac" (i64.const 0)) (i64.const 1)) -(assert_return (invoke "fac" (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac" (i64.const 5)) (i64.const 120)) -(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776)) -(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120)) -(assert_return - (invoke "fac-acc" (i64.const 25) (i64.const 1)) - (i64.const 7034535277573963776) -) - -(assert_return (invoke "fib" (i64.const 0)) (i64.const 1)) -(assert_return (invoke "fib" (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fib" (i64.const 2)) (i64.const 2)) -(assert_return (invoke "fib" (i64.const 5)) (i64.const 8)) -(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946)) - -(assert_return (invoke "even" (i64.const 0)) (i32.const 44)) -(assert_return (invoke "even" (i64.const 1)) (i32.const 99)) -(assert_return (invoke "even" (i64.const 100)) (i32.const 44)) -(assert_return (invoke "even" (i64.const 77)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 0)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 1)) (i32.const 44)) -(assert_return (invoke "odd" (i64.const 200)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 77)) (i32.const 44)) - -(assert_exhaustion (invoke "runaway") "call stack exhausted") -(assert_exhaustion (invoke "mutual-runaway") "call stack exhausted") - -(assert_return (invoke "as-select-first") (i32.const 0x132)) -(assert_return (invoke "as-select-mid") (i32.const 2)) -(assert_return (invoke "as-select-last") (i32.const 2)) - -(assert_return (invoke "as-if-condition") (i32.const 1)) - -(assert_return (invoke "as-br_if-first") (i32.const 0x132)) -(assert_return (invoke "as-br_if-last") (i32.const 2)) - -(assert_return (invoke "as-br_table-first") (i32.const 0x132)) -(assert_return (invoke "as-br_table-last") (i32.const 2)) - -(assert_return (invoke "as-call_indirect-first") (i32.const 0x132)) -(assert_return (invoke "as-call_indirect-mid") (i32.const 2)) -(assert_trap (invoke "as-call_indirect-last") "undefined element") - -(assert_return (invoke "as-store-first")) -(assert_return (invoke "as-store-last")) - -(assert_return (invoke "as-memory.grow-value") (i32.const 1)) -(assert_return (invoke "as-return-value") (i32.const 0x132)) -(assert_return (invoke "as-drop-operand")) -(assert_return (invoke "as-br-value") (i32.const 0x132)) -(assert_return (invoke "as-local.set-value") (i32.const 0x132)) -(assert_return (invoke "as-local.tee-value") (i32.const 0x132)) -(assert_return (invoke "as-global.set-value") (i32.const 0x132)) -(assert_return (invoke "as-load-operand") (i32.const 1)) - -(assert_return (invoke "as-unary-operand") (f32.const 0x0p+0)) -(assert_return (invoke "as-binary-left") (i32.const 11)) -(assert_return (invoke "as-binary-right") (i32.const 9)) -(assert_return (invoke "as-test-operand") (i32.const 0)) -(assert_return (invoke "as-compare-left") (i32.const 1)) -(assert_return (invoke "as-compare-right") (i32.const 1)) -(assert_return (invoke "as-convert-operand") (i64.const 1)) - -(assert_return (invoke "return-from-long-argument-list" (i32.const 42)) (i32.const 42)) - -;; Invalid typing - -(assert_invalid - (module - (func $type-void-vs-num (i32.eqz (call 1))) - (func) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-num-vs-num (i32.eqz (call 1))) - (func (result i64) (i64.const 1)) - ) - "type mismatch" -) - -(assert_invalid - (module - (func $arity-0-vs-1 (call 1)) - (func (param i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $arity-0-vs-2 (call 1)) - (func (param f64 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $arity-1-vs-0 (call 1 (i32.const 1))) - (func) - ) - "type mismatch" -) -(assert_invalid - (module - (func $arity-2-vs-0 (call 1 (f64.const 2) (i32.const 1))) - (func) - ) - "type mismatch" -) - -(assert_invalid - (module - (func $type-first-void-vs-num (call 1 (nop) (i32.const 1))) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-void-vs-num (call 1 (i32.const 1) (nop))) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-first-num-vs-num (call 1 (f64.const 1) (i32.const 1))) - (func (param i32 f64)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-num-vs-num (call 1 (i32.const 1) (f64.const 1))) - (func (param f64 i32)) - ) - "type mismatch" -) - -(assert_invalid - (module - (func $type-first-empty-in-block - (block (call 1)) - ) - (func (param i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-empty-in-block - (block (call 1 (i32.const 0))) - ) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-first-empty-in-loop - (loop (call 1)) - ) - (func (param i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-empty-in-loop - (loop (call 1 (i32.const 0))) - ) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-first-empty-in-then - (if (i32.const 0) (then (call 1))) - ) - (func (param i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-empty-in-then - (if (i32.const 0) (then (call 1 (i32.const 0)))) - ) - (func (param i32 i32)) - ) - "type mismatch" -) - - -;; Unbound function - -(assert_invalid - (module (func $unbound-func (call 1))) - "unknown function" -) -(assert_invalid - (module (func $large-func (call 1012321300))) - "unknown function" -) diff --git a/test/spec/call_ref.wast b/test/spec/call_ref.wast deleted file mode 100644 index 071aa8bbfca..00000000000 --- a/test/spec/call_ref.wast +++ /dev/null @@ -1,136 +0,0 @@ -(module - (type $ii (func (param i32) (result i32))) - - (func $apply (param $f (ref $ii)) (param $x i32) (result i32) - (call_ref $ii (local.get $x) (local.get $f)) - ) - - (func $f (type $ii) (i32.mul (local.get 0) (local.get 0))) - (func $g (type $ii) (i32.sub (i32.const 0) (local.get 0))) - - (elem declare func $f $g) - - (func (export "run") (param $x i32) (result i32) - (local $rf (ref null $ii)) - (local $rg (ref null $ii)) - (local.set $rf (ref.func $f)) - (local.set $rg (ref.func $g)) - (call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg)) - ) - - (func (export "null") (result i32) - (call_ref $ii (i32.const 1) (ref.null $ii)) - ) - - ;; Recursion - - (type $ll (func (param i64) (result i64))) - (type $lll (func (param i64 i64) (result i64))) - - (elem declare func $fac) - (global $fac (ref $ll) (ref.func $fac)) - - (func $fac (export "fac") (type $ll) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 1)) - (else - (i64.mul - (local.get 0) - (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac)) - ) - ) - ) - ) - - (elem declare func $fac-acc) - (global $fac-acc (ref $lll) (ref.func $fac-acc)) - - (func $fac-acc (export "fac-acc") (type $lll) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 1)) - (else - (call_ref $lll - (i64.sub (local.get 0) (i64.const 1)) - (i64.mul (local.get 0) (local.get 1)) - (global.get $fac-acc) - ) - ) - ) - ) - - (elem declare func $fib) - (global $fib (ref $ll) (ref.func $fib)) - - (func $fib (export "fib") (type $ll) - (if (result i64) (i64.le_u (local.get 0) (i64.const 1)) - (then (i64.const 1)) - (else - (i64.add - (call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib)) - (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib)) - ) - ) - ) - ) - - (elem declare func $even $odd) - (global $even (ref $ll) (ref.func $even)) - (global $odd (ref $ll) (ref.func $odd)) - - (func $even (export "even") (type $ll) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 44)) - (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd))) - ) - ) - (func $odd (export "odd") (type $ll) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 99)) - (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even))) - ) - ) -) - -(assert_return (invoke "run" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "run" (i32.const 3)) (i32.const -9)) - -(assert_trap (invoke "null") "null function") - -(assert_return (invoke "fac" (i64.const 0)) (i64.const 1)) -(assert_return (invoke "fac" (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac" (i64.const 5)) (i64.const 120)) -(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776)) -(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120)) -(assert_return - (invoke "fac-acc" (i64.const 25) (i64.const 1)) - (i64.const 7034535277573963776) -) - -(assert_return (invoke "fib" (i64.const 0)) (i64.const 1)) -(assert_return (invoke "fib" (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fib" (i64.const 2)) (i64.const 2)) -(assert_return (invoke "fib" (i64.const 5)) (i64.const 8)) -(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946)) - -(assert_return (invoke "even" (i64.const 0)) (i64.const 44)) -(assert_return (invoke "even" (i64.const 1)) (i64.const 99)) -(assert_return (invoke "even" (i64.const 100)) (i64.const 44)) -(assert_return (invoke "even" (i64.const 77)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 0)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 1)) (i64.const 44)) -(assert_return (invoke "odd" (i64.const 200)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 77)) (i64.const 44)) - - - -(assert_invalid - (module - (type $t (func)) - (func $f (param $r externref) - (call_ref $t (local.get $r)) - ) - ) - "type mismatch" -) diff --git a/test/spec/custom.wast b/test/spec/custom.wast deleted file mode 100644 index fb04f2f6b97..00000000000 --- a/test/spec/custom.wast +++ /dev/null @@ -1,120 +0,0 @@ -(module binary - "\00asm" "\01\00\00\00" - "\00\24\10" "a custom section" "this is the payload" - "\00\20\10" "a custom section" "this is payload" - "\00\11\10" "a custom section" "" - "\00\10\00" "" "this is payload" - "\00\01\00" "" "" - "\00\24\10" "\00\00custom sectio\00" "this is the payload" - "\00\24\10" "\ef\bb\bfa custom sect" "this is the payload" - "\00\24\10" "a custom sect\e2\8c\a3" "this is the payload" - "\00\1f\16" "module within a module" "\00asm" "\01\00\00\00" -) - -(module binary - "\00asm" "\01\00\00\00" - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\01\01\00" ;; type section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\02\01\00" ;; import section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\03\01\00" ;; function section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\04\01\00" ;; table section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\05\01\00" ;; memory section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\06\01\00" ;; global section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\07\01\00" ;; export section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\09\01\00" ;; element section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\0a\01\00" ;; code section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" - "\0b\01\00" ;; data section - "\00\0e\06" "custom" "payload" - "\00\0e\06" "custom" "payload" -) - -(module binary - "\00asm" "\01\00\00\00" - "\01\07\01\60\02\7f\7f\01\7f" ;; type section - "\00\1a\06" "custom" "this is the payload" ;; custom section - "\03\02\01\00" ;; function section - "\07\0a\01\06\61\64\64\54\77\6f\00\00" ;; export section - "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section - "\00\1b\07" "custom2" "this is the payload" ;; custom section -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00" - ) - "unexpected end" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\00" - ) - "unexpected end" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\00\00\05\01\00\07\00\00" - ) - "unexpected end" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\26\10" "a custom section" "this is the payload" - ) - "unexpected end" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\25\10" "a custom section" "this is the payload" - "\00\24\10" "a custom section" "this is the payload" - ) - "invalid section id" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\07\01\60\02\7f\7f\01\7f" ;; type section - "\00\25\10" "a custom section" "this is the payload" ;; invalid length! - "\03\02\01\00" ;; function section - "\0a\09\01\07\00\20\00\20\01\6a\0b" ;; code section - "\00\1b\07" "custom2" "this is the payload" ;; custom section - ) - "function and code section have inconsistent lengths" -) - -;; Test concatenated modules. -(assert_malformed - (module binary - "\00asm\01\00\00\00" - "\00asm\01\00\00\00" - ) - "length out of bounds" -) diff --git a/test/spec/endianness.wast b/test/spec/endianness.wast deleted file mode 100644 index 4f28a168f2a..00000000000 --- a/test/spec/endianness.wast +++ /dev/null @@ -1,217 +0,0 @@ -(module - (memory 1) - - ;; Stores an i16 value in little-endian-format - (func $i16_store_little (param $address i32) (param $value i32) - (i32.store8 (local.get $address) (local.get $value)) - (i32.store8 (i32.add (local.get $address) (i32.const 1)) (i32.shr_u (local.get $value) (i32.const 8))) - ) - - ;; Stores an i32 value in little-endian format - (func $i32_store_little (param $address i32) (param $value i32) - (call $i16_store_little (local.get $address) (local.get $value)) - (call $i16_store_little (i32.add (local.get $address) (i32.const 2)) (i32.shr_u (local.get $value) (i32.const 16))) - ) - - ;; Stores an i64 value in little-endian format - (func $i64_store_little (param $address i32) (param $value i64) - (call $i32_store_little (local.get $address) (i32.wrap_i64 (local.get $value))) - (call $i32_store_little (i32.add (local.get $address) (i32.const 4)) (i32.wrap_i64 (i64.shr_u (local.get $value) (i64.const 32)))) - ) - - ;; Loads an i16 value in little-endian format - (func $i16_load_little (param $address i32) (result i32) - (i32.or - (i32.load8_u (local.get $address)) - (i32.shl (i32.load8_u (i32.add (local.get $address) (i32.const 1))) (i32.const 8)) - ) - ) - - ;; Loads an i32 value in little-endian format - (func $i32_load_little (param $address i32) (result i32) - (i32.or - (call $i16_load_little (local.get $address)) - (i32.shl (call $i16_load_little (i32.add (local.get $address) (i32.const 2))) (i32.const 16)) - ) - ) - - ;; Loads an i64 value in little-endian format - (func $i64_load_little (param $address i32) (result i64) - (i64.or - (i64.extend_i32_u (call $i32_load_little (local.get $address))) - (i64.shl (i64.extend_i32_u (call $i32_load_little (i32.add (local.get $address) (i32.const 4)))) (i64.const 32)) - ) - ) - - (func (export "i32_load16_s") (param $value i32) (result i32) - (call $i16_store_little (i32.const 0) (local.get $value)) - (i32.load16_s (i32.const 0)) - ) - - (func (export "i32_load16_u") (param $value i32) (result i32) - (call $i16_store_little (i32.const 0) (local.get $value)) - (i32.load16_u (i32.const 0)) - ) - - (func (export "i32_load") (param $value i32) (result i32) - (call $i32_store_little (i32.const 0) (local.get $value)) - (i32.load (i32.const 0)) - ) - - (func (export "i64_load16_s") (param $value i64) (result i64) - (call $i16_store_little (i32.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load16_s (i32.const 0)) - ) - - (func (export "i64_load16_u") (param $value i64) (result i64) - (call $i16_store_little (i32.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load16_u (i32.const 0)) - ) - - (func (export "i64_load32_s") (param $value i64) (result i64) - (call $i32_store_little (i32.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load32_s (i32.const 0)) - ) - - (func (export "i64_load32_u") (param $value i64) (result i64) - (call $i32_store_little (i32.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load32_u (i32.const 0)) - ) - - (func (export "i64_load") (param $value i64) (result i64) - (call $i64_store_little (i32.const 0) (local.get $value)) - (i64.load (i32.const 0)) - ) - - (func (export "f32_load") (param $value f32) (result f32) - (call $i32_store_little (i32.const 0) (i32.reinterpret_f32 (local.get $value))) - (f32.load (i32.const 0)) - ) - - (func (export "f64_load") (param $value f64) (result f64) - (call $i64_store_little (i32.const 0) (i64.reinterpret_f64 (local.get $value))) - (f64.load (i32.const 0)) - ) - - - (func (export "i32_store16") (param $value i32) (result i32) - (i32.store16 (i32.const 0) (local.get $value)) - (call $i16_load_little (i32.const 0)) - ) - - (func (export "i32_store") (param $value i32) (result i32) - (i32.store (i32.const 0) (local.get $value)) - (call $i32_load_little (i32.const 0)) - ) - - (func (export "i64_store16") (param $value i64) (result i64) - (i64.store16 (i32.const 0) (local.get $value)) - (i64.extend_i32_u (call $i16_load_little (i32.const 0))) - ) - - (func (export "i64_store32") (param $value i64) (result i64) - (i64.store32 (i32.const 0) (local.get $value)) - (i64.extend_i32_u (call $i32_load_little (i32.const 0))) - ) - - (func (export "i64_store") (param $value i64) (result i64) - (i64.store (i32.const 0) (local.get $value)) - (call $i64_load_little (i32.const 0)) - ) - - (func (export "f32_store") (param $value f32) (result f32) - (f32.store (i32.const 0) (local.get $value)) - (f32.reinterpret_i32 (call $i32_load_little (i32.const 0))) - ) - - (func (export "f64_store") (param $value f64) (result f64) - (f64.store (i32.const 0) (local.get $value)) - (f64.reinterpret_i64 (call $i64_load_little (i32.const 0))) - ) -) - -(assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_load16_s" (i32.const -4242)) (i32.const -4242)) -(assert_return (invoke "i32_load16_s" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_load16_s" (i32.const 0x3210)) (i32.const 0x3210)) - -(assert_return (invoke "i32_load16_u" (i32.const -1)) (i32.const 0xFFFF)) -(assert_return (invoke "i32_load16_u" (i32.const -4242)) (i32.const 61294)) -(assert_return (invoke "i32_load16_u" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_load16_u" (i32.const 0xCAFE)) (i32.const 0xCAFE)) - -(assert_return (invoke "i32_load" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_load" (i32.const -42424242)) (i32.const -42424242)) -(assert_return (invoke "i32_load" (i32.const 42424242)) (i32.const 42424242)) -(assert_return (invoke "i32_load" (i32.const 0xABAD1DEA)) (i32.const 0xABAD1DEA)) - -(assert_return (invoke "i64_load16_s" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load16_s" (i64.const -4242)) (i64.const -4242)) -(assert_return (invoke "i64_load16_s" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_load16_s" (i64.const 0x3210)) (i64.const 0x3210)) - -(assert_return (invoke "i64_load16_u" (i64.const -1)) (i64.const 0xFFFF)) -(assert_return (invoke "i64_load16_u" (i64.const -4242)) (i64.const 61294)) -(assert_return (invoke "i64_load16_u" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_load16_u" (i64.const 0xCAFE)) (i64.const 0xCAFE)) - -(assert_return (invoke "i64_load32_s" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load32_s" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_load32_s" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_load32_s" (i64.const 0x12345678)) (i64.const 0x12345678)) - -(assert_return (invoke "i64_load32_u" (i64.const -1)) (i64.const 0xFFFFFFFF)) -(assert_return (invoke "i64_load32_u" (i64.const -42424242)) (i64.const 4252543054)) -(assert_return (invoke "i64_load32_u" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_load32_u" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) - -(assert_return (invoke "i64_load" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_load" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) -(assert_return (invoke "i64_load" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) - -(assert_return (invoke "f32_load" (f32.const -1)) (f32.const -1)) -(assert_return (invoke "f32_load" (f32.const 1234e-5)) (f32.const 1234e-5)) -(assert_return (invoke "f32_load" (f32.const 4242.4242)) (f32.const 4242.4242)) -(assert_return (invoke "f32_load" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) - -(assert_return (invoke "f64_load" (f64.const -1)) (f64.const -1)) -(assert_return (invoke "f64_load" (f64.const 123456789e-5)) (f64.const 123456789e-5)) -(assert_return (invoke "f64_load" (f64.const 424242.424242)) (f64.const 424242.424242)) -(assert_return (invoke "f64_load" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) - - -(assert_return (invoke "i32_store16" (i32.const -1)) (i32.const 0xFFFF)) -(assert_return (invoke "i32_store16" (i32.const -4242)) (i32.const 61294)) -(assert_return (invoke "i32_store16" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_store16" (i32.const 0xCAFE)) (i32.const 0xCAFE)) - -(assert_return (invoke "i32_store" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_store" (i32.const -4242)) (i32.const -4242)) -(assert_return (invoke "i32_store" (i32.const 42424242)) (i32.const 42424242)) -(assert_return (invoke "i32_store" (i32.const 0xDEADCAFE)) (i32.const 0xDEADCAFE)) - -(assert_return (invoke "i64_store16" (i64.const -1)) (i64.const 0xFFFF)) -(assert_return (invoke "i64_store16" (i64.const -4242)) (i64.const 61294)) -(assert_return (invoke "i64_store16" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_store16" (i64.const 0xCAFE)) (i64.const 0xCAFE)) - -(assert_return (invoke "i64_store32" (i64.const -1)) (i64.const 0xFFFFFFFF)) -(assert_return (invoke "i64_store32" (i64.const -4242)) (i64.const 4294963054)) -(assert_return (invoke "i64_store32" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_store32" (i64.const 0xDEADCAFE)) (i64.const 0xDEADCAFE)) - -(assert_return (invoke "i64_store" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_store" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_store" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) -(assert_return (invoke "i64_store" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) - -(assert_return (invoke "f32_store" (f32.const -1)) (f32.const -1)) -(assert_return (invoke "f32_store" (f32.const 1234e-5)) (f32.const 1234e-5)) -(assert_return (invoke "f32_store" (f32.const 4242.4242)) (f32.const 4242.4242)) -(assert_return (invoke "f32_store" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) - -(assert_return (invoke "f64_store" (f64.const -1)) (f64.const -1)) -(assert_return (invoke "f64_store" (f64.const 123456789e-5)) (f64.const 123456789e-5)) -(assert_return (invoke "f64_store" (f64.const 424242.424242)) (f64.const 424242.424242)) -(assert_return (invoke "f64_store" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) diff --git a/test/spec/endianness64.wast b/test/spec/endianness64.wast deleted file mode 100644 index e583ea9b484..00000000000 --- a/test/spec/endianness64.wast +++ /dev/null @@ -1,217 +0,0 @@ -(module - (memory i64 1) - - ;; Stores an i16 value in little-endian-format - (func $i16_store_little (param $address i64) (param $value i32) - (i32.store8 (local.get $address) (local.get $value)) - (i32.store8 (i64.add (local.get $address) (i64.const 1)) (i32.shr_u (local.get $value) (i32.const 8))) - ) - - ;; Stores an i32 value in little-endian format - (func $i32_store_little (param $address i64) (param $value i32) - (call $i16_store_little (local.get $address) (local.get $value)) - (call $i16_store_little (i64.add (local.get $address) (i64.const 2)) (i32.shr_u (local.get $value) (i32.const 16))) - ) - - ;; Stores an i64 value in little-endian format - (func $i64_store_little (param $address i64) (param $value i64) - (call $i32_store_little (local.get $address) (i32.wrap_i64 (local.get $value))) - (call $i32_store_little (i64.add (local.get $address) (i64.const 4)) (i32.wrap_i64 (i64.shr_u (local.get $value) (i64.const 32)))) - ) - - ;; Loads an i16 value in little-endian format - (func $i16_load_little (param $address i64) (result i32) - (i32.or - (i32.load8_u (local.get $address)) - (i32.shl (i32.load8_u (i64.add (local.get $address) (i64.const 1))) (i32.const 8)) - ) - ) - - ;; Loads an i32 value in little-endian format - (func $i32_load_little (param $address i64) (result i32) - (i32.or - (call $i16_load_little (local.get $address)) - (i32.shl (call $i16_load_little (i64.add (local.get $address) (i64.const 2))) (i32.const 16)) - ) - ) - - ;; Loads an i64 value in little-endian format - (func $i64_load_little (param $address i64) (result i64) - (i64.or - (i64.extend_i32_u (call $i32_load_little (local.get $address))) - (i64.shl (i64.extend_i32_u (call $i32_load_little (i64.add (local.get $address) (i64.const 4)))) (i64.const 32)) - ) - ) - - (func (export "i32_load16_s") (param $value i32) (result i32) - (call $i16_store_little (i64.const 0) (local.get $value)) - (i32.load16_s (i64.const 0)) - ) - - (func (export "i32_load16_u") (param $value i32) (result i32) - (call $i16_store_little (i64.const 0) (local.get $value)) - (i32.load16_u (i64.const 0)) - ) - - (func (export "i32_load") (param $value i32) (result i32) - (call $i32_store_little (i64.const 0) (local.get $value)) - (i32.load (i64.const 0)) - ) - - (func (export "i64_load16_s") (param $value i64) (result i64) - (call $i16_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load16_s (i64.const 0)) - ) - - (func (export "i64_load16_u") (param $value i64) (result i64) - (call $i16_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load16_u (i64.const 0)) - ) - - (func (export "i64_load32_s") (param $value i64) (result i64) - (call $i32_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load32_s (i64.const 0)) - ) - - (func (export "i64_load32_u") (param $value i64) (result i64) - (call $i32_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) - (i64.load32_u (i64.const 0)) - ) - - (func (export "i64_load") (param $value i64) (result i64) - (call $i64_store_little (i64.const 0) (local.get $value)) - (i64.load (i64.const 0)) - ) - - (func (export "f32_load") (param $value f32) (result f32) - (call $i32_store_little (i64.const 0) (i32.reinterpret_f32 (local.get $value))) - (f32.load (i64.const 0)) - ) - - (func (export "f64_load") (param $value f64) (result f64) - (call $i64_store_little (i64.const 0) (i64.reinterpret_f64 (local.get $value))) - (f64.load (i64.const 0)) - ) - - - (func (export "i32_store16") (param $value i32) (result i32) - (i32.store16 (i64.const 0) (local.get $value)) - (call $i16_load_little (i64.const 0)) - ) - - (func (export "i32_store") (param $value i32) (result i32) - (i32.store (i64.const 0) (local.get $value)) - (call $i32_load_little (i64.const 0)) - ) - - (func (export "i64_store16") (param $value i64) (result i64) - (i64.store16 (i64.const 0) (local.get $value)) - (i64.extend_i32_u (call $i16_load_little (i64.const 0))) - ) - - (func (export "i64_store32") (param $value i64) (result i64) - (i64.store32 (i64.const 0) (local.get $value)) - (i64.extend_i32_u (call $i32_load_little (i64.const 0))) - ) - - (func (export "i64_store") (param $value i64) (result i64) - (i64.store (i64.const 0) (local.get $value)) - (call $i64_load_little (i64.const 0)) - ) - - (func (export "f32_store") (param $value f32) (result f32) - (f32.store (i64.const 0) (local.get $value)) - (f32.reinterpret_i32 (call $i32_load_little (i64.const 0))) - ) - - (func (export "f64_store") (param $value f64) (result f64) - (f64.store (i64.const 0) (local.get $value)) - (f64.reinterpret_i64 (call $i64_load_little (i64.const 0))) - ) -) - -(assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_load16_s" (i32.const -4242)) (i32.const -4242)) -(assert_return (invoke "i32_load16_s" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_load16_s" (i32.const 0x3210)) (i32.const 0x3210)) - -(assert_return (invoke "i32_load16_u" (i32.const -1)) (i32.const 0xFFFF)) -(assert_return (invoke "i32_load16_u" (i32.const -4242)) (i32.const 61294)) -(assert_return (invoke "i32_load16_u" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_load16_u" (i32.const 0xCAFE)) (i32.const 0xCAFE)) - -(assert_return (invoke "i32_load" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_load" (i32.const -42424242)) (i32.const -42424242)) -(assert_return (invoke "i32_load" (i32.const 42424242)) (i32.const 42424242)) -(assert_return (invoke "i32_load" (i32.const 0xABAD1DEA)) (i32.const 0xABAD1DEA)) - -(assert_return (invoke "i64_load16_s" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load16_s" (i64.const -4242)) (i64.const -4242)) -(assert_return (invoke "i64_load16_s" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_load16_s" (i64.const 0x3210)) (i64.const 0x3210)) - -(assert_return (invoke "i64_load16_u" (i64.const -1)) (i64.const 0xFFFF)) -(assert_return (invoke "i64_load16_u" (i64.const -4242)) (i64.const 61294)) -(assert_return (invoke "i64_load16_u" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_load16_u" (i64.const 0xCAFE)) (i64.const 0xCAFE)) - -(assert_return (invoke "i64_load32_s" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load32_s" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_load32_s" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_load32_s" (i64.const 0x12345678)) (i64.const 0x12345678)) - -(assert_return (invoke "i64_load32_u" (i64.const -1)) (i64.const 0xFFFFFFFF)) -(assert_return (invoke "i64_load32_u" (i64.const -42424242)) (i64.const 4252543054)) -(assert_return (invoke "i64_load32_u" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_load32_u" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) - -(assert_return (invoke "i64_load" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_load" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_load" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) -(assert_return (invoke "i64_load" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) - -(assert_return (invoke "f32_load" (f32.const -1)) (f32.const -1)) -(assert_return (invoke "f32_load" (f32.const 1234e-5)) (f32.const 1234e-5)) -(assert_return (invoke "f32_load" (f32.const 4242.4242)) (f32.const 4242.4242)) -(assert_return (invoke "f32_load" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) - -(assert_return (invoke "f64_load" (f64.const -1)) (f64.const -1)) -(assert_return (invoke "f64_load" (f64.const 123456789e-5)) (f64.const 123456789e-5)) -(assert_return (invoke "f64_load" (f64.const 424242.424242)) (f64.const 424242.424242)) -(assert_return (invoke "f64_load" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) - - -(assert_return (invoke "i32_store16" (i32.const -1)) (i32.const 0xFFFF)) -(assert_return (invoke "i32_store16" (i32.const -4242)) (i32.const 61294)) -(assert_return (invoke "i32_store16" (i32.const 42)) (i32.const 42)) -(assert_return (invoke "i32_store16" (i32.const 0xCAFE)) (i32.const 0xCAFE)) - -(assert_return (invoke "i32_store" (i32.const -1)) (i32.const -1)) -(assert_return (invoke "i32_store" (i32.const -4242)) (i32.const -4242)) -(assert_return (invoke "i32_store" (i32.const 42424242)) (i32.const 42424242)) -(assert_return (invoke "i32_store" (i32.const 0xDEADCAFE)) (i32.const 0xDEADCAFE)) - -(assert_return (invoke "i64_store16" (i64.const -1)) (i64.const 0xFFFF)) -(assert_return (invoke "i64_store16" (i64.const -4242)) (i64.const 61294)) -(assert_return (invoke "i64_store16" (i64.const 42)) (i64.const 42)) -(assert_return (invoke "i64_store16" (i64.const 0xCAFE)) (i64.const 0xCAFE)) - -(assert_return (invoke "i64_store32" (i64.const -1)) (i64.const 0xFFFFFFFF)) -(assert_return (invoke "i64_store32" (i64.const -4242)) (i64.const 4294963054)) -(assert_return (invoke "i64_store32" (i64.const 42424242)) (i64.const 42424242)) -(assert_return (invoke "i64_store32" (i64.const 0xDEADCAFE)) (i64.const 0xDEADCAFE)) - -(assert_return (invoke "i64_store" (i64.const -1)) (i64.const -1)) -(assert_return (invoke "i64_store" (i64.const -42424242)) (i64.const -42424242)) -(assert_return (invoke "i64_store" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) -(assert_return (invoke "i64_store" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) - -(assert_return (invoke "f32_store" (f32.const -1)) (f32.const -1)) -(assert_return (invoke "f32_store" (f32.const 1234e-5)) (f32.const 1234e-5)) -(assert_return (invoke "f32_store" (f32.const 4242.4242)) (f32.const 4242.4242)) -(assert_return (invoke "f32_store" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) - -(assert_return (invoke "f64_store" (f64.const -1)) (f64.const -1)) -(assert_return (invoke "f64_store" (f64.const 123456789e-5)) (f64.const 123456789e-5)) -(assert_return (invoke "f64_store" (f64.const 424242.424242)) (f64.const 424242.424242)) -(assert_return (invoke "f64_store" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) diff --git a/test/spec/exports.wast b/test/spec/exports.wast deleted file mode 100644 index ef1c4c17eb3..00000000000 --- a/test/spec/exports.wast +++ /dev/null @@ -1,198 +0,0 @@ -;; Functions - -(module (func) (export "a" (func 0))) -(module (func) (export "a" (func 0)) (export "b" (func 0))) -(module (func) (func) (export "a" (func 0)) (export "b" (func 1))) - -(module (func (export "a"))) -(module (func (export "a") (export "b") (export "c"))) -(module (func (export "a") (export "b") (param i32))) -(module (func) (export "a" (func 0))) -(module (func $a (export "a"))) -(module (func $a) (export "a" (func $a))) -(module (export "a" (func 0)) (func)) -(module (export "a" (func $a)) (func $a)) - -(module $Func - (export "e" (func $f)) - (func $f (param $n i32) (result i32) - (return (i32.add (local.get $n) (i32.const 1))) - ) -) -(assert_return (invoke "e" (i32.const 42)) (i32.const 43)) -(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) -(module) -(module $Other1) -(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) - -(assert_invalid - (module (func) (export "a" (func 1))) - "unknown function" -) -(assert_invalid - (module (func) (export "a" (func 0)) (export "a" (func 0))) - "duplicate export name" -) -(assert_invalid - (module (func) (func) (export "a" (func 0)) (export "a" (func 1))) - "duplicate export name" -) -(assert_invalid - (module (func) (global i32 (i32.const 0)) (export "a" (func 0)) (export "a" (global 0))) - "duplicate export name" -) -(assert_invalid - (module (func) (table 0 funcref) (export "a" (func 0)) (export "a" (table 0))) - "duplicate export name" -) -(assert_invalid - (module (func) (memory 0) (export "a" (func 0)) (export "a" (memory 0))) - "duplicate export name" -) - - -;; Globals - -(module (global i32 (i32.const 0)) (export "a" (global 0))) -(module (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 0))) -(module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 1))) - -(module (global (export "a") i32 (i32.const 0))) -(module (global i32 (i32.const 0)) (export "a" (global 0))) -(module (global $a (export "a") i32 (i32.const 0))) -(module (global $a i32 (i32.const 0)) (export "a" (global $a))) -(module (export "a" (global 0)) (global i32 (i32.const 0))) -(module (export "a" (global $a)) (global $a i32 (i32.const 0))) - -(module $Global - (export "e" (global $g)) - (global $g i32 (i32.const 42)) -) -(assert_return (get "e") (i32.const 42)) -(assert_return (get $Global "e") (i32.const 42)) -(module) -(module $Other2) -(assert_return (get $Global "e") (i32.const 42)) - -(assert_invalid - (module (global i32 (i32.const 0)) (export "a" (global 1))) - "unknown global" -) -(assert_invalid - (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0))) - "duplicate export name" -) -(assert_invalid - (module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 1))) - "duplicate export name" -) -(assert_invalid - (module (global i32 (i32.const 0)) (func) (export "a" (global 0)) (export "a" (func 0))) - "duplicate export name" -) -(assert_invalid - (module (global i32 (i32.const 0)) (table 0 funcref) (export "a" (global 0)) (export "a" (table 0))) - "duplicate export name" -) -(assert_invalid - (module (global i32 (i32.const 0)) (memory 0) (export "a" (global 0)) (export "a" (memory 0))) - "duplicate export name" -) - - -;; Tables - -(module (table 0 funcref) (export "a" (table 0))) -(module (table 0 funcref) (export "a" (table 0)) (export "b" (table 0))) -;; No multiple tables yet. -;; (module (table 0 funcref) (table 0 funcref) (export "a" (table 0)) (export "b" (table 1))) - -(module (table (export "a") 0 funcref)) -(module (table (export "a") 0 1 funcref)) -(module (table 0 funcref) (export "a" (table 0))) -(module (table 0 1 funcref) (export "a" (table 0))) -(module (table $a (export "a") 0 funcref)) -(module (table $a (export "a") 0 1 funcref)) -(module (table $a 0 funcref) (export "a" (table $a))) -(module (table $a 0 1 funcref) (export "a" (table $a))) -(module (export "a" (table 0)) (table 0 funcref)) -(module (export "a" (table 0)) (table 0 1 funcref)) -(module (export "a" (table $a)) (table $a 0 funcref)) -(module (export "a" (table $a)) (table $a 0 1 funcref)) - -(; TODO: access table ;) - -(assert_invalid - (module (table 0 funcref) (export "a" (table 1))) - "unknown table" -) -(assert_invalid - (module (table 0 funcref) (export "a" (table 0)) (export "a" (table 0))) - "duplicate export name" -) -;; No multiple tables yet. -;; (assert_invalid -;; (module (table 0 funcref) (table 0 funcref) (export "a" (table 0)) (export "a" (table 1))) -;; "duplicate export name" -;; ) -(assert_invalid - (module (table 0 funcref) (func) (export "a" (table 0)) (export "a" (func 0))) - "duplicate export name" -) -(assert_invalid - (module (table 0 funcref) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0))) - "duplicate export name" -) -(assert_invalid - (module (table 0 funcref) (memory 0) (export "a" (table 0)) (export "a" (memory 0))) - "duplicate export name" -) - - -;; Memories - -(module (memory 0) (export "a" (memory 0))) -(module (memory 0) (export "a" (memory 0)) (export "b" (memory 0))) -;; No multiple memories yet. -;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "b" (memory 1))) - -(module (memory (export "a") 0)) -(module (memory (export "a") 0 1)) -(module (memory 0) (export "a" (memory 0))) -(module (memory 0 1) (export "a" (memory 0))) -(module (memory $a (export "a") 0)) -(module (memory $a (export "a") 0 1)) -(module (memory $a 0) (export "a" (memory $a))) -(module (memory $a 0 1) (export "a" (memory $a))) -(module (export "a" (memory 0)) (memory 0)) -(module (export "a" (memory 0)) (memory 0 1)) -(module (export "a" (memory $a)) (memory $a 0)) -(module (export "a" (memory $a)) (memory $a 0 1)) - -(; TODO: access memory ;) - -(assert_invalid - (module (memory 0) (export "a" (memory 1))) - "unknown memory" -) -(assert_invalid - (module (memory 0) (export "a" (memory 0)) (export "a" (memory 0))) - "duplicate export name" -) -;; No multiple memories yet. -;; (assert_invalid -;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "a" (memory 1))) -;; "duplicate export name" -;; ) -(assert_invalid - (module (memory 0) (func) (export "a" (memory 0)) (export "a" (func 0))) - "duplicate export name" -) -(assert_invalid - (module (memory 0) (global i32 (i32.const 0)) (export "a" (memory 0)) (export "a" (global 0))) - "duplicate export name" -) -(assert_invalid - (module (memory 0) (table 0 funcref) (export "a" (memory 0)) (export "a" (table 0))) - "duplicate export name" -) diff --git a/test/spec/f32_bitwise.wast b/test/spec/f32_bitwise.wast deleted file mode 100644 index 8554d6741d0..00000000000 --- a/test/spec/f32_bitwise.wast +++ /dev/null @@ -1,376 +0,0 @@ -;; Test all the f32 bitwise operators on major boundary values and all special -;; values. - -(module - (func (export "abs") (param $x f32) (result f32) (f32.abs (local.get $x))) - (func (export "neg") (param $x f32) (result f32) (f32.neg (local.get $x))) - (func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (local.get $x) (local.get $y))) -) - -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1p-149)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p-149)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1p-149)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p-149)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1p-126)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p-126)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1p-126)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p-126)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1p-1)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p-1)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1p-1)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p-1)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1p+0)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1p+0)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -inf)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const inf)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -inf)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const inf)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -nan)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const nan)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -nan)) (f32.const -0x0p+0)) -(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const nan)) (f32.const 0x0p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x0p+0)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x0p+0)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x0p+0)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x0p+0)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1p-149)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1p-149)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1p-126)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1p-126)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1p-126)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1p-126)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1p-1)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1p-1)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1p-1)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1p-1)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1p+0)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1p+0)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1p+0)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1p+0)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -inf)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const inf)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -inf)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const inf)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const -nan)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-149) (f32.const nan)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const -nan)) (f32.const -0x1p-149)) -(assert_return (invoke "copysign" (f32.const 0x1p-149) (f32.const nan)) (f32.const 0x1p-149)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x0p+0)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x0p+0)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x0p+0)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x0p+0)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1p-149)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1p-149)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1p-126)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1p-126)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1p-126)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1p-126)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1p-1)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1p-1)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1p-1)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1p-1)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1p+0)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1p+0)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1p+0)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1p+0)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -inf)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const inf)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -inf)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const inf)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const -nan)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-126) (f32.const nan)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const -nan)) (f32.const -0x1p-126)) -(assert_return (invoke "copysign" (f32.const 0x1p-126) (f32.const nan)) (f32.const 0x1p-126)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x0p+0)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x0p+0)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x0p+0)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x0p+0)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1p-149)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1p-149)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1p-149)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1p-149)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1p-126)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1p-126)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1p-126)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1p-126)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1p-1)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1p-1)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1p-1)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1p-1)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1p+0)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1p+0)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1p+0)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1p+0)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -inf)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const inf)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -inf)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const inf)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const -nan)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p-1) (f32.const nan)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const -nan)) (f32.const -0x1p-1)) -(assert_return (invoke "copysign" (f32.const 0x1p-1) (f32.const nan)) (f32.const 0x1p-1)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x0p+0)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x0p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x0p+0)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x0p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1p-149)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1p-149)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1p-149)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1p-149)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1p-126)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1p-126)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1p-126)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1p-126)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1p-1)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1p-1)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1p-1)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1p-1)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1p+0)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1p+0)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -inf)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const inf)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -inf)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const inf)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const -nan)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1p+0) (f32.const nan)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const -nan)) (f32.const -0x1p+0)) -(assert_return (invoke "copysign" (f32.const 0x1p+0) (f32.const nan)) (f32.const 0x1p+0)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const inf)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const inf)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.921fb6p+2) (f32.const nan)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const 0x1.921fb6p+2) (f32.const nan)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -inf)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const inf)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -inf)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const inf)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const -nan)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -0x1.fffffep+127) (f32.const nan)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const -nan)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const 0x1.fffffep+127) (f32.const nan)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x0p+0)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x0p+0)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x0p+0)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x0p+0)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1p-149)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1p-149)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1p-149)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1p-149)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1p-126)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1p-126)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1p-126)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1p-126)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1p-1)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1p-1)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1p-1)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1p-1)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1p+0)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1p+0)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1p+0)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1p+0)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1.921fb6p+2)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1.921fb6p+2)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -0x1.fffffep+127)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const 0x1.fffffep+127)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -0x1.fffffep+127)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const 0x1.fffffep+127)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -inf)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const inf)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -inf)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const inf)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const -nan)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const -inf) (f32.const nan)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const -nan)) (f32.const -inf)) -(assert_return (invoke "copysign" (f32.const inf) (f32.const nan)) (f32.const inf)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x0p+0)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x0p+0)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x0p+0)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x0p+0)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1p-149)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1p-149)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1p-149)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1p-149)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1p-126)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1p-126)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1p-126)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1p-126)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1p-1)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1p-1)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1p-1)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1p-1)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1p+0)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1p+0)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1p+0)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1p+0)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1.921fb6p+2)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -0x1.fffffep+127)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const 0x1.fffffep+127)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -0x1.fffffep+127)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const 0x1.fffffep+127)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -inf)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const inf)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -inf)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const inf)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const -nan)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const -nan) (f32.const nan)) (f32.const nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const -nan)) (f32.const -nan)) -(assert_return (invoke "copysign" (f32.const nan) (f32.const nan)) (f32.const nan)) -(assert_return (invoke "abs" (f32.const -0x0p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "abs" (f32.const 0x0p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "abs" (f32.const -0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "abs" (f32.const 0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "abs" (f32.const -0x1p-126)) (f32.const 0x1p-126)) -(assert_return (invoke "abs" (f32.const 0x1p-126)) (f32.const 0x1p-126)) -(assert_return (invoke "abs" (f32.const -0x1p-1)) (f32.const 0x1p-1)) -(assert_return (invoke "abs" (f32.const 0x1p-1)) (f32.const 0x1p-1)) -(assert_return (invoke "abs" (f32.const -0x1p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "abs" (f32.const 0x1p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "abs" (f32.const -0x1.921fb6p+2)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "abs" (f32.const 0x1.921fb6p+2)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "abs" (f32.const -0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "abs" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "abs" (f32.const -inf)) (f32.const inf)) -(assert_return (invoke "abs" (f32.const inf)) (f32.const inf)) -(assert_return (invoke "abs" (f32.const -nan)) (f32.const nan)) -(assert_return (invoke "abs" (f32.const nan)) (f32.const nan)) -(assert_return (invoke "neg" (f32.const -0x0p+0)) (f32.const 0x0p+0)) -(assert_return (invoke "neg" (f32.const 0x0p+0)) (f32.const -0x0p+0)) -(assert_return (invoke "neg" (f32.const -0x1p-149)) (f32.const 0x1p-149)) -(assert_return (invoke "neg" (f32.const 0x1p-149)) (f32.const -0x1p-149)) -(assert_return (invoke "neg" (f32.const -0x1p-126)) (f32.const 0x1p-126)) -(assert_return (invoke "neg" (f32.const 0x1p-126)) (f32.const -0x1p-126)) -(assert_return (invoke "neg" (f32.const -0x1p-1)) (f32.const 0x1p-1)) -(assert_return (invoke "neg" (f32.const 0x1p-1)) (f32.const -0x1p-1)) -(assert_return (invoke "neg" (f32.const -0x1p+0)) (f32.const 0x1p+0)) -(assert_return (invoke "neg" (f32.const 0x1p+0)) (f32.const -0x1p+0)) -(assert_return (invoke "neg" (f32.const -0x1.921fb6p+2)) (f32.const 0x1.921fb6p+2)) -(assert_return (invoke "neg" (f32.const 0x1.921fb6p+2)) (f32.const -0x1.921fb6p+2)) -(assert_return (invoke "neg" (f32.const -0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) -(assert_return (invoke "neg" (f32.const 0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) -(assert_return (invoke "neg" (f32.const -inf)) (f32.const inf)) -(assert_return (invoke "neg" (f32.const inf)) (f32.const -inf)) -(assert_return (invoke "neg" (f32.const -nan)) (f32.const nan)) -(assert_return (invoke "neg" (f32.const nan)) (f32.const -nan)) - - -;; Type check - -(assert_invalid (module (func (result f32) (f32.copysign (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.abs (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.neg (i64.const 0)))) "type mismatch") diff --git a/test/spec/f32_cmp.wast b/test/spec/f32_cmp.wast deleted file mode 100644 index 0dd7167c038..00000000000 --- a/test/spec/f32_cmp.wast +++ /dev/null @@ -1,2422 +0,0 @@ -;; Test all the f32 comparison operators on major boundary values and all -;; special values. - -(module - (func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (local.get $x) (local.get $y))) - (func (export "ne") (param $x f32) (param $y f32) (result i32) (f32.ne (local.get $x) (local.get $y))) - (func (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (local.get $x) (local.get $y))) - (func (export "le") (param $x f32) (param $y f32) (result i32) (f32.le (local.get $x) (local.get $y))) - (func (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (local.get $x) (local.get $y))) - (func (export "ge") (param $x f32) (param $y f32) (result i32) (f32.ge (local.get $x) (local.get $y))) -) - -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "eq" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const inf) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "ne" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "lt" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "le" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f32.const inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "gt" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x0p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-149) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-126) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p-1) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1p+0) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.921fb6p+2) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const 0x1.fffffep+127) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1p-149)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1p-126)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1.921fb6p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const 0x1.fffffep+127)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const inf) (f32.const inf)) (i32.const 1)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const inf) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1p-149)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1p-126)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1.921fb6p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const 0x1.fffffep+127)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const -nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const -nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan) (f32.const nan:0x200000)) (i32.const 0)) -(assert_return (invoke "ge" (f32.const nan:0x200000) (f32.const nan:0x200000)) (i32.const 0)) - - -;; Type check - -(assert_invalid (module (func (result f32) (f32.eq (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.ge (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.gt (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.le (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.lt (i64.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f32) (f32.ne (i64.const 0) (f64.const 0)))) "type mismatch") diff --git a/test/spec/f64_bitwise.wast b/test/spec/f64_bitwise.wast deleted file mode 100644 index f268a3e18fa..00000000000 --- a/test/spec/f64_bitwise.wast +++ /dev/null @@ -1,376 +0,0 @@ -;; Test all the f64 bitwise operators on major boundary values and all special -;; values. - -(module - (func (export "abs") (param $x f64) (result f64) (f64.abs (local.get $x))) - (func (export "neg") (param $x f64) (result f64) (f64.neg (local.get $x))) - (func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (local.get $x) (local.get $y))) -) - -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x1p-1)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x1p-1)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x1p-1)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x1p-1)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x1p+0)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x1p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x1p+0)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x1p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -inf)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const inf)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -inf)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const inf)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -nan)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const nan)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -nan)) (f64.const -0x0p+0)) -(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const nan)) (f64.const 0x0p+0)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -inf)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const inf)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -inf)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const inf)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const -nan)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1022) (f64.const nan)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const -nan)) (f64.const -0x1p-1022)) -(assert_return (invoke "copysign" (f64.const 0x1p-1022) (f64.const nan)) (f64.const 0x1p-1022)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x0p+0)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x0p+0)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x0p+0)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x0p+0)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x1p-1)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x1p-1)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x1p-1)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x1p-1)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x1p+0)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x1p+0)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x1p+0)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x1p+0)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -inf)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const inf)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -inf)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const inf)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const -nan)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p-1) (f64.const nan)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const -nan)) (f64.const -0x1p-1)) -(assert_return (invoke "copysign" (f64.const 0x1p-1) (f64.const nan)) (f64.const 0x1p-1)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x0p+0)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x0p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x0p+0)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x0p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x1p-1)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x1p-1)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x1p-1)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x1p-1)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x1p+0)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x1p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x1p+0)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x1p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -inf)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const inf)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -inf)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const inf)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const -nan)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1p+0) (f64.const nan)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const -nan)) (f64.const -0x1p+0)) -(assert_return (invoke "copysign" (f64.const 0x1p+0) (f64.const nan)) (f64.const 0x1p+0)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x0p+0)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x0p+0)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x0p+0)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x0p+0)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x1p-1022)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x1p-1022)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x1p-1022)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x1p-1022)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x1p-1)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x1p-1)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x1p-1)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x1p-1)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x1p+0)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x1p+0)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x1p+0)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x1p+0)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -inf)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const inf)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -inf)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const inf)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const -nan)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const -inf) (f64.const nan)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const -nan)) (f64.const -inf)) -(assert_return (invoke "copysign" (f64.const inf) (f64.const nan)) (f64.const inf)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x0p+0)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x0p+0)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x0p+0)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x0p+0)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x1p-1022)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x1p-1022)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x1p-1022)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x1p-1022)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x1p-1)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x1p-1)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x1p-1)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x1p-1)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x1p+0)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x1p+0)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x1p+0)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x1p+0)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -inf)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const inf)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -inf)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const inf)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const -nan)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const -nan) (f64.const nan)) (f64.const nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const -nan)) (f64.const -nan)) -(assert_return (invoke "copysign" (f64.const nan) (f64.const nan)) (f64.const nan)) -(assert_return (invoke "abs" (f64.const -0x0p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "abs" (f64.const 0x0p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "abs" (f64.const -0x0.0000000000001p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "abs" (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "abs" (f64.const -0x1p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "abs" (f64.const 0x1p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "abs" (f64.const -0x1p-1)) (f64.const 0x1p-1)) -(assert_return (invoke "abs" (f64.const 0x1p-1)) (f64.const 0x1p-1)) -(assert_return (invoke "abs" (f64.const -0x1p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "abs" (f64.const 0x1p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "abs" (f64.const -0x1.921fb54442d18p+2)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "abs" (f64.const 0x1.921fb54442d18p+2)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "abs" (f64.const -0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "abs" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "abs" (f64.const -inf)) (f64.const inf)) -(assert_return (invoke "abs" (f64.const inf)) (f64.const inf)) -(assert_return (invoke "abs" (f64.const -nan)) (f64.const nan)) -(assert_return (invoke "abs" (f64.const nan)) (f64.const nan)) -(assert_return (invoke "neg" (f64.const -0x0p+0)) (f64.const 0x0p+0)) -(assert_return (invoke "neg" (f64.const 0x0p+0)) (f64.const -0x0p+0)) -(assert_return (invoke "neg" (f64.const -0x0.0000000000001p-1022)) (f64.const 0x0.0000000000001p-1022)) -(assert_return (invoke "neg" (f64.const 0x0.0000000000001p-1022)) (f64.const -0x0.0000000000001p-1022)) -(assert_return (invoke "neg" (f64.const -0x1p-1022)) (f64.const 0x1p-1022)) -(assert_return (invoke "neg" (f64.const 0x1p-1022)) (f64.const -0x1p-1022)) -(assert_return (invoke "neg" (f64.const -0x1p-1)) (f64.const 0x1p-1)) -(assert_return (invoke "neg" (f64.const 0x1p-1)) (f64.const -0x1p-1)) -(assert_return (invoke "neg" (f64.const -0x1p+0)) (f64.const 0x1p+0)) -(assert_return (invoke "neg" (f64.const 0x1p+0)) (f64.const -0x1p+0)) -(assert_return (invoke "neg" (f64.const -0x1.921fb54442d18p+2)) (f64.const 0x1.921fb54442d18p+2)) -(assert_return (invoke "neg" (f64.const 0x1.921fb54442d18p+2)) (f64.const -0x1.921fb54442d18p+2)) -(assert_return (invoke "neg" (f64.const -0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) -(assert_return (invoke "neg" (f64.const 0x1.fffffffffffffp+1023)) (f64.const -0x1.fffffffffffffp+1023)) -(assert_return (invoke "neg" (f64.const -inf)) (f64.const inf)) -(assert_return (invoke "neg" (f64.const inf)) (f64.const -inf)) -(assert_return (invoke "neg" (f64.const -nan)) (f64.const nan)) -(assert_return (invoke "neg" (f64.const nan)) (f64.const -nan)) - - -;; Type check - -(assert_invalid (module (func (result f64) (f64.copysign (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.abs (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.neg (i64.const 0)))) "type mismatch") diff --git a/test/spec/f64_cmp.wast b/test/spec/f64_cmp.wast deleted file mode 100644 index dd79929d206..00000000000 --- a/test/spec/f64_cmp.wast +++ /dev/null @@ -1,2422 +0,0 @@ -;; Test all the f64 comparison operators on major boundary values and all -;; special values. - -(module - (func (export "eq") (param $x f64) (param $y f64) (result i32) (f64.eq (local.get $x) (local.get $y))) - (func (export "ne") (param $x f64) (param $y f64) (result i32) (f64.ne (local.get $x) (local.get $y))) - (func (export "lt") (param $x f64) (param $y f64) (result i32) (f64.lt (local.get $x) (local.get $y))) - (func (export "le") (param $x f64) (param $y f64) (result i32) (f64.le (local.get $x) (local.get $y))) - (func (export "gt") (param $x f64) (param $y f64) (result i32) (f64.gt (local.get $x) (local.get $y))) - (func (export "ge") (param $x f64) (param $y f64) (result i32) (f64.ge (local.get $x) (local.get $y))) -) - -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "lt" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "le" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "gt" (f64.const inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "gt" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x0.0000000000001p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1022) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p-1) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1p+0) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.921fb54442d18p+2) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x0p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x0.0000000000001p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x1p-1022)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x1p-1)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x1p+0)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x1.921fb54442d18p+2)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const inf) (f64.const inf)) (i32.const 1)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const inf) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x0p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x0.0000000000001p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x1p-1022)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x1p-1)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x1p+0)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x1.921fb54442d18p+2)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const 0x1.fffffffffffffp+1023)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const inf)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const -nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const -nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const nan)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan) (f64.const nan:0x4000000000000)) (i32.const 0)) -(assert_return (invoke "ge" (f64.const nan:0x4000000000000) (f64.const nan:0x4000000000000)) (i32.const 0)) - - -;; Type check - -(assert_invalid (module (func (result f64) (f64.eq (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.ge (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.gt (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.le (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.lt (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result f64) (f64.ne (i64.const 0) (f32.const 0)))) "type mismatch") diff --git a/test/spec/float_literals.wast b/test/spec/float_literals.wast deleted file mode 100644 index fefb91fbb76..00000000000 --- a/test/spec/float_literals.wast +++ /dev/null @@ -1,507 +0,0 @@ -;; Test floating-point literal parsing. - -(module - ;; f32 special values - (func (export "f32.nan") (result i32) (i32.reinterpret_f32 (f32.const nan))) - (func (export "f32.positive_nan") (result i32) (i32.reinterpret_f32 (f32.const +nan))) - (func (export "f32.negative_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan))) - (func (export "f32.plain_nan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x400000))) - (func (export "f32.informally_known_as_plain_snan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x200000))) - (func (export "f32.all_ones_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan:0x7fffff))) - (func (export "f32.misc_nan") (result i32) (i32.reinterpret_f32 (f32.const nan:0x012345))) - (func (export "f32.misc_positive_nan") (result i32) (i32.reinterpret_f32 (f32.const +nan:0x304050))) - (func (export "f32.misc_negative_nan") (result i32) (i32.reinterpret_f32 (f32.const -nan:0x2abcde))) - (func (export "f32.infinity") (result i32) (i32.reinterpret_f32 (f32.const inf))) - (func (export "f32.positive_infinity") (result i32) (i32.reinterpret_f32 (f32.const +inf))) - (func (export "f32.negative_infinity") (result i32) (i32.reinterpret_f32 (f32.const -inf))) - - ;; f32 numbers - (func (export "f32.zero") (result i32) (i32.reinterpret_f32 (f32.const 0x0.0p0))) - (func (export "f32.positive_zero") (result i32) (i32.reinterpret_f32 (f32.const +0x0.0p0))) - (func (export "f32.negative_zero") (result i32) (i32.reinterpret_f32 (f32.const -0x0.0p0))) - (func (export "f32.misc") (result i32) (i32.reinterpret_f32 (f32.const 0x1.921fb6p+2))) - (func (export "f32.min_positive") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-149))) - (func (export "f32.min_normal") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-126))) - (func (export "f32.max_finite") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffep+127))) - (func (export "f32.max_subnormal") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffcp-127))) - (func (export "f32.trailing_dot") (result i32) (i32.reinterpret_f32 (f32.const 0x1.p10))) - - ;; f32 in decimal format - (func (export "f32_dec.zero") (result i32) (i32.reinterpret_f32 (f32.const 0.0e0))) - (func (export "f32_dec.positive_zero") (result i32) (i32.reinterpret_f32 (f32.const +0.0e0))) - (func (export "f32_dec.negative_zero") (result i32) (i32.reinterpret_f32 (f32.const -0.0e0))) - (func (export "f32_dec.misc") (result i32) (i32.reinterpret_f32 (f32.const 6.28318548202514648))) - (func (export "f32_dec.min_positive") (result i32) (i32.reinterpret_f32 (f32.const 1.4013e-45))) - (func (export "f32_dec.min_normal") (result i32) (i32.reinterpret_f32 (f32.const 1.1754944e-38))) - (func (export "f32_dec.max_subnormal") (result i32) (i32.reinterpret_f32 (f32.const 1.1754942e-38))) - (func (export "f32_dec.max_finite") (result i32) (i32.reinterpret_f32 (f32.const 3.4028234e+38))) - (func (export "f32_dec.trailing_dot") (result i32) (i32.reinterpret_f32 (f32.const 1.e10))) - - ;; https://twitter.com/Archivd/status/994637336506912768 - (func (export "f32_dec.root_beer_float") (result i32) (i32.reinterpret_f32 (f32.const 1.000000119))) - - ;; f64 special values - (func (export "f64.nan") (result i64) (i64.reinterpret_f64 (f64.const nan))) - (func (export "f64.positive_nan") (result i64) (i64.reinterpret_f64 (f64.const +nan))) - (func (export "f64.negative_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan))) - (func (export "f64.plain_nan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x8000000000000))) - (func (export "f64.informally_known_as_plain_snan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x4000000000000))) - (func (export "f64.all_ones_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan:0xfffffffffffff))) - (func (export "f64.misc_nan") (result i64) (i64.reinterpret_f64 (f64.const nan:0x0123456789abc))) - (func (export "f64.misc_positive_nan") (result i64) (i64.reinterpret_f64 (f64.const +nan:0x3040506070809))) - (func (export "f64.misc_negative_nan") (result i64) (i64.reinterpret_f64 (f64.const -nan:0x2abcdef012345))) - (func (export "f64.infinity") (result i64) (i64.reinterpret_f64 (f64.const inf))) - (func (export "f64.positive_infinity") (result i64) (i64.reinterpret_f64 (f64.const +inf))) - (func (export "f64.negative_infinity") (result i64) (i64.reinterpret_f64 (f64.const -inf))) - - ;; f64 numbers - (func (export "f64.zero") (result i64) (i64.reinterpret_f64 (f64.const 0x0.0p0))) - (func (export "f64.positive_zero") (result i64) (i64.reinterpret_f64 (f64.const +0x0.0p0))) - (func (export "f64.negative_zero") (result i64) (i64.reinterpret_f64 (f64.const -0x0.0p0))) - (func (export "f64.misc") (result i64) (i64.reinterpret_f64 (f64.const 0x1.921fb54442d18p+2))) - (func (export "f64.min_positive") (result i64) (i64.reinterpret_f64 (f64.const 0x0.0000000000001p-1022))) - (func (export "f64.min_normal") (result i64) (i64.reinterpret_f64 (f64.const 0x1p-1022))) - (func (export "f64.max_subnormal") (result i64) (i64.reinterpret_f64 (f64.const 0x0.fffffffffffffp-1022))) - (func (export "f64.max_finite") (result i64) (i64.reinterpret_f64 (f64.const 0x1.fffffffffffffp+1023))) - (func (export "f64.trailing_dot") (result i64) (i64.reinterpret_f64 (f64.const 0x1.p100))) - - ;; f64 numbers in decimal format - (func (export "f64_dec.zero") (result i64) (i64.reinterpret_f64 (f64.const 0.0e0))) - (func (export "f64_dec.positive_zero") (result i64) (i64.reinterpret_f64 (f64.const +0.0e0))) - (func (export "f64_dec.negative_zero") (result i64) (i64.reinterpret_f64 (f64.const -0.0e0))) - (func (export "f64_dec.misc") (result i64) (i64.reinterpret_f64 (f64.const 6.28318530717958623))) - (func (export "f64_dec.min_positive") (result i64) (i64.reinterpret_f64 (f64.const 4.94066e-324))) - (func (export "f64_dec.min_normal") (result i64) (i64.reinterpret_f64 (f64.const 2.2250738585072012e-308))) - (func (export "f64_dec.max_subnormal") (result i64) (i64.reinterpret_f64 (f64.const 2.2250738585072011e-308))) - (func (export "f64_dec.max_finite") (result i64) (i64.reinterpret_f64 (f64.const 1.7976931348623157e+308))) - (func (export "f64_dec.trailing_dot") (result i64) (i64.reinterpret_f64 (f64.const 1.e100))) - - ;; https://twitter.com/Archivd/status/994637336506912768 - (func (export "f64_dec.root_beer_float") (result i64) (i64.reinterpret_f64 (f64.const 1.000000119))) - - (func (export "f32-dec-sep1") (result f32) (f32.const 1_000_000)) - (func (export "f32-dec-sep2") (result f32) (f32.const 1_0_0_0)) - (func (export "f32-dec-sep3") (result f32) (f32.const 100_3.141_592)) - (func (export "f32-dec-sep4") (result f32) (f32.const 99e+1_3)) - (func (export "f32-dec-sep5") (result f32) (f32.const 122_000.11_3_54E0_2_3)) - (func (export "f32-hex-sep1") (result f32) (f32.const 0xa_0f_00_99)) - (func (export "f32-hex-sep2") (result f32) (f32.const 0x1_a_A_0_f)) - (func (export "f32-hex-sep3") (result f32) (f32.const 0xa0_ff.f141_a59a)) - (func (export "f32-hex-sep4") (result f32) (f32.const 0xf0P+1_3)) - (func (export "f32-hex-sep5") (result f32) (f32.const 0x2a_f00a.1f_3_eep2_3)) - - (func (export "f64-dec-sep1") (result f64) (f64.const 1_000_000)) - (func (export "f64-dec-sep2") (result f64) (f64.const 1_0_0_0)) - (func (export "f64-dec-sep3") (result f64) (f64.const 100_3.141_592)) - (func (export "f64-dec-sep4") (result f64) (f64.const 99e-1_23)) - (func (export "f64-dec-sep5") (result f64) (f64.const 122_000.11_3_54e0_2_3)) - (func (export "f64-hex-sep1") (result f64) (f64.const 0xa_f00f_0000_9999)) - (func (export "f64-hex-sep2") (result f64) (f64.const 0x1_a_A_0_f)) - (func (export "f64-hex-sep3") (result f64) (f64.const 0xa0_ff.f141_a59a)) - (func (export "f64-hex-sep4") (result f64) (f64.const 0xf0P+1_3)) - (func (export "f64-hex-sep5") (result f64) (f64.const 0x2a_f00a.1f_3_eep2_3)) -) - -(assert_return (invoke "f32.nan") (i32.const 0x7fc00000)) -(assert_return (invoke "f32.positive_nan") (i32.const 0x7fc00000)) -(assert_return (invoke "f32.negative_nan") (i32.const 0xffc00000)) -(assert_return (invoke "f32.plain_nan") (i32.const 0x7fc00000)) -(assert_return (invoke "f32.informally_known_as_plain_snan") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.all_ones_nan") (i32.const 0xffffffff)) -(assert_return (invoke "f32.misc_nan") (i32.const 0x7f812345)) -(assert_return (invoke "f32.misc_positive_nan") (i32.const 0x7fb04050)) -(assert_return (invoke "f32.misc_negative_nan") (i32.const 0xffaabcde)) -(assert_return (invoke "f32.infinity") (i32.const 0x7f800000)) -(assert_return (invoke "f32.positive_infinity") (i32.const 0x7f800000)) -(assert_return (invoke "f32.negative_infinity") (i32.const 0xff800000)) -(assert_return (invoke "f32.zero") (i32.const 0)) -(assert_return (invoke "f32.positive_zero") (i32.const 0)) -(assert_return (invoke "f32.negative_zero") (i32.const 0x80000000)) -(assert_return (invoke "f32.misc") (i32.const 0x40c90fdb)) -(assert_return (invoke "f32.min_positive") (i32.const 1)) -(assert_return (invoke "f32.min_normal") (i32.const 0x800000)) -(assert_return (invoke "f32.max_subnormal") (i32.const 0x7fffff)) -(assert_return (invoke "f32.max_finite") (i32.const 0x7f7fffff)) -(assert_return (invoke "f32.trailing_dot") (i32.const 0x44800000)) -(assert_return (invoke "f32_dec.zero") (i32.const 0)) -(assert_return (invoke "f32_dec.positive_zero") (i32.const 0)) -(assert_return (invoke "f32_dec.negative_zero") (i32.const 0x80000000)) -(assert_return (invoke "f32_dec.misc") (i32.const 0x40c90fdb)) -(assert_return (invoke "f32_dec.min_positive") (i32.const 1)) -(assert_return (invoke "f32_dec.min_normal") (i32.const 0x800000)) -(assert_return (invoke "f32_dec.max_subnormal") (i32.const 0x7fffff)) -(assert_return (invoke "f32_dec.max_finite") (i32.const 0x7f7fffff)) -(assert_return (invoke "f32_dec.trailing_dot") (i32.const 0x501502f9)) -(assert_return (invoke "f32_dec.root_beer_float") (i32.const 0x3f800001)) - -(assert_return (invoke "f64.nan") (i64.const 0x7ff8000000000000)) -(assert_return (invoke "f64.positive_nan") (i64.const 0x7ff8000000000000)) -(assert_return (invoke "f64.negative_nan") (i64.const 0xfff8000000000000)) -(assert_return (invoke "f64.plain_nan") (i64.const 0x7ff8000000000000)) -(assert_return (invoke "f64.informally_known_as_plain_snan") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.all_ones_nan") (i64.const 0xffffffffffffffff)) -(assert_return (invoke "f64.misc_nan") (i64.const 0x7ff0123456789abc)) -(assert_return (invoke "f64.misc_positive_nan") (i64.const 0x7ff3040506070809)) -(assert_return (invoke "f64.misc_negative_nan") (i64.const 0xfff2abcdef012345)) -(assert_return (invoke "f64.infinity") (i64.const 0x7ff0000000000000)) -(assert_return (invoke "f64.positive_infinity") (i64.const 0x7ff0000000000000)) -(assert_return (invoke "f64.negative_infinity") (i64.const 0xfff0000000000000)) -(assert_return (invoke "f64.zero") (i64.const 0)) -(assert_return (invoke "f64.positive_zero") (i64.const 0)) -(assert_return (invoke "f64.negative_zero") (i64.const 0x8000000000000000)) -(assert_return (invoke "f64.misc") (i64.const 0x401921fb54442d18)) -(assert_return (invoke "f64.min_positive") (i64.const 1)) -(assert_return (invoke "f64.min_normal") (i64.const 0x10000000000000)) -(assert_return (invoke "f64.max_subnormal") (i64.const 0xfffffffffffff)) -(assert_return (invoke "f64.max_finite") (i64.const 0x7fefffffffffffff)) -(assert_return (invoke "f64.trailing_dot") (i64.const 0x4630000000000000)) -(assert_return (invoke "f64_dec.zero") (i64.const 0)) -(assert_return (invoke "f64_dec.positive_zero") (i64.const 0)) -(assert_return (invoke "f64_dec.negative_zero") (i64.const 0x8000000000000000)) -(assert_return (invoke "f64_dec.misc") (i64.const 0x401921fb54442d18)) -(assert_return (invoke "f64_dec.min_positive") (i64.const 1)) -(assert_return (invoke "f64_dec.min_normal") (i64.const 0x10000000000000)) -(assert_return (invoke "f64_dec.max_subnormal") (i64.const 0xfffffffffffff)) -(assert_return (invoke "f64_dec.max_finite") (i64.const 0x7fefffffffffffff)) -(assert_return (invoke "f64_dec.trailing_dot") (i64.const 0x54b249ad2594c37d)) -(assert_return (invoke "f64_dec.root_beer_float") (i64.const 0x3ff000001ff19e24)) - -(assert_return (invoke "f32-dec-sep1") (f32.const 1000000)) -(assert_return (invoke "f32-dec-sep2") (f32.const 1000)) -(assert_return (invoke "f32-dec-sep3") (f32.const 1003.141592)) -(assert_return (invoke "f32-dec-sep4") (f32.const 99e+13)) -(assert_return (invoke "f32-dec-sep5") (f32.const 122000.11354e23)) -(assert_return (invoke "f32-hex-sep1") (f32.const 0xa0f0099)) -(assert_return (invoke "f32-hex-sep2") (f32.const 0x1aa0f)) -(assert_return (invoke "f32-hex-sep3") (f32.const 0xa0ff.f141a59a)) -(assert_return (invoke "f32-hex-sep4") (f32.const 0xf0P+13)) -(assert_return (invoke "f32-hex-sep5") (f32.const 0x2af00a.1f3eep23)) - -(assert_return (invoke "f64-dec-sep1") (f64.const 1000000)) -(assert_return (invoke "f64-dec-sep2") (f64.const 1000)) -(assert_return (invoke "f64-dec-sep3") (f64.const 1003.141592)) -(assert_return (invoke "f64-dec-sep4") (f64.const 99e-123)) -(assert_return (invoke "f64-dec-sep5") (f64.const 122000.11354e23)) -(assert_return (invoke "f64-hex-sep1") (f64.const 0xaf00f00009999)) -(assert_return (invoke "f64-hex-sep2") (f64.const 0x1aa0f)) -(assert_return (invoke "f64-hex-sep3") (f64.const 0xa0ff.f141a59a)) -(assert_return (invoke "f64-hex-sep4") (f64.const 0xf0P+13)) -(assert_return (invoke "f64-hex-sep5") (f64.const 0x2af00a.1f3eep23)) - -;; Test parsing a float from binary -(module binary - ;; (func (export "4294967249") (result f64) (f64.const 4294967249)) - "\00\61\73\6d\01\00\00\00\01\85\80\80\80\00\01\60" - "\00\01\7c\03\82\80\80\80\00\01\00\07\8e\80\80\80" - "\00\01\0a\34\32\39\34\39\36\37\32\34\39\00\00\0a" - "\91\80\80\80\00\01\8b\80\80\80\00\00\44\00\00\20" - "\fa\ff\ff\ef\41\0b" -) - -(assert_return (invoke "4294967249") (f64.const 4294967249)) - -(assert_malformed - (module quote "(global f32 (f32.const _100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const +_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const -_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 99_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1__000))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const _1.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1_.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1._0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const _1e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1e1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1_e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1e_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const _1.0e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0e1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0_e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0e_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0e+_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 1.0e_+1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const _0x100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0_x100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x00_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0xff__ffff))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x_1.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1_.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1._0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x_1p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1p1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1_p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1p_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x_1.0p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0p1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0_p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0p_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0p+_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f32 (f32.const 0x1.0p_+1))") - "unknown operator" -) - -(assert_malformed - (module quote "(global f64 (f64.const _100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const +_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const -_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 99_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1__000))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const _1.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1_.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1._0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const _1e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1e1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1_e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1e_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const _1.0e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0e1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0_e1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0e_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0e+_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 1.0e_+1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const _0x100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0_x100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x_100))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x00_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0xff__ffff))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x_1.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1_.0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1._0))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x_1p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1p1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1_p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1p_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x_1.0p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0p1_))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0_p1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0p_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0p+_1))") - "unknown operator" -) -(assert_malformed - (module quote "(global f64 (f64.const 0x1.0p_+1))") - "unknown operator" -) diff --git a/test/spec/float_memory.wast b/test/spec/float_memory.wast deleted file mode 100644 index 3801158f92b..00000000000 --- a/test/spec/float_memory.wast +++ /dev/null @@ -1,157 +0,0 @@ -;; Test that floating-point load and store are bit-preserving. - -;; Test that load and store do not canonicalize NaNs as x87 does. - -(module - (memory (data "\00\00\a0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i32.const 0))) - (func (export "i32.load") (result i32) (i32.load (i32.const 0))) - (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x200000))) - (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fa00000))) - (func (export "reset") (i32.store (i32.const 0) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) - -(module - (memory (data "\00\00\00\00\00\00\f4\7f")) - - (func (export "f64.load") (result f64) (f64.load (i32.const 0))) - (func (export "i64.load") (result i64) (i64.load (i32.const 0))) - (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0x4000000000000))) - (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ff4000000000000))) - (func (export "reset") (i64.store (i32.const 0) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) - -;; Test that unaligned load and store do not canonicalize NaNs. - -(module - (memory (data "\00\00\00\a0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i32.const 1))) - (func (export "i32.load") (result i32) (i32.load (i32.const 1))) - (func (export "f32.store") (f32.store (i32.const 1) (f32.const nan:0x200000))) - (func (export "i32.store") (i32.store (i32.const 1) (i32.const 0x7fa00000))) - (func (export "reset") (i32.store (i32.const 1) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) - -(module - (memory (data "\00\00\00\00\00\00\00\f4\7f")) - - (func (export "f64.load") (result f64) (f64.load (i32.const 1))) - (func (export "i64.load") (result i64) (i64.load (i32.const 1))) - (func (export "f64.store") (f64.store (i32.const 1) (f64.const nan:0x4000000000000))) - (func (export "i64.store") (i64.store (i32.const 1) (i64.const 0x7ff4000000000000))) - (func (export "reset") (i64.store (i32.const 1) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) - -;; Test that load and store do not canonicalize NaNs as some JS engines do. - -(module - (memory (data "\01\00\d0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i32.const 0))) - (func (export "i32.load") (result i32) (i32.load (i32.const 0))) - (func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x500001))) - (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fd00001))) - (func (export "reset") (i32.store (i32.const 0) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) - -(module - (memory (data "\01\00\00\00\00\00\fc\7f")) - - (func (export "f64.load") (result f64) (f64.load (i32.const 0))) - (func (export "i64.load") (result i64) (i64.load (i32.const 0))) - (func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0xc000000000001))) - (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ffc000000000001))) - (func (export "reset") (i64.store (i32.const 0) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) diff --git a/test/spec/float_memory64.wast b/test/spec/float_memory64.wast deleted file mode 100644 index 674b254f5a1..00000000000 --- a/test/spec/float_memory64.wast +++ /dev/null @@ -1,157 +0,0 @@ -;; Test that floating-point load and store are bit-preserving. - -;; Test that load and store do not canonicalize NaNs as x87 does. - -(module - (memory i64 (data "\00\00\a0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i64.const 0))) - (func (export "i32.load") (result i32) (i32.load (i64.const 0))) - (func (export "f32.store") (f32.store (i64.const 0) (f32.const nan:0x200000))) - (func (export "i32.store") (i32.store (i64.const 0) (i32.const 0x7fa00000))) - (func (export "reset") (i32.store (i64.const 0) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) - -(module - (memory i64 (data "\00\00\00\00\00\00\f4\7f")) - - (func (export "f64.load") (result f64) (f64.load (i64.const 0))) - (func (export "i64.load") (result i64) (i64.load (i64.const 0))) - (func (export "f64.store") (f64.store (i64.const 0) (f64.const nan:0x4000000000000))) - (func (export "i64.store") (i64.store (i64.const 0) (i64.const 0x7ff4000000000000))) - (func (export "reset") (i64.store (i64.const 0) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) - -;; Test that unaligned load and store do not canonicalize NaNs. - -(module - (memory i64 (data "\00\00\00\a0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i64.const 1))) - (func (export "i32.load") (result i32) (i32.load (i64.const 1))) - (func (export "f32.store") (f32.store (i64.const 1) (f32.const nan:0x200000))) - (func (export "i32.store") (i32.store (i64.const 1) (i32.const 0x7fa00000))) - (func (export "reset") (i32.store (i64.const 1) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) -(assert_return (invoke "f32.load") (f32.const nan:0x200000)) - -(module - (memory i64 (data "\00\00\00\00\00\00\00\f4\7f")) - - (func (export "f64.load") (result f64) (f64.load (i64.const 1))) - (func (export "i64.load") (result i64) (i64.load (i64.const 1))) - (func (export "f64.store") (f64.store (i64.const 1) (f64.const nan:0x4000000000000))) - (func (export "i64.store") (i64.store (i64.const 1) (i64.const 0x7ff4000000000000))) - (func (export "reset") (i64.store (i64.const 1) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) -(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) - -;; Test that load and store do not canonicalize NaNs as some JS engines do. - -(module - (memory i64 (data "\01\00\d0\7f")) - - (func (export "f32.load") (result f32) (f32.load (i64.const 0))) - (func (export "i32.load") (result i32) (i32.load (i64.const 0))) - (func (export "f32.store") (f32.store (i64.const 0) (f32.const nan:0x500001))) - (func (export "i32.store") (i32.store (i64.const 0) (i32.const 0x7fd00001))) - (func (export "reset") (i32.store (i64.const 0) (i32.const 0))) -) - -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "f32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) -(invoke "reset") -(assert_return (invoke "i32.load") (i32.const 0x0)) -(assert_return (invoke "f32.load") (f32.const 0.0)) -(invoke "i32.store") -(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) -(assert_return (invoke "f32.load") (f32.const nan:0x500001)) - -(module - (memory i64 (data "\01\00\00\00\00\00\fc\7f")) - - (func (export "f64.load") (result f64) (f64.load (i64.const 0))) - (func (export "i64.load") (result i64) (i64.load (i64.const 0))) - (func (export "f64.store") (f64.store (i64.const 0) (f64.const nan:0xc000000000001))) - (func (export "i64.store") (i64.store (i64.const 0) (i64.const 0x7ffc000000000001))) - (func (export "reset") (i64.store (i64.const 0) (i64.const 0))) -) - -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "f64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) -(invoke "reset") -(assert_return (invoke "i64.load") (i64.const 0x0)) -(assert_return (invoke "f64.load") (f64.const 0.0)) -(invoke "i64.store") -(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) -(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) diff --git a/test/spec/forward.wast b/test/spec/forward.wast deleted file mode 100644 index 7bb3770d7d5..00000000000 --- a/test/spec/forward.wast +++ /dev/null @@ -1,20 +0,0 @@ -(module - (func $even (export "even") (param $n i32) (result i32) - (if (result i32) (i32.eq (local.get $n) (i32.const 0)) - (then (i32.const 1)) - (else (call $odd (i32.sub (local.get $n) (i32.const 1)))) - ) - ) - - (func $odd (export "odd") (param $n i32) (result i32) - (if (result i32) (i32.eq (local.get $n) (i32.const 0)) - (then (i32.const 0)) - (else (call $even (i32.sub (local.get $n) (i32.const 1)))) - ) - ) -) - -(assert_return (invoke "even" (i32.const 13)) (i32.const 0)) -(assert_return (invoke "even" (i32.const 20)) (i32.const 1)) -(assert_return (invoke "odd" (i32.const 13)) (i32.const 1)) -(assert_return (invoke "odd" (i32.const 20)) (i32.const 0)) diff --git a/test/spec/func_ptrs.wast b/test/spec/func_ptrs.wast deleted file mode 100644 index f6f8e2c429d..00000000000 --- a/test/spec/func_ptrs.wast +++ /dev/null @@ -1,106 +0,0 @@ -(module - (type (func)) ;; 0: void -> void - (type $S (func)) ;; 1: void -> void - (type (func (param))) ;; 2: void -> void - (type (func (result i32))) ;; 3: void -> i32 - (type (func (param) (result i32))) ;; 4: void -> i32 - (type $T (func (param i32) (result i32))) ;; 5: i32 -> i32 - (type $U (func (param i32))) ;; 6: i32 -> void - - (func $print (import "spectest" "print_i32") (type 6)) - - (func (type 0)) - (func (type $S)) - - (func (export "one") (type 4) (i32.const 13)) - (func (export "two") (type $T) (i32.add (local.get 0) (i32.const 1))) - - ;; Both signature and parameters are allowed (and required to match) - ;; since this allows the naming of parameters. - (func (export "three") (type $T) (param $a i32) (result i32) - (i32.sub (local.get 0) (i32.const 2)) - ) - - (func (export "four") (type $U) (call $print (local.get 0))) -) - -(assert_return (invoke "one") (i32.const 13)) -(assert_return (invoke "two" (i32.const 13)) (i32.const 14)) -(assert_return (invoke "three" (i32.const 13)) (i32.const 11)) -(invoke "four" (i32.const 83)) - -(assert_invalid (module (elem (i32.const 0))) "unknown table") -(assert_invalid (module (elem (i32.const 0) 0) (func)) "unknown table") - -(assert_invalid - (module (table 1 funcref) (elem (i64.const 0))) - "type mismatch" -) -(assert_invalid - (module (table 1 funcref) (elem (i32.ctz (i32.const 0)))) - "constant expression required" -) -(assert_invalid - (module (table 1 funcref) (elem (nop))) - "constant expression required" -) - -(assert_invalid (module (func (type 42))) "unknown type") -(assert_invalid (module (import "spectest" "print_i32" (func (type 43)))) "unknown type") - -(module - (type $T (func (param) (result i32))) - (type $U (func (param) (result i32))) - (table funcref (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3)) - - (func $t1 (type $T) (i32.const 1)) - (func $t2 (type $T) (i32.const 2)) - (func $t3 (type $T) (i32.const 3)) - (func $u1 (type $U) (i32.const 4)) - (func $u2 (type $U) (i32.const 5)) - - (func (export "callt") (param $i i32) (result i32) - (call_indirect (type $T) (local.get $i)) - ) - - (func (export "callu") (param $i i32) (result i32) - (call_indirect (type $U) (local.get $i)) - ) -) - -(assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "callt" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "callt" (i32.const 3)) (i32.const 4)) -(assert_return (invoke "callt" (i32.const 4)) (i32.const 5)) -(assert_return (invoke "callt" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "callt" (i32.const 6)) (i32.const 3)) -(assert_trap (invoke "callt" (i32.const 7)) "undefined element") -(assert_trap (invoke "callt" (i32.const 100)) "undefined element") -(assert_trap (invoke "callt" (i32.const -1)) "undefined element") - -(assert_return (invoke "callu" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "callu" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "callu" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "callu" (i32.const 3)) (i32.const 4)) -(assert_return (invoke "callu" (i32.const 4)) (i32.const 5)) -(assert_return (invoke "callu" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "callu" (i32.const 6)) (i32.const 3)) -(assert_trap (invoke "callu" (i32.const 7)) "undefined element") -(assert_trap (invoke "callu" (i32.const 100)) "undefined element") -(assert_trap (invoke "callu" (i32.const -1)) "undefined element") - -(module - (type $T (func (result i32))) - (table funcref (elem 0 1)) - - (func $t1 (type $T) (i32.const 1)) - (func $t2 (type $T) (i32.const 2)) - - (func (export "callt") (param $i i32) (result i32) - (call_indirect (type $T) (local.get $i)) - ) -) - -(assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) diff --git a/test/spec/i32.wast b/test/spec/i32.wast deleted file mode 100644 index 58c853a6ba6..00000000000 --- a/test/spec/i32.wast +++ /dev/null @@ -1,958 +0,0 @@ -;; i32 operations - -(module - (func (export "add") (param $x i32) (param $y i32) (result i32) (i32.add (local.get $x) (local.get $y))) - (func (export "sub") (param $x i32) (param $y i32) (result i32) (i32.sub (local.get $x) (local.get $y))) - (func (export "mul") (param $x i32) (param $y i32) (result i32) (i32.mul (local.get $x) (local.get $y))) - (func (export "div_s") (param $x i32) (param $y i32) (result i32) (i32.div_s (local.get $x) (local.get $y))) - (func (export "div_u") (param $x i32) (param $y i32) (result i32) (i32.div_u (local.get $x) (local.get $y))) - (func (export "rem_s") (param $x i32) (param $y i32) (result i32) (i32.rem_s (local.get $x) (local.get $y))) - (func (export "rem_u") (param $x i32) (param $y i32) (result i32) (i32.rem_u (local.get $x) (local.get $y))) - (func (export "and") (param $x i32) (param $y i32) (result i32) (i32.and (local.get $x) (local.get $y))) - (func (export "or") (param $x i32) (param $y i32) (result i32) (i32.or (local.get $x) (local.get $y))) - (func (export "xor") (param $x i32) (param $y i32) (result i32) (i32.xor (local.get $x) (local.get $y))) - (func (export "shl") (param $x i32) (param $y i32) (result i32) (i32.shl (local.get $x) (local.get $y))) - (func (export "shr_s") (param $x i32) (param $y i32) (result i32) (i32.shr_s (local.get $x) (local.get $y))) - (func (export "shr_u") (param $x i32) (param $y i32) (result i32) (i32.shr_u (local.get $x) (local.get $y))) - (func (export "rotl") (param $x i32) (param $y i32) (result i32) (i32.rotl (local.get $x) (local.get $y))) - (func (export "rotr") (param $x i32) (param $y i32) (result i32) (i32.rotr (local.get $x) (local.get $y))) - (func (export "clz") (param $x i32) (result i32) (i32.clz (local.get $x))) - (func (export "ctz") (param $x i32) (result i32) (i32.ctz (local.get $x))) - (func (export "popcnt") (param $x i32) (result i32) (i32.popcnt (local.get $x))) - (func (export "eqz") (param $x i32) (result i32) (i32.eqz (local.get $x))) - (func (export "eq") (param $x i32) (param $y i32) (result i32) (i32.eq (local.get $x) (local.get $y))) - (func (export "ne") (param $x i32) (param $y i32) (result i32) (i32.ne (local.get $x) (local.get $y))) - (func (export "lt_s") (param $x i32) (param $y i32) (result i32) (i32.lt_s (local.get $x) (local.get $y))) - (func (export "lt_u") (param $x i32) (param $y i32) (result i32) (i32.lt_u (local.get $x) (local.get $y))) - (func (export "le_s") (param $x i32) (param $y i32) (result i32) (i32.le_s (local.get $x) (local.get $y))) - (func (export "le_u") (param $x i32) (param $y i32) (result i32) (i32.le_u (local.get $x) (local.get $y))) - (func (export "gt_s") (param $x i32) (param $y i32) (result i32) (i32.gt_s (local.get $x) (local.get $y))) - (func (export "gt_u") (param $x i32) (param $y i32) (result i32) (i32.gt_u (local.get $x) (local.get $y))) - (func (export "ge_s") (param $x i32) (param $y i32) (result i32) (i32.ge_s (local.get $x) (local.get $y))) - (func (export "ge_u") (param $x i32) (param $y i32) (result i32) (i32.ge_u (local.get $x) (local.get $y))) -) - -(assert_return (invoke "add" (i32.const 1) (i32.const 1)) (i32.const 2)) -(assert_return (invoke "add" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "add" (i32.const -1) (i32.const -1)) (i32.const -2)) -(assert_return (invoke "add" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "add" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x80000000)) -(assert_return (invoke "add" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x7fffffff)) -(assert_return (invoke "add" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "add" (i32.const 0x3fffffff) (i32.const 1)) (i32.const 0x40000000)) - -(assert_return (invoke "sub" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "sub" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "sub" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "sub" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x80000000)) -(assert_return (invoke "sub" (i32.const 0x80000000) (i32.const 1)) (i32.const 0x7fffffff)) -(assert_return (invoke "sub" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "sub" (i32.const 0x3fffffff) (i32.const -1)) (i32.const 0x40000000)) - -(assert_return (invoke "mul" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "mul" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "mul" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "mul" (i32.const 0x10000000) (i32.const 4096)) (i32.const 0)) -(assert_return (invoke "mul" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "mul" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x80000000)) -(assert_return (invoke "mul" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x80000001)) -(assert_return (invoke "mul" (i32.const 0x01234567) (i32.const 0x76543210)) (i32.const 0x358e7470)) -(assert_return (invoke "mul" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) - -(assert_trap (invoke "div_s" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "div_s" (i32.const 0) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "div_s" (i32.const 0x80000000) (i32.const -1)) "integer overflow") -(assert_trap (invoke "div_s" (i32.const 0x80000000) (i32.const 0)) "integer divide by zero") -(assert_return (invoke "div_s" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "div_s" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "div_s" (i32.const 0) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "div_s" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "div_s" (i32.const 0x80000000) (i32.const 2)) (i32.const 0xc0000000)) -(assert_return (invoke "div_s" (i32.const 0x80000001) (i32.const 1000)) (i32.const 0xffdf3b65)) -(assert_return (invoke "div_s" (i32.const 5) (i32.const 2)) (i32.const 2)) -(assert_return (invoke "div_s" (i32.const -5) (i32.const 2)) (i32.const -2)) -(assert_return (invoke "div_s" (i32.const 5) (i32.const -2)) (i32.const -2)) -(assert_return (invoke "div_s" (i32.const -5) (i32.const -2)) (i32.const 2)) -(assert_return (invoke "div_s" (i32.const 7) (i32.const 3)) (i32.const 2)) -(assert_return (invoke "div_s" (i32.const -7) (i32.const 3)) (i32.const -2)) -(assert_return (invoke "div_s" (i32.const 7) (i32.const -3)) (i32.const -2)) -(assert_return (invoke "div_s" (i32.const -7) (i32.const -3)) (i32.const 2)) -(assert_return (invoke "div_s" (i32.const 11) (i32.const 5)) (i32.const 2)) -(assert_return (invoke "div_s" (i32.const 17) (i32.const 7)) (i32.const 2)) - -(assert_trap (invoke "div_u" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "div_u" (i32.const 0) (i32.const 0)) "integer divide by zero") -(assert_return (invoke "div_u" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "div_u" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "div_u" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "div_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "div_u" (i32.const 0x80000000) (i32.const 2)) (i32.const 0x40000000)) -(assert_return (invoke "div_u" (i32.const 0x8ff00ff0) (i32.const 0x10001)) (i32.const 0x8fef)) -(assert_return (invoke "div_u" (i32.const 0x80000001) (i32.const 1000)) (i32.const 0x20c49b)) -(assert_return (invoke "div_u" (i32.const 5) (i32.const 2)) (i32.const 2)) -(assert_return (invoke "div_u" (i32.const -5) (i32.const 2)) (i32.const 0x7ffffffd)) -(assert_return (invoke "div_u" (i32.const 5) (i32.const -2)) (i32.const 0)) -(assert_return (invoke "div_u" (i32.const -5) (i32.const -2)) (i32.const 0)) -(assert_return (invoke "div_u" (i32.const 7) (i32.const 3)) (i32.const 2)) -(assert_return (invoke "div_u" (i32.const 11) (i32.const 5)) (i32.const 2)) -(assert_return (invoke "div_u" (i32.const 17) (i32.const 7)) (i32.const 2)) - -(assert_trap (invoke "rem_s" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "rem_s" (i32.const 0) (i32.const 0)) "integer divide by zero") -(assert_return (invoke "rem_s" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 0) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 0x80000000) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "rem_s" (i32.const 0x80000001) (i32.const 1000)) (i32.const -647)) -(assert_return (invoke "rem_s" (i32.const 5) (i32.const 2)) (i32.const 1)) -(assert_return (invoke "rem_s" (i32.const -5) (i32.const 2)) (i32.const -1)) -(assert_return (invoke "rem_s" (i32.const 5) (i32.const -2)) (i32.const 1)) -(assert_return (invoke "rem_s" (i32.const -5) (i32.const -2)) (i32.const -1)) -(assert_return (invoke "rem_s" (i32.const 7) (i32.const 3)) (i32.const 1)) -(assert_return (invoke "rem_s" (i32.const -7) (i32.const 3)) (i32.const -1)) -(assert_return (invoke "rem_s" (i32.const 7) (i32.const -3)) (i32.const 1)) -(assert_return (invoke "rem_s" (i32.const -7) (i32.const -3)) (i32.const -1)) -(assert_return (invoke "rem_s" (i32.const 11) (i32.const 5)) (i32.const 1)) -(assert_return (invoke "rem_s" (i32.const 17) (i32.const 7)) (i32.const 3)) - -(assert_trap (invoke "rem_u" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "rem_u" (i32.const 0) (i32.const 0)) "integer divide by zero") -(assert_return (invoke "rem_u" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "rem_u" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "rem_u" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "rem_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x80000000)) -(assert_return (invoke "rem_u" (i32.const 0x80000000) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "rem_u" (i32.const 0x8ff00ff0) (i32.const 0x10001)) (i32.const 0x8001)) -(assert_return (invoke "rem_u" (i32.const 0x80000001) (i32.const 1000)) (i32.const 649)) -(assert_return (invoke "rem_u" (i32.const 5) (i32.const 2)) (i32.const 1)) -(assert_return (invoke "rem_u" (i32.const -5) (i32.const 2)) (i32.const 1)) -(assert_return (invoke "rem_u" (i32.const 5) (i32.const -2)) (i32.const 5)) -(assert_return (invoke "rem_u" (i32.const -5) (i32.const -2)) (i32.const -5)) -(assert_return (invoke "rem_u" (i32.const 7) (i32.const 3)) (i32.const 1)) -(assert_return (invoke "rem_u" (i32.const 11) (i32.const 5)) (i32.const 1)) -(assert_return (invoke "rem_u" (i32.const 17) (i32.const 7)) (i32.const 3)) - -(assert_return (invoke "and" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "and" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "and" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "and" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "and" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "and" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x7fffffff)) -(assert_return (invoke "and" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0xf0f0f0f0)) -(assert_return (invoke "and" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0xffffffff)) - -(assert_return (invoke "or" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "or" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "or" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "or" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "or" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const -1)) -(assert_return (invoke "or" (i32.const 0x80000000) (i32.const 0)) (i32.const 0x80000000)) -(assert_return (invoke "or" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0xffffffff)) -(assert_return (invoke "or" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0xffffffff)) - -(assert_return (invoke "xor" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "xor" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "xor" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "xor" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "xor" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const -1)) -(assert_return (invoke "xor" (i32.const 0x80000000) (i32.const 0)) (i32.const 0x80000000)) -(assert_return (invoke "xor" (i32.const -1) (i32.const 0x80000000)) (i32.const 0x7fffffff)) -(assert_return (invoke "xor" (i32.const -1) (i32.const 0x7fffffff)) (i32.const 0x80000000)) -(assert_return (invoke "xor" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0x0f0f0f0f)) -(assert_return (invoke "xor" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0)) - -(assert_return (invoke "shl" (i32.const 1) (i32.const 1)) (i32.const 2)) -(assert_return (invoke "shl" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "shl" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0xfffffffe)) -(assert_return (invoke "shl" (i32.const 0xffffffff) (i32.const 1)) (i32.const 0xfffffffe)) -(assert_return (invoke "shl" (i32.const 0x80000000) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "shl" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x80000000)) -(assert_return (invoke "shl" (i32.const 1) (i32.const 31)) (i32.const 0x80000000)) -(assert_return (invoke "shl" (i32.const 1) (i32.const 32)) (i32.const 1)) -(assert_return (invoke "shl" (i32.const 1) (i32.const 33)) (i32.const 2)) -(assert_return (invoke "shl" (i32.const 1) (i32.const -1)) (i32.const 0x80000000)) -(assert_return (invoke "shl" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0x80000000)) - -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const 1)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x3fffffff)) -(assert_return (invoke "shr_s" (i32.const 0x80000000) (i32.const 1)) (i32.const 0xc0000000)) -(assert_return (invoke "shr_s" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x20000000)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 32)) (i32.const 1)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 33)) (i32.const 0)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "shr_s" (i32.const 0x80000000) (i32.const 31)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const 32)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const 33)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const -1)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const 0x7fffffff)) (i32.const -1)) -(assert_return (invoke "shr_s" (i32.const -1) (i32.const 0x80000000)) (i32.const -1)) - -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const 1)) (i32.const 0x7fffffff)) -(assert_return (invoke "shr_u" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x3fffffff)) -(assert_return (invoke "shr_u" (i32.const 0x80000000) (i32.const 1)) (i32.const 0x40000000)) -(assert_return (invoke "shr_u" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x20000000)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 32)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 33)) (i32.const 0)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const 0x80000000) (i32.const 31)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const 32)) (i32.const -1)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const 33)) (i32.const 0x7fffffff)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "shr_u" (i32.const -1) (i32.const 0x80000000)) (i32.const -1)) - -(assert_return (invoke "rotl" (i32.const 1) (i32.const 1)) (i32.const 2)) -(assert_return (invoke "rotl" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "rotl" (i32.const -1) (i32.const 1)) (i32.const -1)) -(assert_return (invoke "rotl" (i32.const 1) (i32.const 32)) (i32.const 1)) -(assert_return (invoke "rotl" (i32.const 0xabcd9876) (i32.const 1)) (i32.const 0x579b30ed)) -(assert_return (invoke "rotl" (i32.const 0xfe00dc00) (i32.const 4)) (i32.const 0xe00dc00f)) -(assert_return (invoke "rotl" (i32.const 0xb0c1d2e3) (i32.const 5)) (i32.const 0x183a5c76)) -(assert_return (invoke "rotl" (i32.const 0x00008000) (i32.const 37)) (i32.const 0x00100000)) -(assert_return (invoke "rotl" (i32.const 0xb0c1d2e3) (i32.const 0xff05)) (i32.const 0x183a5c76)) -(assert_return (invoke "rotl" (i32.const 0x769abcdf) (i32.const 0xffffffed)) (i32.const 0x579beed3)) -(assert_return (invoke "rotl" (i32.const 0x769abcdf) (i32.const 0x8000000d)) (i32.const 0x579beed3)) -(assert_return (invoke "rotl" (i32.const 1) (i32.const 31)) (i32.const 0x80000000)) -(assert_return (invoke "rotl" (i32.const 0x80000000) (i32.const 1)) (i32.const 1)) - -(assert_return (invoke "rotr" (i32.const 1) (i32.const 1)) (i32.const 0x80000000)) -(assert_return (invoke "rotr" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "rotr" (i32.const -1) (i32.const 1)) (i32.const -1)) -(assert_return (invoke "rotr" (i32.const 1) (i32.const 32)) (i32.const 1)) -(assert_return (invoke "rotr" (i32.const 0xff00cc00) (i32.const 1)) (i32.const 0x7f806600)) -(assert_return (invoke "rotr" (i32.const 0x00080000) (i32.const 4)) (i32.const 0x00008000)) -(assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 5)) (i32.const 0x1d860e97)) -(assert_return (invoke "rotr" (i32.const 0x00008000) (i32.const 37)) (i32.const 0x00000400)) -(assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 0xff05)) (i32.const 0x1d860e97)) -(assert_return (invoke "rotr" (i32.const 0x769abcdf) (i32.const 0xffffffed)) (i32.const 0xe6fbb4d5)) -(assert_return (invoke "rotr" (i32.const 0x769abcdf) (i32.const 0x8000000d)) (i32.const 0xe6fbb4d5)) -(assert_return (invoke "rotr" (i32.const 1) (i32.const 31)) (i32.const 2)) -(assert_return (invoke "rotr" (i32.const 0x80000000) (i32.const 31)) (i32.const 1)) - -(assert_return (invoke "clz" (i32.const 0xffffffff)) (i32.const 0)) -(assert_return (invoke "clz" (i32.const 0)) (i32.const 32)) -(assert_return (invoke "clz" (i32.const 0x00008000)) (i32.const 16)) -(assert_return (invoke "clz" (i32.const 0xff)) (i32.const 24)) -(assert_return (invoke "clz" (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "clz" (i32.const 1)) (i32.const 31)) -(assert_return (invoke "clz" (i32.const 2)) (i32.const 30)) -(assert_return (invoke "clz" (i32.const 0x7fffffff)) (i32.const 1)) - -(assert_return (invoke "ctz" (i32.const -1)) (i32.const 0)) -(assert_return (invoke "ctz" (i32.const 0)) (i32.const 32)) -(assert_return (invoke "ctz" (i32.const 0x00008000)) (i32.const 15)) -(assert_return (invoke "ctz" (i32.const 0x00010000)) (i32.const 16)) -(assert_return (invoke "ctz" (i32.const 0x80000000)) (i32.const 31)) -(assert_return (invoke "ctz" (i32.const 0x7fffffff)) (i32.const 0)) - -(assert_return (invoke "popcnt" (i32.const -1)) (i32.const 32)) -(assert_return (invoke "popcnt" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "popcnt" (i32.const 0x00008000)) (i32.const 1)) -(assert_return (invoke "popcnt" (i32.const 0x80008000)) (i32.const 2)) -(assert_return (invoke "popcnt" (i32.const 0x7fffffff)) (i32.const 31)) -(assert_return (invoke "popcnt" (i32.const 0xAAAAAAAA)) (i32.const 16)) -(assert_return (invoke "popcnt" (i32.const 0x55555555)) (i32.const 16)) -(assert_return (invoke "popcnt" (i32.const 0xDEADBEEF)) (i32.const 24)) - -(assert_return (invoke "eqz" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "eqz" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eqz" (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "eqz" (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "eqz" (i32.const 0xffffffff)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) - -(assert_return (invoke "ne" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ne" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ne" (i32.const -1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "ne" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "ne" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) - -(assert_return (invoke "lt_s" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const -1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "lt_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "lt_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) - -(assert_return (invoke "lt_u" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "lt_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "lt_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) - -(assert_return (invoke "le_s" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const -1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "le_s" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "le_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) - -(assert_return (invoke "le_u" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const 1) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "le_u" (i32.const 0) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "le_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "le_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "le_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) - -(assert_return (invoke "gt_s" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "gt_s" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "gt_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) - -(assert_return (invoke "gt_u" (i32.const 0) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const 1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const -1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const -1) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "gt_u" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "gt_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "gt_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) - -(assert_return (invoke "ge_s" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const -1) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ge_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0)) -(assert_return (invoke "ge_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1)) - -(assert_return (invoke "ge_u" (i32.const 0) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const -1) (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const -1) (i32.const -1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 1) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0)) -(assert_return (invoke "ge_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1)) -(assert_return (invoke "ge_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0)) - - -(assert_invalid - (module - (func $type-unary-operand-empty - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-block - (i32.const 0) - (block (i32.eqz) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-loop - (i32.const 0) - (loop (i32.eqz) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-if - (i32.const 0) (i32.const 0) - (if (then (i32.eqz) (drop))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-else - (i32.const 0) (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (i32.eqz))) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-br - (i32.const 0) - (block (br 0 (i32.eqz)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-br_if - (i32.const 0) - (block (br_if 0 (i32.eqz) (i32.const 1)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-br_table - (i32.const 0) - (block (br_table 0 (i32.eqz)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-return - (return (i32.eqz)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-select - (select (i32.eqz) (i32.const 1) (i32.const 2)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-call - (call 1 (i32.eqz)) (drop) - ) - (func (param i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-unary-operand-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (i32.eqz) (i32.const 0) - ) - (drop) - ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-local.set - (local i32) - (local.set 0 (i32.eqz)) (local.get 0) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-unary-operand-empty-in-local.tee - (local i32) - (local.tee 0 (i32.eqz)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (global $x (mut i32) (i32.const 0)) - (func $type-unary-operand-empty-in-global.set - (global.set $x (i32.eqz)) (global.get $x) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-unary-operand-empty-in-memory.grow - (memory.grow (i32.eqz)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-unary-operand-empty-in-load - (i32.load (i32.eqz)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-unary-operand-empty-in-store - (i32.store (i32.eqz) (i32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (func $type-binary-1st-operand-empty - (i32.add) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty - (i32.const 0) (i32.add) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-block - (i32.const 0) (i32.const 0) - (block (i32.add) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-block - (i32.const 0) - (block (i32.const 0) (i32.add) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-loop - (i32.const 0) (i32.const 0) - (loop (i32.add) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-loop - (i32.const 0) - (loop (i32.const 0) (i32.add) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-if - (i32.const 0) (i32.const 0) (i32.const 0) - (if (i32.add) (then (drop))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-if - (i32.const 0) (i32.const 0) - (if (i32.const 0) (then (i32.add)) (else (drop))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-else - (i32.const 0) (i32.const 0) (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (i32.add) (i32.const 0))) - (drop) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-else - (i32.const 0) (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (i32.add))) - (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-br - (i32.const 0) (i32.const 0) - (block (br 0 (i32.add)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-br - (i32.const 0) - (block (br 0 (i32.const 0) (i32.add)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-br_if - (i32.const 0) (i32.const 0) - (block (br_if 0 (i32.add) (i32.const 1)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-br_if - (i32.const 0) - (block (br_if 0 (i32.const 0) (i32.add) (i32.const 1)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-br_table - (i32.const 0) (i32.const 0) - (block (br_table 0 (i32.add)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-br_table - (i32.const 0) - (block (br_table 0 (i32.const 0) (i32.add)) (drop)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-return - (return (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-return - (return (i32.const 0) (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-select - (select (i32.add) (i32.const 1) (i32.const 2)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-select - (select (i32.const 0) (i32.add) (i32.const 1) (i32.const 2)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-call - (call 1 (i32.add)) (drop) - ) - (func (param i32 i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-call - (call 1 (i32.const 0) (i32.add)) (drop) - ) - (func (param i32 i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-binary-1st-operand-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (i32.add) (i32.const 0) - ) - (drop) - ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-binary-2nd-operand-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.add) (i32.const 0) - ) - (drop) - ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-local.set - (local i32) - (local.set 0 (i32.add)) (local.get 0) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-local.set - (local i32) - (local.set 0 (i32.const 0) (i32.add)) (local.get 0) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-1st-operand-empty-in-local.tee - (local i32) - (local.tee 0 (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-binary-2nd-operand-empty-in-local.tee - (local i32) - (local.tee 0 (i32.const 0) (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (global $x (mut i32) (i32.const 0)) - (func $type-binary-1st-operand-empty-in-global.set - (global.set $x (i32.add)) (global.get $x) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (global $x (mut i32) (i32.const 0)) - (func $type-binary-2nd-operand-empty-in-global.set - (global.set $x (i32.const 0) (i32.add)) (global.get $x) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-binary-1st-operand-empty-in-memory.grow - (memory.grow (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-binary-2nd-operand-empty-in-memory.grow - (memory.grow (i32.const 0) (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-binary-1st-operand-empty-in-load - (i32.load (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-binary-2nd-operand-empty-in-load - (i32.load (i32.const 0) (i32.add)) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-binary-1st-operand-empty-in-store - (i32.store (i32.add) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-binary-2nd-operand-empty-in-store - (i32.store (i32.const 1) (i32.add) (i32.const 0)) - ) - ) - "type mismatch" -) - - -;; Type check - -(assert_invalid (module (func (result i32) (i32.add (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.and (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.div_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.div_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.mul (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.or (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.rem_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.rem_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.rotl (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.rotr (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.shl (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.shr_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.shr_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.sub (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.xor (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.eqz (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.clz (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.ctz (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.popcnt (i64.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.eq (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.ge_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.ge_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.gt_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.gt_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.le_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.le_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.lt_s (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.lt_u (i64.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i32) (i32.ne (i64.const 0) (f32.const 0)))) "type mismatch") diff --git a/test/spec/i64.wast b/test/spec/i64.wast deleted file mode 100644 index 5a8c1d66256..00000000000 --- a/test/spec/i64.wast +++ /dev/null @@ -1,455 +0,0 @@ -;; i64 operations - -(module - (func (export "add") (param $x i64) (param $y i64) (result i64) (i64.add (local.get $x) (local.get $y))) - (func (export "sub") (param $x i64) (param $y i64) (result i64) (i64.sub (local.get $x) (local.get $y))) - (func (export "mul") (param $x i64) (param $y i64) (result i64) (i64.mul (local.get $x) (local.get $y))) - (func (export "div_s") (param $x i64) (param $y i64) (result i64) (i64.div_s (local.get $x) (local.get $y))) - (func (export "div_u") (param $x i64) (param $y i64) (result i64) (i64.div_u (local.get $x) (local.get $y))) - (func (export "rem_s") (param $x i64) (param $y i64) (result i64) (i64.rem_s (local.get $x) (local.get $y))) - (func (export "rem_u") (param $x i64) (param $y i64) (result i64) (i64.rem_u (local.get $x) (local.get $y))) - (func (export "and") (param $x i64) (param $y i64) (result i64) (i64.and (local.get $x) (local.get $y))) - (func (export "or") (param $x i64) (param $y i64) (result i64) (i64.or (local.get $x) (local.get $y))) - (func (export "xor") (param $x i64) (param $y i64) (result i64) (i64.xor (local.get $x) (local.get $y))) - (func (export "shl") (param $x i64) (param $y i64) (result i64) (i64.shl (local.get $x) (local.get $y))) - (func (export "shr_s") (param $x i64) (param $y i64) (result i64) (i64.shr_s (local.get $x) (local.get $y))) - (func (export "shr_u") (param $x i64) (param $y i64) (result i64) (i64.shr_u (local.get $x) (local.get $y))) - (func (export "rotl") (param $x i64) (param $y i64) (result i64) (i64.rotl (local.get $x) (local.get $y))) - (func (export "rotr") (param $x i64) (param $y i64) (result i64) (i64.rotr (local.get $x) (local.get $y))) - (func (export "clz") (param $x i64) (result i64) (i64.clz (local.get $x))) - (func (export "ctz") (param $x i64) (result i64) (i64.ctz (local.get $x))) - (func (export "popcnt") (param $x i64) (result i64) (i64.popcnt (local.get $x))) - (func (export "eqz") (param $x i64) (result i32) (i64.eqz (local.get $x))) - (func (export "eq") (param $x i64) (param $y i64) (result i32) (i64.eq (local.get $x) (local.get $y))) - (func (export "ne") (param $x i64) (param $y i64) (result i32) (i64.ne (local.get $x) (local.get $y))) - (func (export "lt_s") (param $x i64) (param $y i64) (result i32) (i64.lt_s (local.get $x) (local.get $y))) - (func (export "lt_u") (param $x i64) (param $y i64) (result i32) (i64.lt_u (local.get $x) (local.get $y))) - (func (export "le_s") (param $x i64) (param $y i64) (result i32) (i64.le_s (local.get $x) (local.get $y))) - (func (export "le_u") (param $x i64) (param $y i64) (result i32) (i64.le_u (local.get $x) (local.get $y))) - (func (export "gt_s") (param $x i64) (param $y i64) (result i32) (i64.gt_s (local.get $x) (local.get $y))) - (func (export "gt_u") (param $x i64) (param $y i64) (result i32) (i64.gt_u (local.get $x) (local.get $y))) - (func (export "ge_s") (param $x i64) (param $y i64) (result i32) (i64.ge_s (local.get $x) (local.get $y))) - (func (export "ge_u") (param $x i64) (param $y i64) (result i32) (i64.ge_u (local.get $x) (local.get $y))) -) - -(assert_return (invoke "add" (i64.const 1) (i64.const 1)) (i64.const 2)) -(assert_return (invoke "add" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "add" (i64.const -1) (i64.const -1)) (i64.const -2)) -(assert_return (invoke "add" (i64.const -1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "add" (i64.const 0x7fffffffffffffff) (i64.const 1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "add" (i64.const 0x8000000000000000) (i64.const -1)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "add" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i64.const 0)) -(assert_return (invoke "add" (i64.const 0x3fffffff) (i64.const 1)) (i64.const 0x40000000)) - -(assert_return (invoke "sub" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "sub" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "sub" (i64.const -1) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "sub" (i64.const 0x7fffffffffffffff) (i64.const -1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "sub" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "sub" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i64.const 0)) -(assert_return (invoke "sub" (i64.const 0x3fffffff) (i64.const -1)) (i64.const 0x40000000)) - -(assert_return (invoke "mul" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "mul" (i64.const 1) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "mul" (i64.const -1) (i64.const -1)) (i64.const 1)) -(assert_return (invoke "mul" (i64.const 0x1000000000000000) (i64.const 4096)) (i64.const 0)) -(assert_return (invoke "mul" (i64.const 0x8000000000000000) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "mul" (i64.const 0x8000000000000000) (i64.const -1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "mul" (i64.const 0x7fffffffffffffff) (i64.const -1)) (i64.const 0x8000000000000001)) -(assert_return (invoke "mul" (i64.const 0x0123456789abcdef) (i64.const 0xfedcba9876543210)) (i64.const 0x2236d88fe5618cf0)) -(assert_return (invoke "mul" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i64.const 1)) - -(assert_trap (invoke "div_s" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "div_s" (i64.const 0) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "div_s" (i64.const 0x8000000000000000) (i64.const -1)) "integer overflow") -(assert_trap (invoke "div_s" (i64.const 0x8000000000000000) (i64.const 0)) "integer divide by zero") -(assert_return (invoke "div_s" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "div_s" (i64.const 0) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "div_s" (i64.const 0) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "div_s" (i64.const -1) (i64.const -1)) (i64.const 1)) -(assert_return (invoke "div_s" (i64.const 0x8000000000000000) (i64.const 2)) (i64.const 0xc000000000000000)) -(assert_return (invoke "div_s" (i64.const 0x8000000000000001) (i64.const 1000)) (i64.const 0xffdf3b645a1cac09)) -(assert_return (invoke "div_s" (i64.const 5) (i64.const 2)) (i64.const 2)) -(assert_return (invoke "div_s" (i64.const -5) (i64.const 2)) (i64.const -2)) -(assert_return (invoke "div_s" (i64.const 5) (i64.const -2)) (i64.const -2)) -(assert_return (invoke "div_s" (i64.const -5) (i64.const -2)) (i64.const 2)) -(assert_return (invoke "div_s" (i64.const 7) (i64.const 3)) (i64.const 2)) -(assert_return (invoke "div_s" (i64.const -7) (i64.const 3)) (i64.const -2)) -(assert_return (invoke "div_s" (i64.const 7) (i64.const -3)) (i64.const -2)) -(assert_return (invoke "div_s" (i64.const -7) (i64.const -3)) (i64.const 2)) -(assert_return (invoke "div_s" (i64.const 11) (i64.const 5)) (i64.const 2)) -(assert_return (invoke "div_s" (i64.const 17) (i64.const 7)) (i64.const 2)) - -(assert_trap (invoke "div_u" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "div_u" (i64.const 0) (i64.const 0)) "integer divide by zero") -(assert_return (invoke "div_u" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "div_u" (i64.const 0) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "div_u" (i64.const -1) (i64.const -1)) (i64.const 1)) -(assert_return (invoke "div_u" (i64.const 0x8000000000000000) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "div_u" (i64.const 0x8000000000000000) (i64.const 2)) (i64.const 0x4000000000000000)) -(assert_return (invoke "div_u" (i64.const 0x8ff00ff00ff00ff0) (i64.const 0x100000001)) (i64.const 0x8ff00fef)) -(assert_return (invoke "div_u" (i64.const 0x8000000000000001) (i64.const 1000)) (i64.const 0x20c49ba5e353f7)) -(assert_return (invoke "div_u" (i64.const 5) (i64.const 2)) (i64.const 2)) -(assert_return (invoke "div_u" (i64.const -5) (i64.const 2)) (i64.const 0x7ffffffffffffffd)) -(assert_return (invoke "div_u" (i64.const 5) (i64.const -2)) (i64.const 0)) -(assert_return (invoke "div_u" (i64.const -5) (i64.const -2)) (i64.const 0)) -(assert_return (invoke "div_u" (i64.const 7) (i64.const 3)) (i64.const 2)) -(assert_return (invoke "div_u" (i64.const 11) (i64.const 5)) (i64.const 2)) -(assert_return (invoke "div_u" (i64.const 17) (i64.const 7)) (i64.const 2)) - -(assert_trap (invoke "rem_s" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "rem_s" (i64.const 0) (i64.const 0)) "integer divide by zero") -(assert_return (invoke "rem_s" (i64.const 0x7fffffffffffffff) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 0) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 0) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const -1) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 0x8000000000000000) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 0x8000000000000000) (i64.const 2)) (i64.const 0)) -(assert_return (invoke "rem_s" (i64.const 0x8000000000000001) (i64.const 1000)) (i64.const -807)) -(assert_return (invoke "rem_s" (i64.const 5) (i64.const 2)) (i64.const 1)) -(assert_return (invoke "rem_s" (i64.const -5) (i64.const 2)) (i64.const -1)) -(assert_return (invoke "rem_s" (i64.const 5) (i64.const -2)) (i64.const 1)) -(assert_return (invoke "rem_s" (i64.const -5) (i64.const -2)) (i64.const -1)) -(assert_return (invoke "rem_s" (i64.const 7) (i64.const 3)) (i64.const 1)) -(assert_return (invoke "rem_s" (i64.const -7) (i64.const 3)) (i64.const -1)) -(assert_return (invoke "rem_s" (i64.const 7) (i64.const -3)) (i64.const 1)) -(assert_return (invoke "rem_s" (i64.const -7) (i64.const -3)) (i64.const -1)) -(assert_return (invoke "rem_s" (i64.const 11) (i64.const 5)) (i64.const 1)) -(assert_return (invoke "rem_s" (i64.const 17) (i64.const 7)) (i64.const 3)) - -(assert_trap (invoke "rem_u" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "rem_u" (i64.const 0) (i64.const 0)) "integer divide by zero") -(assert_return (invoke "rem_u" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "rem_u" (i64.const 0) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "rem_u" (i64.const -1) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "rem_u" (i64.const 0x8000000000000000) (i64.const -1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "rem_u" (i64.const 0x8000000000000000) (i64.const 2)) (i64.const 0)) -(assert_return (invoke "rem_u" (i64.const 0x8ff00ff00ff00ff0) (i64.const 0x100000001)) (i64.const 0x80000001)) -(assert_return (invoke "rem_u" (i64.const 0x8000000000000001) (i64.const 1000)) (i64.const 809)) -(assert_return (invoke "rem_u" (i64.const 5) (i64.const 2)) (i64.const 1)) -(assert_return (invoke "rem_u" (i64.const -5) (i64.const 2)) (i64.const 1)) -(assert_return (invoke "rem_u" (i64.const 5) (i64.const -2)) (i64.const 5)) -(assert_return (invoke "rem_u" (i64.const -5) (i64.const -2)) (i64.const -5)) -(assert_return (invoke "rem_u" (i64.const 7) (i64.const 3)) (i64.const 1)) -(assert_return (invoke "rem_u" (i64.const 11) (i64.const 5)) (i64.const 1)) -(assert_return (invoke "rem_u" (i64.const 17) (i64.const 7)) (i64.const 3)) - -(assert_return (invoke "and" (i64.const 1) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "and" (i64.const 0) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "and" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "and" (i64.const 0) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "and" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i64.const 0)) -(assert_return (invoke "and" (i64.const 0x7fffffffffffffff) (i64.const -1)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "and" (i64.const 0xf0f0ffff) (i64.const 0xfffff0f0)) (i64.const 0xf0f0f0f0)) -(assert_return (invoke "and" (i64.const 0xffffffffffffffff) (i64.const 0xffffffffffffffff)) (i64.const 0xffffffffffffffff)) - -(assert_return (invoke "or" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "or" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "or" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "or" (i64.const 0) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "or" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i64.const -1)) -(assert_return (invoke "or" (i64.const 0x8000000000000000) (i64.const 0)) (i64.const 0x8000000000000000)) -(assert_return (invoke "or" (i64.const 0xf0f0ffff) (i64.const 0xfffff0f0)) (i64.const 0xffffffff)) -(assert_return (invoke "or" (i64.const 0xffffffffffffffff) (i64.const 0xffffffffffffffff)) (i64.const 0xffffffffffffffff)) - -(assert_return (invoke "xor" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "xor" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "xor" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "xor" (i64.const 0) (i64.const 0)) (i64.const 0)) -(assert_return (invoke "xor" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i64.const -1)) -(assert_return (invoke "xor" (i64.const 0x8000000000000000) (i64.const 0)) (i64.const 0x8000000000000000)) -(assert_return (invoke "xor" (i64.const -1) (i64.const 0x8000000000000000)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "xor" (i64.const -1) (i64.const 0x7fffffffffffffff)) (i64.const 0x8000000000000000)) -(assert_return (invoke "xor" (i64.const 0xf0f0ffff) (i64.const 0xfffff0f0)) (i64.const 0x0f0f0f0f)) -(assert_return (invoke "xor" (i64.const 0xffffffffffffffff) (i64.const 0xffffffffffffffff)) (i64.const 0)) - -(assert_return (invoke "shl" (i64.const 1) (i64.const 1)) (i64.const 2)) -(assert_return (invoke "shl" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "shl" (i64.const 0x7fffffffffffffff) (i64.const 1)) (i64.const 0xfffffffffffffffe)) -(assert_return (invoke "shl" (i64.const 0xffffffffffffffff) (i64.const 1)) (i64.const 0xfffffffffffffffe)) -(assert_return (invoke "shl" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "shl" (i64.const 0x4000000000000000) (i64.const 1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "shl" (i64.const 1) (i64.const 63)) (i64.const 0x8000000000000000)) -(assert_return (invoke "shl" (i64.const 1) (i64.const 64)) (i64.const 1)) -(assert_return (invoke "shl" (i64.const 1) (i64.const 65)) (i64.const 2)) -(assert_return (invoke "shl" (i64.const 1) (i64.const -1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "shl" (i64.const 1) (i64.const 0x7fffffffffffffff)) (i64.const 0x8000000000000000)) - -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const 1)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const 0x7fffffffffffffff) (i64.const 1)) (i64.const 0x3fffffffffffffff)) -(assert_return (invoke "shr_s" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 0xc000000000000000)) -(assert_return (invoke "shr_s" (i64.const 0x4000000000000000) (i64.const 1)) (i64.const 0x2000000000000000)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 64)) (i64.const 1)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 65)) (i64.const 0)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 0x7fffffffffffffff)) (i64.const 0)) -(assert_return (invoke "shr_s" (i64.const 1) (i64.const 0x8000000000000000)) (i64.const 1)) -(assert_return (invoke "shr_s" (i64.const 0x8000000000000000) (i64.const 63)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const 64)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const 65)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const -1)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const 0x7fffffffffffffff)) (i64.const -1)) -(assert_return (invoke "shr_s" (i64.const -1) (i64.const 0x8000000000000000)) (i64.const -1)) - -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 1)) (i64.const 0)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const 1)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "shr_u" (i64.const 0x7fffffffffffffff) (i64.const 1)) (i64.const 0x3fffffffffffffff)) -(assert_return (invoke "shr_u" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 0x4000000000000000)) -(assert_return (invoke "shr_u" (i64.const 0x4000000000000000) (i64.const 1)) (i64.const 0x2000000000000000)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 64)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 65)) (i64.const 0)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const -1)) (i64.const 0)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 0x7fffffffffffffff)) (i64.const 0)) -(assert_return (invoke "shr_u" (i64.const 1) (i64.const 0x8000000000000000)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const 0x8000000000000000) (i64.const 63)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const 64)) (i64.const -1)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const 65)) (i64.const 0x7fffffffffffffff)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const -1)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const 0x7fffffffffffffff)) (i64.const 1)) -(assert_return (invoke "shr_u" (i64.const -1) (i64.const 0x8000000000000000)) (i64.const -1)) - -(assert_return (invoke "rotl" (i64.const 1) (i64.const 1)) (i64.const 2)) -(assert_return (invoke "rotl" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "rotl" (i64.const -1) (i64.const 1)) (i64.const -1)) -(assert_return (invoke "rotl" (i64.const 1) (i64.const 64)) (i64.const 1)) -(assert_return (invoke "rotl" (i64.const 0xabcd987602468ace) (i64.const 1)) (i64.const 0x579b30ec048d159d)) -(assert_return (invoke "rotl" (i64.const 0xfe000000dc000000) (i64.const 4)) (i64.const 0xe000000dc000000f)) -(assert_return (invoke "rotl" (i64.const 0xabcd1234ef567809) (i64.const 53)) (i64.const 0x013579a2469deacf)) -(assert_return (invoke "rotl" (i64.const 0xabd1234ef567809c) (i64.const 63)) (i64.const 0x55e891a77ab3c04e)) -(assert_return (invoke "rotl" (i64.const 0xabcd1234ef567809) (i64.const 0xf5)) (i64.const 0x013579a2469deacf)) -(assert_return (invoke "rotl" (i64.const 0xabcd7294ef567809) (i64.const 0xffffffffffffffed)) (i64.const 0xcf013579ae529dea)) -(assert_return (invoke "rotl" (i64.const 0xabd1234ef567809c) (i64.const 0x800000000000003f)) (i64.const 0x55e891a77ab3c04e)) -(assert_return (invoke "rotl" (i64.const 1) (i64.const 63)) (i64.const 0x8000000000000000)) -(assert_return (invoke "rotl" (i64.const 0x8000000000000000) (i64.const 1)) (i64.const 1)) - -(assert_return (invoke "rotr" (i64.const 1) (i64.const 1)) (i64.const 0x8000000000000000)) -(assert_return (invoke "rotr" (i64.const 1) (i64.const 0)) (i64.const 1)) -(assert_return (invoke "rotr" (i64.const -1) (i64.const 1)) (i64.const -1)) -(assert_return (invoke "rotr" (i64.const 1) (i64.const 64)) (i64.const 1)) -(assert_return (invoke "rotr" (i64.const 0xabcd987602468ace) (i64.const 1)) (i64.const 0x55e6cc3b01234567)) -(assert_return (invoke "rotr" (i64.const 0xfe000000dc000000) (i64.const 4)) (i64.const 0x0fe000000dc00000)) -(assert_return (invoke "rotr" (i64.const 0xabcd1234ef567809) (i64.const 53)) (i64.const 0x6891a77ab3c04d5e)) -(assert_return (invoke "rotr" (i64.const 0xabd1234ef567809c) (i64.const 63)) (i64.const 0x57a2469deacf0139)) -(assert_return (invoke "rotr" (i64.const 0xabcd1234ef567809) (i64.const 0xf5)) (i64.const 0x6891a77ab3c04d5e)) -(assert_return (invoke "rotr" (i64.const 0xabcd7294ef567809) (i64.const 0xffffffffffffffed)) (i64.const 0x94a77ab3c04d5e6b)) -(assert_return (invoke "rotr" (i64.const 0xabd1234ef567809c) (i64.const 0x800000000000003f)) (i64.const 0x57a2469deacf0139)) -(assert_return (invoke "rotr" (i64.const 1) (i64.const 63)) (i64.const 2)) -(assert_return (invoke "rotr" (i64.const 0x8000000000000000) (i64.const 63)) (i64.const 1)) - -(assert_return (invoke "clz" (i64.const 0xffffffffffffffff)) (i64.const 0)) -(assert_return (invoke "clz" (i64.const 0)) (i64.const 64)) -(assert_return (invoke "clz" (i64.const 0x00008000)) (i64.const 48)) -(assert_return (invoke "clz" (i64.const 0xff)) (i64.const 56)) -(assert_return (invoke "clz" (i64.const 0x8000000000000000)) (i64.const 0)) -(assert_return (invoke "clz" (i64.const 1)) (i64.const 63)) -(assert_return (invoke "clz" (i64.const 2)) (i64.const 62)) -(assert_return (invoke "clz" (i64.const 0x7fffffffffffffff)) (i64.const 1)) - -(assert_return (invoke "ctz" (i64.const -1)) (i64.const 0)) -(assert_return (invoke "ctz" (i64.const 0)) (i64.const 64)) -(assert_return (invoke "ctz" (i64.const 0x00008000)) (i64.const 15)) -(assert_return (invoke "ctz" (i64.const 0x00010000)) (i64.const 16)) -(assert_return (invoke "ctz" (i64.const 0x8000000000000000)) (i64.const 63)) -(assert_return (invoke "ctz" (i64.const 0x7fffffffffffffff)) (i64.const 0)) - -(assert_return (invoke "popcnt" (i64.const -1)) (i64.const 64)) -(assert_return (invoke "popcnt" (i64.const 0)) (i64.const 0)) -(assert_return (invoke "popcnt" (i64.const 0x00008000)) (i64.const 1)) -(assert_return (invoke "popcnt" (i64.const 0x8000800080008000)) (i64.const 4)) -(assert_return (invoke "popcnt" (i64.const 0x7fffffffffffffff)) (i64.const 63)) -(assert_return (invoke "popcnt" (i64.const 0xAAAAAAAA55555555)) (i64.const 32)) -(assert_return (invoke "popcnt" (i64.const 0x99999999AAAAAAAA)) (i64.const 32)) -(assert_return (invoke "popcnt" (i64.const 0xDEADBEEFDEADBEEF)) (i64.const 48)) - -(assert_return (invoke "eqz" (i64.const 0)) (i32.const 1)) -(assert_return (invoke "eqz" (i64.const 1)) (i32.const 0)) -(assert_return (invoke "eqz" (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "eqz" (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "eqz" (i64.const 0xffffffffffffffff)) (i32.const 0)) - -(assert_return (invoke "eq" (i64.const 0) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "eq" (i64.const 1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "eq" (i64.const -1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "eq" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "eq" (i64.const -1) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "eq" (i64.const 1) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "eq" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) - -(assert_return (invoke "ne" (i64.const 0) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "ne" (i64.const 1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "ne" (i64.const -1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "ne" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "ne" (i64.const -1) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "ne" (i64.const 1) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "ne" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) - -(assert_return (invoke "lt_s" (i64.const 0) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const -1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const -1) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 1) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 0) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "lt_s" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "lt_s" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "lt_s" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "lt_s" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) - -(assert_return (invoke "lt_u" (i64.const 0) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const -1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const -1) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 1) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "lt_u" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "lt_u" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "lt_u" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "lt_u" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) - -(assert_return (invoke "le_s" (i64.const 0) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const -1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const -1) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 1) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "le_s" (i64.const 0) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "le_s" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "le_s" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "le_s" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) - -(assert_return (invoke "le_u" (i64.const 0) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const 1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const -1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "le_u" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const -1) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const 1) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "le_u" (i64.const 0) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "le_u" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "le_u" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "le_u" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "le_u" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) - -(assert_return (invoke "gt_s" (i64.const 0) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const -1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const -1) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 1) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "gt_s" (i64.const 0) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "gt_s" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "gt_s" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "gt_s" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) - -(assert_return (invoke "gt_u" (i64.const 0) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const 1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const -1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "gt_u" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const -1) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const 1) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "gt_u" (i64.const 0) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "gt_u" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "gt_u" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "gt_u" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "gt_u" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) - -(assert_return (invoke "ge_s" (i64.const 0) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const -1) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const -1) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 1) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 0) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 0)) -(assert_return (invoke "ge_s" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "ge_s" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ge_s" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 0)) -(assert_return (invoke "ge_s" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 1)) - -(assert_return (invoke "ge_u" (i64.const 0) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const -1) (i64.const 1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0x7fffffffffffffff) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const -1) (i64.const -1)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 1) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0) (i64.const 1)) (i32.const 0)) -(assert_return (invoke "ge_u" (i64.const 0x8000000000000000) (i64.const 0)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0) (i64.const 0x8000000000000000)) (i32.const 0)) -(assert_return (invoke "ge_u" (i64.const 0x8000000000000000) (i64.const -1)) (i32.const 0)) -(assert_return (invoke "ge_u" (i64.const -1) (i64.const 0x8000000000000000)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0x8000000000000000) (i64.const 0x7fffffffffffffff)) (i32.const 1)) -(assert_return (invoke "ge_u" (i64.const 0x7fffffffffffffff) (i64.const 0x8000000000000000)) (i32.const 0)) - - -;; Type check - -(assert_invalid (module (func (result i64) (i64.add (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.and (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.div_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.div_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.mul (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.or (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.rem_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.rem_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.rotl (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.rotr (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.shl (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.shr_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.shr_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.sub (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.xor (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.eqz (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.clz (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.ctz (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.popcnt (i32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.eq (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.ge_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.ge_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.gt_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.gt_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.le_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.le_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.lt_s (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.lt_u (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (func (result i64) (i64.ne (i32.const 0) (f32.const 0)))) "type mismatch") diff --git a/test/spec/inline-module.wast b/test/spec/inline-module.wast deleted file mode 100644 index dc7ead7767f..00000000000 --- a/test/spec/inline-module.wast +++ /dev/null @@ -1 +0,0 @@ -(func) (memory 0) (func (export "f")) diff --git a/test/spec/int_exprs.wast b/test/spec/int_exprs.wast deleted file mode 100644 index 22e1fbcb5c9..00000000000 --- a/test/spec/int_exprs.wast +++ /dev/null @@ -1,350 +0,0 @@ -;; Test interesting integer "expressions". These tests contain code -;; patterns which tempt common value-changing optimizations. - -;; Test that x+1>n is not folded to x. - -(module - (func (export "i32.no_fold_shl_shr_s") (param $x i32) (result i32) - (i32.shr_s (i32.shl (local.get $x) (i32.const 1)) (i32.const 1))) - (func (export "i32.no_fold_shl_shr_u") (param $x i32) (result i32) - (i32.shr_u (i32.shl (local.get $x) (i32.const 1)) (i32.const 1))) - - (func (export "i64.no_fold_shl_shr_s") (param $x i64) (result i64) - (i64.shr_s (i64.shl (local.get $x) (i64.const 1)) (i64.const 1))) - (func (export "i64.no_fold_shl_shr_u") (param $x i64) (result i64) - (i64.shr_u (i64.shl (local.get $x) (i64.const 1)) (i64.const 1))) -) - -(assert_return (invoke "i32.no_fold_shl_shr_s" (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "i32.no_fold_shl_shr_u" (i32.const 0x80000000)) (i32.const 0)) -(assert_return (invoke "i64.no_fold_shl_shr_s" (i64.const 0x8000000000000000)) (i64.const 0)) -(assert_return (invoke "i64.no_fold_shl_shr_u" (i64.const 0x8000000000000000)) (i64.const 0)) - -;; Test that x>>n<?,./ ") (result i32) (i32.const 6)) - - ;; Test that we can use names that have special meaning in JS. - (func (export "NaN") (result i32) (i32.const 7)) - (func (export "Infinity") (result i32) (i32.const 8)) - (func (export "if") (result i32) (i32.const 9)) - - ;; Test that we can use common libc names without conflict. - (func (export "malloc") (result i32) (i32.const 10)) - - ;; Test that we can use some libc hidden names without conflict. - (func (export "_malloc") (result i32) (i32.const 11)) - (func (export "__malloc") (result i32) (i32.const 12)) - - ;; Test that names are case-sensitive. - (func (export "a") (result i32) (i32.const 13)) - (func (export "A") (result i32) (i32.const 14)) - - ;; Test that UTF-8 BOM code points can appear in identifiers. - (func (export "") (result i32) (i32.const 15)) - - ;; Test that Unicode normalization is not applied. These function names - ;; contain different codepoints which normalize to the same thing under - ;; NFC or NFD. - (func (export "Å") (result i32) (i32.const 16)) - (func (export "Å") (result i32) (i32.const 17)) - (func (export "Å") (result i32) (i32.const 18)) - - ;; Test that Unicode compatibility normalization is not applied. These - ;; function names contain different codepoints which normalize to the - ;; same thing under NFKC or NFKD. - (func (export "ffi") (result i32) (i32.const 19)) - (func (export "ffi") (result i32) (i32.const 20)) - (func (export "ffi") (result i32) (i32.const 21)) - - ;; Test the C0 control codes. - (func (export "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f") (result i32) (i32.const 22)) - (func (export "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f") (result i32) (i32.const 23)) - ;; Test miscellaneous control codes. - (func (export " \7f") (result i32) (i32.const 24)) - ;; Test the C1 control codes. - (func (export "\c2\80\c2\81\c2\82\c2\83\c2\84\c2\85\c2\86\c2\87\c2\88\c2\89\c2\8a\c2\8b\c2\8c\c2\8d\c2\8e\c2\8f") (result i32) (i32.const 25)) - (func (export "\c2\90\c2\91\c2\92\c2\93\c2\94\c2\95\c2\96\c2\97\c2\98\c2\99\c2\9a\c2\9b\c2\9c\c2\9d\c2\9e\c2\9f") (result i32) (i32.const 26)) - ;; Test the Unicode Specials. - (func (export "\ef\bf\b0\ef\bf\b1\ef\bf\b2\ef\bf\b3\ef\bf\b4\ef\bf\b5\ef\bf\b6\ef\bf\b7") (result i32) (i32.const 27)) - (func (export "\ef\bf\b8\ef\bf\b9\ef\bf\ba\ef\bf\bb\ef\bf\bc\ef\bf\bd\ef\bf\be\ef\bf\bf") (result i32) (i32.const 28)) - - ;; Test that the control pictures are distinct from the control codes they - ;; depict. These correspond to the C0 and miscellaneous control code tests - ;; above. - (func (export "␀␁␂␃␄␅␆␇␈␉␊␋␌␍␎␏") (result i32) (i32.const 29)) - (func (export "␐␑␒␓␔␕␖␗␘␙␚␛␜␝␞␟") (result i32) (i32.const 30)) - (func (export "␠␡") (result i32) (i32.const 31)) - - ;; Test the Unicode Specials in non-escaped form (excluding U+FFFE and - ;; U+FFFF, so that generic tools don't detect this file as non-UTF-8). - (func (export "￰￱￲￳￴￵￶￷￸�") (result i32) (i32.const 32)) - - ;; Test a bare ZWJ code point. - (func (export "‍") (result i32) (i32.const 33)) - ;; Test a bare ZWNJ code point. - (func (export "‌") (result i32) (i32.const 34)) - - ;; Test various bare joiner code points. - (func (export "͏") (result i32) (i32.const 35)) - (func (export "⁠") (result i32) (i32.const 36)) - (func (export "⵿") (result i32) (i32.const 37)) - (func (export "𑁿") (result i32) (i32.const 38)) - (func (export "᠎") (result i32) (i32.const 39)) - - ;; Test various interesting code points: reverse BOM, zero-width space, - ;; no-break space, soft hyphen, word joiner, ogham space mark, - ;; right-to-left override, left-to-right override. - (func (export "￯​ ­⁠ ‮‭") (result i32) (i32.const 40)) - - ;; Test more interesting code points: left-to-right mark, right-to-left mark, - ;; non-breaking hyphen, line separator, paragraph separator, - ;; left-to-right embedding, right-to-left embedding, - ;; pop directional formatting, narrow no-break space, left-to-right isolate, - ;; right-to-left isolate, first strong isolate, pop directional isolate. - (func (export "‎‏‑

‪‫‬ ⁦⁧⁨⁩") (result i32) (i32.const 41)) - - ;; Test some deprecated code points: inhibit symmetric swapping, - ;; activate symmetric swapping, inhibit arabic form shaping, - ;; activate arabic form shaping, national digit shapes, nominal digit shapes. - (func (export "") (result i32) (i32.const 42)) - - ;; Test "invisible" operator code points. - (func (export "⁡⁢⁣⁤") (result i32) (i32.const 43)) - - ;; Test that code points outside the BMP are supported. - (func (export "𐀀󟿿􏿿") (result i32) (i32.const 44)) - - ;; Test that WebAssembly implementations cope in the presence of Zalgo. - (func (export "Z̴͇̫̥̪͓͈͔͎̗̞̺̯̱̞̙̱̜̖̠̏͆̆͛͌͘͞ḁ̶̰̳̭͙̲̱̹̝͎̼͗ͨ̎̄̆͗̿̀́͟͡l̶̷͉̩̹̫̝͖̙̲̼͇͚͍̮͎̥̞̈́͊͗ͦ̈́ͫ̇́̚ͅͅg̶͕͔͚̩̓̐̅ͮ̔̐̎̂̏̾͊̍͋͊ͧ́̆ͦ͞o̡͋̔͐ͪͩ͏̢̧̫̙̤̮͖͙͓̺̜̩̼̘̠́") (result i32) (i32.const 45)) - - ;; Test Hangul filler code points. - (func (export "ᅟᅠㅤᅠ") (result i32) (i32.const 46)) - - ;; Test variation selectors (which are also ID_Continue code points). - (func (export "︀") (result i32) (i32.const 47)) - (func (export "︄") (result i32) (i32.const 48)) - (func (export "󠄀") (result i32) (i32.const 49)) - (func (export "󠇯") (result i32) (i32.const 50)) - - ;; Test an uncombined combining code point. - (func (export "̈") (result i32) (i32.const 51)) - - ;; Test that numerous different present and historical representations of the - ;; "newline" concept are distinct. Tests largely inspired by: - ;; https://en.wikipedia.org/wiki/Newline#Representations - ;; https://en.wikipedia.org/wiki/Newline#Unicode and - ;; https://en.wikipedia.org/wiki/Newline#Reverse_and_partial_line_feeds - (func (export "\0a") (result i32) (i32.const 52)) - (func (export "␤") (result i32) (i32.const 53)) - (func (export "
") (result i32) (i32.const 54)) - (func (export "\0d") (result i32) (i32.const 55)) - (func (export "\0d\0a") (result i32) (i32.const 56)) - (func (export "\0a\0d") (result i32) (i32.const 57)) - (func (export "\1e") (result i32) (i32.const 58)) - (func (export "\0b") (result i32) (i32.const 59)) - (func (export "\0c") (result i32) (i32.const 60)) - (func (export "\c2\85") (result i32) (i32.const 61)) - (func (export "
") (result i32) (i32.const 62)) - (func (export "…") (result i32) (i32.const 63)) - (func (export "⏎") (result i32) (i32.const 64)) - (func (export "\c2\8b") (result i32) (i32.const 65)) - (func (export "\c2\8c") (result i32) (i32.const 66)) - (func (export "\c2\8d") (result i32) (i32.const 67)) - (func (export "↵") (result i32) (i32.const 68)) - (func (export "↩") (result i32) (i32.const 69)) - (func (export "⌤") (result i32) (i32.const 70)) - (func (export "⤶") (result i32) (i32.const 71)) - (func (export "↲") (result i32) (i32.const 72)) - (func (export "⮨") (result i32) (i32.const 73)) - (func (export "⮰") (result i32) (i32.const 74)) - - ;; Test that non-characters are not replaced by the replacement character. - (func (export "�") (result i32) (i32.const 75)) - (func (export "\ef\b7\90") (result i32) (i32.const 76)) - (func (export "\ef\b7\91") (result i32) (i32.const 77)) - (func (export "\ef\b7\92") (result i32) (i32.const 78)) - (func (export "\ef\b7\93") (result i32) (i32.const 79)) - (func (export "\ef\b7\94") (result i32) (i32.const 80)) - (func (export "\ef\b7\95") (result i32) (i32.const 81)) - (func (export "\ef\b7\96") (result i32) (i32.const 82)) - (func (export "\ef\b7\97") (result i32) (i32.const 83)) - (func (export "\ef\b7\98") (result i32) (i32.const 84)) - (func (export "\ef\b7\99") (result i32) (i32.const 85)) - (func (export "\ef\b7\9a") (result i32) (i32.const 86)) - (func (export "\ef\b7\9b") (result i32) (i32.const 87)) - (func (export "\ef\b7\9c") (result i32) (i32.const 88)) - (func (export "\ef\b7\9d") (result i32) (i32.const 89)) - (func (export "\ef\b7\9e") (result i32) (i32.const 90)) - (func (export "\ef\b7\9f") (result i32) (i32.const 91)) - (func (export "\ef\b7\a0") (result i32) (i32.const 92)) - (func (export "\ef\b7\a1") (result i32) (i32.const 93)) - (func (export "\ef\b7\a2") (result i32) (i32.const 94)) - (func (export "\ef\b7\a3") (result i32) (i32.const 95)) - (func (export "\ef\b7\a4") (result i32) (i32.const 96)) - (func (export "\ef\b7\a5") (result i32) (i32.const 97)) - (func (export "\ef\b7\a6") (result i32) (i32.const 98)) - (func (export "\ef\b7\a7") (result i32) (i32.const 99)) - (func (export "\ef\b7\a8") (result i32) (i32.const 100)) - (func (export "\ef\b7\a9") (result i32) (i32.const 101)) - (func (export "\ef\b7\aa") (result i32) (i32.const 102)) - (func (export "\ef\b7\ab") (result i32) (i32.const 103)) - (func (export "\ef\b7\ac") (result i32) (i32.const 104)) - (func (export "\ef\b7\ad") (result i32) (i32.const 105)) - (func (export "\ef\b7\ae") (result i32) (i32.const 106)) - (func (export "\ef\b7\af") (result i32) (i32.const 107)) - (func (export "\ef\bf\be") (result i32) (i32.const 108)) - (func (export "\ef\bf\bf") (result i32) (i32.const 109)) - (func (export "\f0\9f\bf\be") (result i32) (i32.const 110)) - (func (export "\f0\9f\bf\bf") (result i32) (i32.const 111)) - (func (export "\f0\af\bf\be") (result i32) (i32.const 112)) - (func (export "\f0\af\bf\bf") (result i32) (i32.const 113)) - (func (export "\f0\bf\bf\be") (result i32) (i32.const 114)) - (func (export "\f0\bf\bf\bf") (result i32) (i32.const 115)) - (func (export "\f1\8f\bf\be") (result i32) (i32.const 116)) - (func (export "\f1\8f\bf\bf") (result i32) (i32.const 117)) - (func (export "\f1\9f\bf\be") (result i32) (i32.const 118)) - (func (export "\f1\9f\bf\bf") (result i32) (i32.const 119)) - (func (export "\f1\af\bf\be") (result i32) (i32.const 120)) - (func (export "\f1\af\bf\bf") (result i32) (i32.const 121)) - (func (export "\f1\bf\bf\be") (result i32) (i32.const 122)) - (func (export "\f1\bf\bf\bf") (result i32) (i32.const 123)) - (func (export "\f2\8f\bf\be") (result i32) (i32.const 124)) - (func (export "\f2\8f\bf\bf") (result i32) (i32.const 125)) - (func (export "\f2\9f\bf\be") (result i32) (i32.const 126)) - (func (export "\f2\9f\bf\bf") (result i32) (i32.const 127)) - (func (export "\f2\af\bf\be") (result i32) (i32.const 128)) - (func (export "\f2\af\bf\bf") (result i32) (i32.const 129)) - (func (export "\f2\bf\bf\be") (result i32) (i32.const 130)) - (func (export "\f2\bf\bf\bf") (result i32) (i32.const 131)) - (func (export "\f3\8f\bf\be") (result i32) (i32.const 132)) - (func (export "\f3\8f\bf\bf") (result i32) (i32.const 133)) - (func (export "\f3\9f\bf\be") (result i32) (i32.const 134)) - (func (export "\f3\9f\bf\bf") (result i32) (i32.const 135)) - (func (export "\f3\af\bf\be") (result i32) (i32.const 136)) - (func (export "\f3\af\bf\bf") (result i32) (i32.const 137)) - (func (export "\f3\bf\bf\be") (result i32) (i32.const 138)) - (func (export "\f3\bf\bf\bf") (result i32) (i32.const 139)) - (func (export "\f4\8f\bf\be") (result i32) (i32.const 140)) - (func (export "\f4\8f\bf\bf") (result i32) (i32.const 141)) - - ;; Test an interrobang with combining diacritical marks above. - ;; https://xkcd.com/1209/ - (func (export "̈‽̈̉") (result i32) (i32.const 142)) - - ;; Test that RLM/LRM don't change the logical byte order. - (func (export "abc") (result i32) (i32.const 143)) - (func (export "‭abc") (result i32) (i32.const 144)) - (func (export "‮cba") (result i32) (i32.const 145)) - (func (export "‭abc‮") (result i32) (i32.const 146)) - (func (export "‮cba‭") (result i32) (i32.const 147)) - - ;; Test that Unicode font variations are preserved. - (func (export "𝑨") (result i32) (i32.const 148)) - (func (export "𝐴") (result i32) (i32.const 149)) - (func (export "𝘈") (result i32) (i32.const 150)) - (func (export "𝘼") (result i32) (i32.const 151)) - (func (export "𝐀") (result i32) (i32.const 152)) - (func (export "𝓐") (result i32) (i32.const 153)) - (func (export "𝕬") (result i32) (i32.const 154)) - (func (export "𝗔") (result i32) (i32.const 155)) - (func (export "𝒜") (result i32) (i32.const 156)) - (func (export "𝔄") (result i32) (i32.const 157)) - (func (export "𝔸") (result i32) (i32.const 158)) - (func (export "𝖠") (result i32) (i32.const 159)) - (func (export "𝙰") (result i32) (i32.const 160)) - (func (export "ᴀ") (result i32) (i32.const 161)) - - ;; Test that various additional letter variations are preserved. - ;; (U+0040, U+0061, U+0041, U+00C5, U+0041 U+030A, U+212B, and the font - ;; variations are covered above.) - (func (export "ᴬ") (result i32) (i32.const 162)) - (func (export "Ⓐ") (result i32) (i32.const 163)) - (func (export "A") (result i32) (i32.const 164)) - (func (export "🄐") (result i32) (i32.const 165)) - (func (export "🄰") (result i32) (i32.const 166)) - (func (export "󠁁") (result i32) (i32.const 167)) - (func (export "U+0041") (result i32) (i32.const 168)) - (func (export "A​") (result i32) (i32.const 169)) - (func (export "А") (result i32) (i32.const 170)) - (func (export "Ꙗ") (result i32) (i32.const 171)) - (func (export "ⷼ") (result i32) (i32.const 172)) - (func (export "ⷶ") (result i32) (i32.const 173)) - (func (export "Ɐ") (result i32) (i32.const 174)) - (func (export "🅐") (result i32) (i32.const 175)) - (func (export "🅰") (result i32) (i32.const 176)) - (func (export "Ⱝ") (result i32) (i32.const 177)) - (func (export "𐐂") (result i32) (i32.const 178)) - (func (export "𐐈") (result i32) (i32.const 179)) - (func (export "𐒰") (result i32) (i32.const 180)) - (func (export "À") (result i32) (i32.const 181)) - (func (export "Á") (result i32) (i32.const 182)) - (func (export "Â") (result i32) (i32.const 183)) - (func (export "Ã") (result i32) (i32.const 184)) - (func (export "Ä") (result i32) (i32.const 185)) - (func (export "Ā") (result i32) (i32.const 186)) - (func (export "Ă") (result i32) (i32.const 187)) - (func (export "Ą") (result i32) (i32.const 188)) - (func (export "Ǎ") (result i32) (i32.const 189)) - (func (export "Ǟ") (result i32) (i32.const 190)) - (func (export "Ǡ") (result i32) (i32.const 191)) - (func (export "Ǻ") (result i32) (i32.const 192)) - (func (export "Ȁ") (result i32) (i32.const 193)) - (func (export "Ȃ") (result i32) (i32.const 194)) - (func (export "Ȧ") (result i32) (i32.const 195)) - (func (export "Ⱥ") (result i32) (i32.const 196)) - (func (export "Ӑ") (result i32) (i32.const 197)) - (func (export "Ӓ") (result i32) (i32.const 198)) - (func (export "ߊ") (result i32) (i32.const 199)) - (func (export "ࠡ") (result i32) (i32.const 200)) - (func (export "ࠢ") (result i32) (i32.const 201)) - (func (export "ࠣ") (result i32) (i32.const 202)) - (func (export "ࠤ") (result i32) (i32.const 203)) - (func (export "ࠥ") (result i32) (i32.const 204)) - (func (export "ऄ") (result i32) (i32.const 205)) - (func (export "अ") (result i32) (i32.const 206)) - (func (export "ॲ") (result i32) (i32.const 207)) - (func (export "অ") (result i32) (i32.const 208)) - (func (export "ਅ") (result i32) (i32.const 209)) - (func (export "અ") (result i32) (i32.const 210)) - (func (export "ଅ") (result i32) (i32.const 211)) - (func (export "அ") (result i32) (i32.const 212)) - (func (export "అ") (result i32) (i32.const 213)) - (func (export "ಅ") (result i32) (i32.const 214)) - (func (export "അ") (result i32) (i32.const 215)) - (func (export "ะ") (result i32) (i32.const 216)) - (func (export "ະ") (result i32) (i32.const 217)) - (func (export "༁") (result i32) (i32.const 218)) - (func (export "ཨ") (result i32) (i32.const 219)) - (func (export "ྸ") (result i32) (i32.const 220)) - (func (export "အ") (result i32) (i32.const 221)) - (func (export "ဢ") (result i32) (i32.const 222)) - (func (export "ႜ") (result i32) (i32.const 223)) - (func (export "ᅡ") (result i32) (i32.const 224)) - (func (export "አ") (result i32) (i32.const 225)) - (func (export "ዐ") (result i32) (i32.const 226)) - (func (export "Ꭰ") (result i32) (i32.const 227)) - (func (export "ᐊ") (result i32) (i32.const 228)) - (func (export "ᖳ") (result i32) (i32.const 229)) - (func (export "ᚨ") (result i32) (i32.const 230)) - (func (export "ᚪ") (result i32) (i32.const 231)) - (func (export "ᛆ") (result i32) (i32.const 232)) - (func (export "ᜀ") (result i32) (i32.const 233)) - (func (export "ᜠ") (result i32) (i32.const 234)) - (func (export "ᝀ") (result i32) (i32.const 235)) - (func (export "ᝠ") (result i32) (i32.const 236)) - (func (export "ᠠ") (result i32) (i32.const 237)) - (func (export "ᢇ") (result i32) (i32.const 238)) - (func (export "ᤠ") (result i32) (i32.const 239)) - (func (export "ᥣ") (result i32) (i32.const 240)) - (func (export "ᨕ") (result i32) (i32.const 241)) - (func (export "ᩋ") (result i32) (i32.const 242)) - (func (export "ᩡ") (result i32) (i32.const 243)) - (func (export "ᮃ") (result i32) (i32.const 244)) - (func (export "ᯀ") (result i32) (i32.const 245)) - (func (export "ᯁ") (result i32) (i32.const 246)) - (func (export "ᰣ") (result i32) (i32.const 247)) - (func (export "Ḁ") (result i32) (i32.const 248)) - (func (export "Ạ") (result i32) (i32.const 249)) - (func (export "Ả") (result i32) (i32.const 250)) - (func (export "Ấ") (result i32) (i32.const 251)) - (func (export "Ầ") (result i32) (i32.const 252)) - (func (export "Ẩ") (result i32) (i32.const 253)) - (func (export "Ẫ") (result i32) (i32.const 254)) - (func (export "Ậ") (result i32) (i32.const 255)) - (func (export "Ắ") (result i32) (i32.const 256)) - (func (export "Ằ") (result i32) (i32.const 257)) - (func (export "Ẳ") (result i32) (i32.const 258)) - (func (export "Ẵ") (result i32) (i32.const 259)) - (func (export "Ặ") (result i32) (i32.const 260)) - (func (export "あ") (result i32) (i32.const 261)) - (func (export "ア") (result i32) (i32.const 262)) - (func (export "ㄚ") (result i32) (i32.const 263)) - (func (export "ㅏ") (result i32) (i32.const 264)) - (func (export "㈎") (result i32) (i32.const 265)) - (func (export "㈏") (result i32) (i32.const 266)) - (func (export "㈐") (result i32) (i32.const 267)) - (func (export "㈑") (result i32) (i32.const 268)) - (func (export "㈒") (result i32) (i32.const 269)) - (func (export "㈓") (result i32) (i32.const 270)) - (func (export "㈔") (result i32) (i32.const 271)) - (func (export "㈕") (result i32) (i32.const 272)) - (func (export "㈖") (result i32) (i32.const 273)) - (func (export "㈗") (result i32) (i32.const 274)) - (func (export "㈘") (result i32) (i32.const 275)) - (func (export "㈙") (result i32) (i32.const 276)) - (func (export "㈚") (result i32) (i32.const 277)) - (func (export "㈛") (result i32) (i32.const 278)) - (func (export "㉮") (result i32) (i32.const 279)) - (func (export "㉯") (result i32) (i32.const 280)) - (func (export "㉰") (result i32) (i32.const 281)) - (func (export "㉱") (result i32) (i32.const 282)) - (func (export "㉲") (result i32) (i32.const 283)) - (func (export "㉳") (result i32) (i32.const 284)) - (func (export "㉴") (result i32) (i32.const 285)) - (func (export "㉵") (result i32) (i32.const 286)) - (func (export "㉶") (result i32) (i32.const 287)) - (func (export "㉷") (result i32) (i32.const 288)) - (func (export "㉸") (result i32) (i32.const 289)) - (func (export "㉹") (result i32) (i32.const 290)) - (func (export "㉺") (result i32) (i32.const 291)) - (func (export "㉻") (result i32) (i32.const 292)) - (func (export "㋐") (result i32) (i32.const 293)) - (func (export "ꀊ") (result i32) (i32.const 294)) - (func (export "ꓮ") (result i32) (i32.const 295)) - (func (export "ꕉ") (result i32) (i32.const 296)) - (func (export "ꚠ") (result i32) (i32.const 297)) - (func (export "ꠀ") (result i32) (i32.const 298)) - (func (export "ꠣ") (result i32) (i32.const 299)) - (func (export "ꡝ") (result i32) (i32.const 300)) - (func (export "ꢂ") (result i32) (i32.const 301)) - (func (export "꣪") (result i32) (i32.const 302)) - (func (export "ꤢ") (result i32) (i32.const 303)) - (func (export "ꥆ") (result i32) (i32.const 304)) - (func (export "ꦄ") (result i32) (i32.const 305)) - (func (export "ꨀ") (result i32) (i32.const 306)) - (func (export "ア") (result i32) (i32.const 307)) - (func (export "ᅡ") (result i32) (i32.const 308)) - (func (export "𐀀") (result i32) (i32.const 309)) - (func (export "𐊀") (result i32) (i32.const 310)) - (func (export "𐊠") (result i32) (i32.const 311)) - (func (export "𐌀") (result i32) (i32.const 312)) - (func (export "𐎠") (result i32) (i32.const 313)) - (func (export "𐒖") (result i32) (i32.const 314)) - (func (export "𐔀") (result i32) (i32.const 315)) - (func (export "𐝀") (result i32) (i32.const 316)) - (func (export "𐠀") (result i32) (i32.const 317)) - (func (export "𐤠") (result i32) (i32.const 318)) - (func (export "𐦀") (result i32) (i32.const 319)) - (func (export "𐦠") (result i32) (i32.const 320)) - (func (export "𐨀") (result i32) (i32.const 321)) - (func (export "𐬀") (result i32) (i32.const 322)) - (func (export "𐰀") (result i32) (i32.const 323)) - (func (export "𐰁") (result i32) (i32.const 324)) - (func (export "𐲀") (result i32) (i32.const 325)) - (func (export "𑀅") (result i32) (i32.const 326)) - (func (export "𑂃") (result i32) (i32.const 327)) - (func (export "𑄧") (result i32) (i32.const 328)) - (func (export "𑅐") (result i32) (i32.const 329)) - (func (export "𑆃") (result i32) (i32.const 330)) - (func (export "𑈀") (result i32) (i32.const 331)) - (func (export "𑊀") (result i32) (i32.const 332)) - (func (export "𑊰") (result i32) (i32.const 333)) - (func (export "𑌅") (result i32) (i32.const 334)) - (func (export "𑍰") (result i32) (i32.const 335)) - (func (export "𑐀") (result i32) (i32.const 336)) - (func (export "𑒁") (result i32) (i32.const 337)) - (func (export "𑖀") (result i32) (i32.const 338)) - (func (export "𑘀") (result i32) (i32.const 339)) - (func (export "𑚀") (result i32) (i32.const 340)) - (func (export "𑜒") (result i32) (i32.const 341)) - (func (export "𑜠") (result i32) (i32.const 342)) - (func (export "𑢡") (result i32) (i32.const 343)) - (func (export "𑫕") (result i32) (i32.const 344)) - (func (export "𑰀") (result i32) (i32.const 345)) - (func (export "𑲏") (result i32) (i32.const 346)) - (func (export "𑲯") (result i32) (i32.const 347)) - (func (export "𒀀") (result i32) (i32.const 348)) - (func (export "𖧕") (result i32) (i32.const 349)) - (func (export "𖩆") (result i32) (i32.const 350)) - (func (export "𖫧") (result i32) (i32.const 351)) - (func (export "𖽔") (result i32) (i32.const 352)) - (func (export "𛱁") (result i32) (i32.const 353)) - (func (export "𛱤") (result i32) (i32.const 354)) - (func (export "𞠣") (result i32) (i32.const 355)) - (func (export "🇦") (result i32) (i32.const 356)) - (func (export "Ɑ") (result i32) (i32.const 357)) - (func (export "Λ") (result i32) (i32.const 358)) - (func (export "Ɒ") (result i32) (i32.const 359)) - (func (export "ª") (result i32) (i32.const 360)) - (func (export "∀") (result i32) (i32.const 361)) - (func (export "₳") (result i32) (i32.const 362)) - (func (export "𐤀") (result i32) (i32.const 363)) - (func (export "Ⲁ") (result i32) (i32.const 364)) - (func (export "𐌰") (result i32) (i32.const 365)) - (func (export "Ά") (result i32) (i32.const 366)) - (func (export "Α") (result i32) (i32.const 367)) - (func (export "Ἀ") (result i32) (i32.const 368)) - (func (export "Ἁ") (result i32) (i32.const 369)) - (func (export "Ἂ") (result i32) (i32.const 370)) - (func (export "Ἃ") (result i32) (i32.const 371)) - (func (export "Ἄ") (result i32) (i32.const 372)) - (func (export "Ἅ") (result i32) (i32.const 373)) - (func (export "Ἆ") (result i32) (i32.const 374)) - (func (export "Ἇ") (result i32) (i32.const 375)) - (func (export "ᾈ") (result i32) (i32.const 376)) - (func (export "ᾉ") (result i32) (i32.const 377)) - (func (export "ᾊ") (result i32) (i32.const 378)) - (func (export "ᾋ") (result i32) (i32.const 379)) - (func (export "ᾌ") (result i32) (i32.const 380)) - (func (export "ᾍ") (result i32) (i32.const 381)) - (func (export "ᾎ") (result i32) (i32.const 382)) - (func (export "ᾏ") (result i32) (i32.const 383)) - (func (export "Ᾰ") (result i32) (i32.const 384)) - (func (export "Ᾱ") (result i32) (i32.const 385)) - (func (export "Ὰ") (result i32) (i32.const 386)) - (func (export "Ά") (result i32) (i32.const 387)) - (func (export "ᾼ") (result i32) (i32.const 388)) - (func (export "𝚨") (result i32) (i32.const 389)) - (func (export "𝛢") (result i32) (i32.const 390)) - (func (export "𝜜") (result i32) (i32.const 391)) - (func (export "𝝖") (result i32) (i32.const 392)) - (func (export "𝞐") (result i32) (i32.const 393)) - (func (export "⍶") (result i32) (i32.const 394)) - (func (export "⍺") (result i32) (i32.const 395)) - (func (export "⩜") (result i32) (i32.const 396)) - (func (export "ᗅ") (result i32) (i32.const 397)) - (func (export "Ꭺ") (result i32) (i32.const 398)) - - ;; Test unmatched "closing" and "opening" code points. - (func (export ")˺˼𔗏𝅴𝅶𝅸𝅺⁾₎❩❫⟯﴿︶﹚)⦆󠀩❳❵⟧⟩⟫⟭⦈⦊⦖⸣⸥︘︸︺︼︾﹀﹂﹄﹈﹜﹞]}」󠁝󠁽»’”›❯") (result i32) (i32.const 399)) - (func (export "(˹˻𔗎𝅳𝅵𝅷𝅹⁽₍❨❪⟮﴾︵﹙(⦅󠀨❲❴⟦⟨⟪⟬⦇⦉⦕⸢⸤︗︷︹︻︽︿﹁﹃﹇﹛﹝[{「󠁛󠁻«‘“‹❮") (result i32) (i32.const 400)) - (func (export "𝪋𝪤") (result i32) (i32.const 401)) - (func (export "𝪋") (result i32) (i32.const 402)) - - ;; Test that Unicode fraction normalization is not applied. - (func (export "½") (result i32) (i32.const 403)) - (func (export "1⁄2") (result i32) (i32.const 404)) - (func (export "1/2") (result i32) (i32.const 405)) - (func (export "୳") (result i32) (i32.const 406)) - (func (export "൴") (result i32) (i32.const 407)) - (func (export "⳽") (result i32) (i32.const 408)) - (func (export "꠱") (result i32) (i32.const 409)) - (func (export "𐅁") (result i32) (i32.const 410)) - (func (export "𐅵") (result i32) (i32.const 411)) - (func (export "𐅶") (result i32) (i32.const 412)) - (func (export "𐦽") (result i32) (i32.const 413)) - (func (export "𐹻") (result i32) (i32.const 414)) - - ;; Test a full-width quote. - (func (export """) (result i32) (i32.const 415)) - - ;; Test that different present and historical representations of the "delete" - ;; concept are distinct. - (func (export "\7f") (result i32) (i32.const 416)) - (func (export "\08") (result i32) (i32.const 417)) - (func (export "⌫") (result i32) (i32.const 418)) - (func (export "⌦") (result i32) (i32.const 419)) - (func (export "␈") (result i32) (i32.const 420)) - (func (export "␡") (result i32) (i32.const 421)) - (func (export "᷻") (result i32) (i32.const 422)) - (func (export "\0f") (result i32) (i32.const 423)) - (func (export "←") (result i32) (i32.const 424)) - (func (export "⌧") (result i32) (i32.const 425)) - (func (export "⍒") (result i32) (i32.const 426)) - (func (export "⍔") (result i32) (i32.const 427)) - (func (export "⍢") (result i32) (i32.const 428)) - (func (export "⍫") (result i32) (i32.const 429)) - - ;; Test that different representations of the "substitute" concept are - ;; distinct. (U+FFFD is covered above.) - (func (export "\1a") (result i32) (i32.const 430)) - (func (export "␦") (result i32) (i32.const 431)) - (func (export "␚") (result i32) (i32.const 432)) - (func (export "") (result i32) (i32.const 433)) - (func (export "?") (result i32) (i32.const 434)) - (func (export "¿") (result i32) (i32.const 435)) - (func (export "᥅") (result i32) (i32.const 436)) - (func (export ";") (result i32) (i32.const 437)) - (func (export "՞") (result i32) (i32.const 438)) - (func (export "؟") (result i32) (i32.const 439)) - (func (export "፧") (result i32) (i32.const 440)) - (func (export "⁇") (result i32) (i32.const 441)) - (func (export "⍰") (result i32) (i32.const 442)) - (func (export "❓") (result i32) (i32.const 443)) - (func (export "❔") (result i32) (i32.const 444)) - (func (export "⳺") (result i32) (i32.const 445)) - (func (export "⳻") (result i32) (i32.const 446)) - (func (export "⸮") (result i32) (i32.const 447)) - (func (export "㉄") (result i32) (i32.const 448)) - (func (export "꘏") (result i32) (i32.const 449)) - (func (export "꛷") (result i32) (i32.const 450)) - (func (export "︖") (result i32) (i32.const 451)) - (func (export "﹖") (result i32) (i32.const 452)) - (func (export "?") (result i32) (i32.const 453)) - (func (export "𑅃") (result i32) (i32.const 454)) - (func (export "𞥟") (result i32) (i32.const 455)) - (func (export "󠀿") (result i32) (i32.const 456)) - (func (export "𖡄") (result i32) (i32.const 457)) - (func (export "⯑") (result i32) (i32.const 458)) - - ;; Test that different present and historical representations of the - ;; "paragraph" concept are distinct. (U+2029 is covered above). - (func (export "¶") (result i32) (i32.const 459)) - (func (export "⁋") (result i32) (i32.const 460)) - (func (export "܀") (result i32) (i32.const 461)) - (func (export "჻") (result i32) (i32.const 462)) - (func (export "፨") (result i32) (i32.const 463)) - (func (export "〷") (result i32) (i32.const 464)) - (func (export "❡") (result i32) (i32.const 465)) - (func (export "⸏") (result i32) (i32.const 466)) - (func (export "⸐") (result i32) (i32.const 467)) - (func (export "⸑") (result i32) (i32.const 468)) - (func (export "⸎") (result i32) (i32.const 469)) - (func (export "\14") (result i32) (i32.const 470)) ;; ¶ in CP437 - (func (export "☙") (result i32) (i32.const 471)) - (func (export "⸿") (result i32) (i32.const 472)) - (func (export "〇") (result i32) (i32.const 473)) - (func (export "๛") (result i32) (i32.const 474)) - - ;; Test an unusual character. - (func (export "ꙮ") (result i32) (i32.const 475)) - - ;; Test the three characters whose normalization forms under NFC, NFD, NFKC, - ;; and NFKD are all different. - ;; http://unicode.org/faq/normalization.html#6 - (func (export "ϓ") (result i32) (i32.const 476)) - (func (export "ϔ") (result i32) (i32.const 477)) - (func (export "ẛ") (result i32) (i32.const 478)) -) - -(assert_return (invoke "") (i32.const 0)) -(assert_return (invoke "0") (i32.const 1)) -(assert_return (invoke "-0") (i32.const 2)) -(assert_return (invoke "_") (i32.const 3)) -(assert_return (invoke "$") (i32.const 4)) -(assert_return (invoke "@") (i32.const 5)) -(assert_return (invoke "~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./ ") (i32.const 6)) -(assert_return (invoke "NaN") (i32.const 7)) -(assert_return (invoke "Infinity") (i32.const 8)) -(assert_return (invoke "if") (i32.const 9)) -(assert_return (invoke "malloc") (i32.const 10)) -(assert_return (invoke "_malloc") (i32.const 11)) -(assert_return (invoke "__malloc") (i32.const 12)) -(assert_return (invoke "a") (i32.const 13)) -(assert_return (invoke "A") (i32.const 14)) -(assert_return (invoke "") (i32.const 15)) -(assert_return (invoke "Å") (i32.const 16)) -(assert_return (invoke "Å") (i32.const 17)) -(assert_return (invoke "Å") (i32.const 18)) -(assert_return (invoke "ffi") (i32.const 19)) -(assert_return (invoke "ffi") (i32.const 20)) -(assert_return (invoke "ffi") (i32.const 21)) -(assert_return (invoke "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f") (i32.const 22)) -(assert_return (invoke "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f") (i32.const 23)) -(assert_return (invoke " \7f") (i32.const 24)) -(assert_return (invoke "\c2\80\c2\81\c2\82\c2\83\c2\84\c2\85\c2\86\c2\87\c2\88\c2\89\c2\8a\c2\8b\c2\8c\c2\8d\c2\8e\c2\8f") (i32.const 25)) -(assert_return (invoke "\c2\90\c2\91\c2\92\c2\93\c2\94\c2\95\c2\96\c2\97\c2\98\c2\99\c2\9a\c2\9b\c2\9c\c2\9d\c2\9e\c2\9f") (i32.const 26)) -(assert_return (invoke "\ef\bf\b0\ef\bf\b1\ef\bf\b2\ef\bf\b3\ef\bf\b4\ef\bf\b5\ef\bf\b6\ef\bf\b7") (i32.const 27)) -(assert_return (invoke "\ef\bf\b8\ef\bf\b9\ef\bf\ba\ef\bf\bb\ef\bf\bc\ef\bf\bd\ef\bf\be\ef\bf\bf") (i32.const 28)) -(assert_return (invoke "␀␁␂␃␄␅␆␇␈␉␊␋␌␍␎␏") (i32.const 29)) -(assert_return (invoke "␐␑␒␓␔␕␖␗␘␙␚␛␜␝␞␟") (i32.const 30)) -(assert_return (invoke "␠␡") (i32.const 31)) -(assert_return (invoke "￰￱￲￳￴￵￶￷￸�") (i32.const 32)) -(assert_return (invoke "‍") (i32.const 33)) -(assert_return (invoke "‌") (i32.const 34)) -(assert_return (invoke "͏") (i32.const 35)) -(assert_return (invoke "⁠") (i32.const 36)) -(assert_return (invoke "⵿") (i32.const 37)) -(assert_return (invoke "𑁿") (i32.const 38)) -(assert_return (invoke "᠎") (i32.const 39)) -(assert_return (invoke "￯​ ­⁠ ‮‭") (i32.const 40)) -(assert_return (invoke "‎‏‑

‪‫‬ ⁦⁧⁨⁩") (i32.const 41)) -(assert_return (invoke "") (i32.const 42)) -(assert_return (invoke "⁡⁢⁣⁤") (i32.const 43)) -(assert_return (invoke "𐀀󟿿􏿿") (i32.const 44)) -(assert_return (invoke "Z̴͇̫̥̪͓͈͔͎̗̞̺̯̱̞̙̱̜̖̠̏͆̆͛͌͘͞ḁ̶̰̳̭͙̲̱̹̝͎̼͗ͨ̎̄̆͗̿̀́͟͡l̶̷͉̩̹̫̝͖̙̲̼͇͚͍̮͎̥̞̈́͊͗ͦ̈́ͫ̇́̚ͅͅg̶͕͔͚̩̓̐̅ͮ̔̐̎̂̏̾͊̍͋͊ͧ́̆ͦ͞o̡͋̔͐ͪͩ͏̢̧̫̙̤̮͖͙͓̺̜̩̼̘̠́") (i32.const 45)) -(assert_return (invoke "ᅟᅠㅤᅠ") (i32.const 46)) -(assert_return (invoke "︀") (i32.const 47)) -(assert_return (invoke "︄") (i32.const 48)) -(assert_return (invoke "󠄀") (i32.const 49)) -(assert_return (invoke "󠇯") (i32.const 50)) -(assert_return (invoke "̈") (i32.const 51)) -(assert_return (invoke "\0a") (i32.const 52)) -(assert_return (invoke "␤") (i32.const 53)) -(assert_return (invoke "
") (i32.const 54)) -(assert_return (invoke "\0d") (i32.const 55)) -(assert_return (invoke "\0d\0a") (i32.const 56)) -(assert_return (invoke "\0a\0d") (i32.const 57)) -(assert_return (invoke "\1e") (i32.const 58)) -(assert_return (invoke "\0b") (i32.const 59)) -(assert_return (invoke "\0c") (i32.const 60)) -(assert_return (invoke "\c2\85") (i32.const 61)) -(assert_return (invoke "
") (i32.const 62)) -(assert_return (invoke "…") (i32.const 63)) -(assert_return (invoke "⏎") (i32.const 64)) -(assert_return (invoke "\c2\8b") (i32.const 65)) -(assert_return (invoke "\c2\8c") (i32.const 66)) -(assert_return (invoke "\c2\8d") (i32.const 67)) -(assert_return (invoke "↵") (i32.const 68)) -(assert_return (invoke "↩") (i32.const 69)) -(assert_return (invoke "⌤") (i32.const 70)) -(assert_return (invoke "⤶") (i32.const 71)) -(assert_return (invoke "↲") (i32.const 72)) -(assert_return (invoke "⮨") (i32.const 73)) -(assert_return (invoke "⮰") (i32.const 74)) -(assert_return (invoke "�") (i32.const 75)) -(assert_return (invoke "\ef\b7\90") (i32.const 76)) -(assert_return (invoke "\ef\b7\91") (i32.const 77)) -(assert_return (invoke "\ef\b7\92") (i32.const 78)) -(assert_return (invoke "\ef\b7\93") (i32.const 79)) -(assert_return (invoke "\ef\b7\94") (i32.const 80)) -(assert_return (invoke "\ef\b7\95") (i32.const 81)) -(assert_return (invoke "\ef\b7\96") (i32.const 82)) -(assert_return (invoke "\ef\b7\97") (i32.const 83)) -(assert_return (invoke "\ef\b7\98") (i32.const 84)) -(assert_return (invoke "\ef\b7\99") (i32.const 85)) -(assert_return (invoke "\ef\b7\9a") (i32.const 86)) -(assert_return (invoke "\ef\b7\9b") (i32.const 87)) -(assert_return (invoke "\ef\b7\9c") (i32.const 88)) -(assert_return (invoke "\ef\b7\9d") (i32.const 89)) -(assert_return (invoke "\ef\b7\9e") (i32.const 90)) -(assert_return (invoke "\ef\b7\9f") (i32.const 91)) -(assert_return (invoke "\ef\b7\a0") (i32.const 92)) -(assert_return (invoke "\ef\b7\a1") (i32.const 93)) -(assert_return (invoke "\ef\b7\a2") (i32.const 94)) -(assert_return (invoke "\ef\b7\a3") (i32.const 95)) -(assert_return (invoke "\ef\b7\a4") (i32.const 96)) -(assert_return (invoke "\ef\b7\a5") (i32.const 97)) -(assert_return (invoke "\ef\b7\a6") (i32.const 98)) -(assert_return (invoke "\ef\b7\a7") (i32.const 99)) -(assert_return (invoke "\ef\b7\a8") (i32.const 100)) -(assert_return (invoke "\ef\b7\a9") (i32.const 101)) -(assert_return (invoke "\ef\b7\aa") (i32.const 102)) -(assert_return (invoke "\ef\b7\ab") (i32.const 103)) -(assert_return (invoke "\ef\b7\ac") (i32.const 104)) -(assert_return (invoke "\ef\b7\ad") (i32.const 105)) -(assert_return (invoke "\ef\b7\ae") (i32.const 106)) -(assert_return (invoke "\ef\b7\af") (i32.const 107)) -(assert_return (invoke "\ef\bf\be") (i32.const 108)) -(assert_return (invoke "\ef\bf\bf") (i32.const 109)) -(assert_return (invoke "\f0\9f\bf\be") (i32.const 110)) -(assert_return (invoke "\f0\9f\bf\bf") (i32.const 111)) -(assert_return (invoke "\f0\af\bf\be") (i32.const 112)) -(assert_return (invoke "\f0\af\bf\bf") (i32.const 113)) -(assert_return (invoke "\f0\bf\bf\be") (i32.const 114)) -(assert_return (invoke "\f0\bf\bf\bf") (i32.const 115)) -(assert_return (invoke "\f1\8f\bf\be") (i32.const 116)) -(assert_return (invoke "\f1\8f\bf\bf") (i32.const 117)) -(assert_return (invoke "\f1\9f\bf\be") (i32.const 118)) -(assert_return (invoke "\f1\9f\bf\bf") (i32.const 119)) -(assert_return (invoke "\f1\af\bf\be") (i32.const 120)) -(assert_return (invoke "\f1\af\bf\bf") (i32.const 121)) -(assert_return (invoke "\f1\bf\bf\be") (i32.const 122)) -(assert_return (invoke "\f1\bf\bf\bf") (i32.const 123)) -(assert_return (invoke "\f2\8f\bf\be") (i32.const 124)) -(assert_return (invoke "\f2\8f\bf\bf") (i32.const 125)) -(assert_return (invoke "\f2\9f\bf\be") (i32.const 126)) -(assert_return (invoke "\f2\9f\bf\bf") (i32.const 127)) -(assert_return (invoke "\f2\af\bf\be") (i32.const 128)) -(assert_return (invoke "\f2\af\bf\bf") (i32.const 129)) -(assert_return (invoke "\f2\bf\bf\be") (i32.const 130)) -(assert_return (invoke "\f2\bf\bf\bf") (i32.const 131)) -(assert_return (invoke "\f3\8f\bf\be") (i32.const 132)) -(assert_return (invoke "\f3\8f\bf\bf") (i32.const 133)) -(assert_return (invoke "\f3\9f\bf\be") (i32.const 134)) -(assert_return (invoke "\f3\9f\bf\bf") (i32.const 135)) -(assert_return (invoke "\f3\af\bf\be") (i32.const 136)) -(assert_return (invoke "\f3\af\bf\bf") (i32.const 137)) -(assert_return (invoke "\f3\bf\bf\be") (i32.const 138)) -(assert_return (invoke "\f3\bf\bf\bf") (i32.const 139)) -(assert_return (invoke "\f4\8f\bf\be") (i32.const 140)) -(assert_return (invoke "\f4\8f\bf\bf") (i32.const 141)) -(assert_return (invoke "̈‽̈̉") (i32.const 142)) -(assert_return (invoke "abc") (i32.const 143)) -(assert_return (invoke "‭abc") (i32.const 144)) -(assert_return (invoke "‮cba") (i32.const 145)) -(assert_return (invoke "‭abc‮") (i32.const 146)) -(assert_return (invoke "‮cba‭") (i32.const 147)) -(assert_return (invoke "𝑨") (i32.const 148)) -(assert_return (invoke "𝐴") (i32.const 149)) -(assert_return (invoke "𝘈") (i32.const 150)) -(assert_return (invoke "𝘼") (i32.const 151)) -(assert_return (invoke "𝐀") (i32.const 152)) -(assert_return (invoke "𝓐") (i32.const 153)) -(assert_return (invoke "𝕬") (i32.const 154)) -(assert_return (invoke "𝗔") (i32.const 155)) -(assert_return (invoke "𝒜") (i32.const 156)) -(assert_return (invoke "𝔄") (i32.const 157)) -(assert_return (invoke "𝔸") (i32.const 158)) -(assert_return (invoke "𝖠") (i32.const 159)) -(assert_return (invoke "𝙰") (i32.const 160)) -(assert_return (invoke "ᴀ") (i32.const 161)) -(assert_return (invoke "ᴬ") (i32.const 162)) -(assert_return (invoke "Ⓐ") (i32.const 163)) -(assert_return (invoke "A") (i32.const 164)) -(assert_return (invoke "🄐") (i32.const 165)) -(assert_return (invoke "🄰") (i32.const 166)) -(assert_return (invoke "󠁁") (i32.const 167)) -(assert_return (invoke "U+0041") (i32.const 168)) -(assert_return (invoke "A​") (i32.const 169)) -(assert_return (invoke "А") (i32.const 170)) -(assert_return (invoke "Ꙗ") (i32.const 171)) -(assert_return (invoke "ⷼ") (i32.const 172)) -(assert_return (invoke "ⷶ") (i32.const 173)) -(assert_return (invoke "Ɐ") (i32.const 174)) -(assert_return (invoke "🅐") (i32.const 175)) -(assert_return (invoke "🅰") (i32.const 176)) -(assert_return (invoke "Ⱝ") (i32.const 177)) -(assert_return (invoke "𐐂") (i32.const 178)) -(assert_return (invoke "𐐈") (i32.const 179)) -(assert_return (invoke "𐒰") (i32.const 180)) -(assert_return (invoke "À") (i32.const 181)) -(assert_return (invoke "Á") (i32.const 182)) -(assert_return (invoke "Â") (i32.const 183)) -(assert_return (invoke "Ã") (i32.const 184)) -(assert_return (invoke "Ä") (i32.const 185)) -(assert_return (invoke "Ā") (i32.const 186)) -(assert_return (invoke "Ă") (i32.const 187)) -(assert_return (invoke "Ą") (i32.const 188)) -(assert_return (invoke "Ǎ") (i32.const 189)) -(assert_return (invoke "Ǟ") (i32.const 190)) -(assert_return (invoke "Ǡ") (i32.const 191)) -(assert_return (invoke "Ǻ") (i32.const 192)) -(assert_return (invoke "Ȁ") (i32.const 193)) -(assert_return (invoke "Ȃ") (i32.const 194)) -(assert_return (invoke "Ȧ") (i32.const 195)) -(assert_return (invoke "Ⱥ") (i32.const 196)) -(assert_return (invoke "Ӑ") (i32.const 197)) -(assert_return (invoke "Ӓ") (i32.const 198)) -(assert_return (invoke "ߊ") (i32.const 199)) -(assert_return (invoke "ࠡ") (i32.const 200)) -(assert_return (invoke "ࠢ") (i32.const 201)) -(assert_return (invoke "ࠣ") (i32.const 202)) -(assert_return (invoke "ࠤ") (i32.const 203)) -(assert_return (invoke "ࠥ") (i32.const 204)) -(assert_return (invoke "ऄ") (i32.const 205)) -(assert_return (invoke "अ") (i32.const 206)) -(assert_return (invoke "ॲ") (i32.const 207)) -(assert_return (invoke "অ") (i32.const 208)) -(assert_return (invoke "ਅ") (i32.const 209)) -(assert_return (invoke "અ") (i32.const 210)) -(assert_return (invoke "ଅ") (i32.const 211)) -(assert_return (invoke "அ") (i32.const 212)) -(assert_return (invoke "అ") (i32.const 213)) -(assert_return (invoke "ಅ") (i32.const 214)) -(assert_return (invoke "അ") (i32.const 215)) -(assert_return (invoke "ะ") (i32.const 216)) -(assert_return (invoke "ະ") (i32.const 217)) -(assert_return (invoke "༁") (i32.const 218)) -(assert_return (invoke "ཨ") (i32.const 219)) -(assert_return (invoke "ྸ") (i32.const 220)) -(assert_return (invoke "အ") (i32.const 221)) -(assert_return (invoke "ဢ") (i32.const 222)) -(assert_return (invoke "ႜ") (i32.const 223)) -(assert_return (invoke "ᅡ") (i32.const 224)) -(assert_return (invoke "አ") (i32.const 225)) -(assert_return (invoke "ዐ") (i32.const 226)) -(assert_return (invoke "Ꭰ") (i32.const 227)) -(assert_return (invoke "ᐊ") (i32.const 228)) -(assert_return (invoke "ᖳ") (i32.const 229)) -(assert_return (invoke "ᚨ") (i32.const 230)) -(assert_return (invoke "ᚪ") (i32.const 231)) -(assert_return (invoke "ᛆ") (i32.const 232)) -(assert_return (invoke "ᜀ") (i32.const 233)) -(assert_return (invoke "ᜠ") (i32.const 234)) -(assert_return (invoke "ᝀ") (i32.const 235)) -(assert_return (invoke "ᝠ") (i32.const 236)) -(assert_return (invoke "ᠠ") (i32.const 237)) -(assert_return (invoke "ᢇ") (i32.const 238)) -(assert_return (invoke "ᤠ") (i32.const 239)) -(assert_return (invoke "ᥣ") (i32.const 240)) -(assert_return (invoke "ᨕ") (i32.const 241)) -(assert_return (invoke "ᩋ") (i32.const 242)) -(assert_return (invoke "ᩡ") (i32.const 243)) -(assert_return (invoke "ᮃ") (i32.const 244)) -(assert_return (invoke "ᯀ") (i32.const 245)) -(assert_return (invoke "ᯁ") (i32.const 246)) -(assert_return (invoke "ᰣ") (i32.const 247)) -(assert_return (invoke "Ḁ") (i32.const 248)) -(assert_return (invoke "Ạ") (i32.const 249)) -(assert_return (invoke "Ả") (i32.const 250)) -(assert_return (invoke "Ấ") (i32.const 251)) -(assert_return (invoke "Ầ") (i32.const 252)) -(assert_return (invoke "Ẩ") (i32.const 253)) -(assert_return (invoke "Ẫ") (i32.const 254)) -(assert_return (invoke "Ậ") (i32.const 255)) -(assert_return (invoke "Ắ") (i32.const 256)) -(assert_return (invoke "Ằ") (i32.const 257)) -(assert_return (invoke "Ẳ") (i32.const 258)) -(assert_return (invoke "Ẵ") (i32.const 259)) -(assert_return (invoke "Ặ") (i32.const 260)) -(assert_return (invoke "あ") (i32.const 261)) -(assert_return (invoke "ア") (i32.const 262)) -(assert_return (invoke "ㄚ") (i32.const 263)) -(assert_return (invoke "ㅏ") (i32.const 264)) -(assert_return (invoke "㈎") (i32.const 265)) -(assert_return (invoke "㈏") (i32.const 266)) -(assert_return (invoke "㈐") (i32.const 267)) -(assert_return (invoke "㈑") (i32.const 268)) -(assert_return (invoke "㈒") (i32.const 269)) -(assert_return (invoke "㈓") (i32.const 270)) -(assert_return (invoke "㈔") (i32.const 271)) -(assert_return (invoke "㈕") (i32.const 272)) -(assert_return (invoke "㈖") (i32.const 273)) -(assert_return (invoke "㈗") (i32.const 274)) -(assert_return (invoke "㈘") (i32.const 275)) -(assert_return (invoke "㈙") (i32.const 276)) -(assert_return (invoke "㈚") (i32.const 277)) -(assert_return (invoke "㈛") (i32.const 278)) -(assert_return (invoke "㉮") (i32.const 279)) -(assert_return (invoke "㉯") (i32.const 280)) -(assert_return (invoke "㉰") (i32.const 281)) -(assert_return (invoke "㉱") (i32.const 282)) -(assert_return (invoke "㉲") (i32.const 283)) -(assert_return (invoke "㉳") (i32.const 284)) -(assert_return (invoke "㉴") (i32.const 285)) -(assert_return (invoke "㉵") (i32.const 286)) -(assert_return (invoke "㉶") (i32.const 287)) -(assert_return (invoke "㉷") (i32.const 288)) -(assert_return (invoke "㉸") (i32.const 289)) -(assert_return (invoke "㉹") (i32.const 290)) -(assert_return (invoke "㉺") (i32.const 291)) -(assert_return (invoke "㉻") (i32.const 292)) -(assert_return (invoke "㋐") (i32.const 293)) -(assert_return (invoke "ꀊ") (i32.const 294)) -(assert_return (invoke "ꓮ") (i32.const 295)) -(assert_return (invoke "ꕉ") (i32.const 296)) -(assert_return (invoke "ꚠ") (i32.const 297)) -(assert_return (invoke "ꠀ") (i32.const 298)) -(assert_return (invoke "ꠣ") (i32.const 299)) -(assert_return (invoke "ꡝ") (i32.const 300)) -(assert_return (invoke "ꢂ") (i32.const 301)) -(assert_return (invoke "꣪") (i32.const 302)) -(assert_return (invoke "ꤢ") (i32.const 303)) -(assert_return (invoke "ꥆ") (i32.const 304)) -(assert_return (invoke "ꦄ") (i32.const 305)) -(assert_return (invoke "ꨀ") (i32.const 306)) -(assert_return (invoke "ア") (i32.const 307)) -(assert_return (invoke "ᅡ") (i32.const 308)) -(assert_return (invoke "𐀀") (i32.const 309)) -(assert_return (invoke "𐊀") (i32.const 310)) -(assert_return (invoke "𐊠") (i32.const 311)) -(assert_return (invoke "𐌀") (i32.const 312)) -(assert_return (invoke "𐎠") (i32.const 313)) -(assert_return (invoke "𐒖") (i32.const 314)) -(assert_return (invoke "𐔀") (i32.const 315)) -(assert_return (invoke "𐝀") (i32.const 316)) -(assert_return (invoke "𐠀") (i32.const 317)) -(assert_return (invoke "𐤠") (i32.const 318)) -(assert_return (invoke "𐦀") (i32.const 319)) -(assert_return (invoke "𐦠") (i32.const 320)) -(assert_return (invoke "𐨀") (i32.const 321)) -(assert_return (invoke "𐬀") (i32.const 322)) -(assert_return (invoke "𐰀") (i32.const 323)) -(assert_return (invoke "𐰁") (i32.const 324)) -(assert_return (invoke "𐲀") (i32.const 325)) -(assert_return (invoke "𑀅") (i32.const 326)) -(assert_return (invoke "𑂃") (i32.const 327)) -(assert_return (invoke "𑄧") (i32.const 328)) -(assert_return (invoke "𑅐") (i32.const 329)) -(assert_return (invoke "𑆃") (i32.const 330)) -(assert_return (invoke "𑈀") (i32.const 331)) -(assert_return (invoke "𑊀") (i32.const 332)) -(assert_return (invoke "𑊰") (i32.const 333)) -(assert_return (invoke "𑌅") (i32.const 334)) -(assert_return (invoke "𑍰") (i32.const 335)) -(assert_return (invoke "𑐀") (i32.const 336)) -(assert_return (invoke "𑒁") (i32.const 337)) -(assert_return (invoke "𑖀") (i32.const 338)) -(assert_return (invoke "𑘀") (i32.const 339)) -(assert_return (invoke "𑚀") (i32.const 340)) -(assert_return (invoke "𑜒") (i32.const 341)) -(assert_return (invoke "𑜠") (i32.const 342)) -(assert_return (invoke "𑢡") (i32.const 343)) -(assert_return (invoke "𑫕") (i32.const 344)) -(assert_return (invoke "𑰀") (i32.const 345)) -(assert_return (invoke "𑲏") (i32.const 346)) -(assert_return (invoke "𑲯") (i32.const 347)) -(assert_return (invoke "𒀀") (i32.const 348)) -(assert_return (invoke "𖧕") (i32.const 349)) -(assert_return (invoke "𖩆") (i32.const 350)) -(assert_return (invoke "𖫧") (i32.const 351)) -(assert_return (invoke "𖽔") (i32.const 352)) -(assert_return (invoke "𛱁") (i32.const 353)) -(assert_return (invoke "𛱤") (i32.const 354)) -(assert_return (invoke "𞠣") (i32.const 355)) -(assert_return (invoke "🇦") (i32.const 356)) -(assert_return (invoke "Ɑ") (i32.const 357)) -(assert_return (invoke "Λ") (i32.const 358)) -(assert_return (invoke "Ɒ") (i32.const 359)) -(assert_return (invoke "ª") (i32.const 360)) -(assert_return (invoke "∀") (i32.const 361)) -(assert_return (invoke "₳") (i32.const 362)) -(assert_return (invoke "𐤀") (i32.const 363)) -(assert_return (invoke "Ⲁ") (i32.const 364)) -(assert_return (invoke "𐌰") (i32.const 365)) -(assert_return (invoke "Ά") (i32.const 366)) -(assert_return (invoke "Α") (i32.const 367)) -(assert_return (invoke "Ἀ") (i32.const 368)) -(assert_return (invoke "Ἁ") (i32.const 369)) -(assert_return (invoke "Ἂ") (i32.const 370)) -(assert_return (invoke "Ἃ") (i32.const 371)) -(assert_return (invoke "Ἄ") (i32.const 372)) -(assert_return (invoke "Ἅ") (i32.const 373)) -(assert_return (invoke "Ἆ") (i32.const 374)) -(assert_return (invoke "Ἇ") (i32.const 375)) -(assert_return (invoke "ᾈ") (i32.const 376)) -(assert_return (invoke "ᾉ") (i32.const 377)) -(assert_return (invoke "ᾊ") (i32.const 378)) -(assert_return (invoke "ᾋ") (i32.const 379)) -(assert_return (invoke "ᾌ") (i32.const 380)) -(assert_return (invoke "ᾍ") (i32.const 381)) -(assert_return (invoke "ᾎ") (i32.const 382)) -(assert_return (invoke "ᾏ") (i32.const 383)) -(assert_return (invoke "Ᾰ") (i32.const 384)) -(assert_return (invoke "Ᾱ") (i32.const 385)) -(assert_return (invoke "Ὰ") (i32.const 386)) -(assert_return (invoke "Ά") (i32.const 387)) -(assert_return (invoke "ᾼ") (i32.const 388)) -(assert_return (invoke "𝚨") (i32.const 389)) -(assert_return (invoke "𝛢") (i32.const 390)) -(assert_return (invoke "𝜜") (i32.const 391)) -(assert_return (invoke "𝝖") (i32.const 392)) -(assert_return (invoke "𝞐") (i32.const 393)) -(assert_return (invoke "⍶") (i32.const 394)) -(assert_return (invoke "⍺") (i32.const 395)) -(assert_return (invoke "⩜") (i32.const 396)) -(assert_return (invoke "ᗅ") (i32.const 397)) -(assert_return (invoke "Ꭺ") (i32.const 398)) -(assert_return (invoke ")˺˼𔗏𝅴𝅶𝅸𝅺⁾₎❩❫⟯﴿︶﹚)⦆󠀩❳❵⟧⟩⟫⟭⦈⦊⦖⸣⸥︘︸︺︼︾﹀﹂﹄﹈﹜﹞]}」󠁝󠁽»’”›❯") (i32.const 399)) -(assert_return (invoke "(˹˻𔗎𝅳𝅵𝅷𝅹⁽₍❨❪⟮﴾︵﹙(⦅󠀨❲❴⟦⟨⟪⟬⦇⦉⦕⸢⸤︗︷︹︻︽︿﹁﹃﹇﹛﹝[{「󠁛󠁻«‘“‹❮") (i32.const 400)) -(assert_return (invoke "𝪋𝪤") (i32.const 401)) -(assert_return (invoke "𝪋") (i32.const 402)) -(assert_return (invoke "½") (i32.const 403)) -(assert_return (invoke "1⁄2") (i32.const 404)) -(assert_return (invoke "1/2") (i32.const 405)) -(assert_return (invoke "୳") (i32.const 406)) -(assert_return (invoke "൴") (i32.const 407)) -(assert_return (invoke "⳽") (i32.const 408)) -(assert_return (invoke "꠱") (i32.const 409)) -(assert_return (invoke "𐅁") (i32.const 410)) -(assert_return (invoke "𐅵") (i32.const 411)) -(assert_return (invoke "𐅶") (i32.const 412)) -(assert_return (invoke "𐦽") (i32.const 413)) -(assert_return (invoke "𐹻") (i32.const 414)) -(assert_return (invoke """) (i32.const 415)) -(assert_return (invoke "\7f") (i32.const 416)) -(assert_return (invoke "\08") (i32.const 417)) -(assert_return (invoke "⌫") (i32.const 418)) -(assert_return (invoke "⌦") (i32.const 419)) -(assert_return (invoke "␈") (i32.const 420)) -(assert_return (invoke "␡") (i32.const 421)) -(assert_return (invoke "᷻") (i32.const 422)) -(assert_return (invoke "\0f") (i32.const 423)) -(assert_return (invoke "←") (i32.const 424)) -(assert_return (invoke "⌧") (i32.const 425)) -(assert_return (invoke "⍒") (i32.const 426)) -(assert_return (invoke "⍔") (i32.const 427)) -(assert_return (invoke "⍢") (i32.const 428)) -(assert_return (invoke "⍫") (i32.const 429)) -(assert_return (invoke "\1a") (i32.const 430)) -(assert_return (invoke "␦") (i32.const 431)) -(assert_return (invoke "␚") (i32.const 432)) -(assert_return (invoke "") (i32.const 433)) -(assert_return (invoke "?") (i32.const 434)) -(assert_return (invoke "¿") (i32.const 435)) -(assert_return (invoke "᥅") (i32.const 436)) -(assert_return (invoke ";") (i32.const 437)) -(assert_return (invoke "՞") (i32.const 438)) -(assert_return (invoke "؟") (i32.const 439)) -(assert_return (invoke "፧") (i32.const 440)) -(assert_return (invoke "⁇") (i32.const 441)) -(assert_return (invoke "⍰") (i32.const 442)) -(assert_return (invoke "❓") (i32.const 443)) -(assert_return (invoke "❔") (i32.const 444)) -(assert_return (invoke "⳺") (i32.const 445)) -(assert_return (invoke "⳻") (i32.const 446)) -(assert_return (invoke "⸮") (i32.const 447)) -(assert_return (invoke "㉄") (i32.const 448)) -(assert_return (invoke "꘏") (i32.const 449)) -(assert_return (invoke "꛷") (i32.const 450)) -(assert_return (invoke "︖") (i32.const 451)) -(assert_return (invoke "﹖") (i32.const 452)) -(assert_return (invoke "?") (i32.const 453)) -(assert_return (invoke "𑅃") (i32.const 454)) -(assert_return (invoke "𞥟") (i32.const 455)) -(assert_return (invoke "󠀿") (i32.const 456)) -(assert_return (invoke "𖡄") (i32.const 457)) -(assert_return (invoke "⯑") (i32.const 458)) -(assert_return (invoke "¶") (i32.const 459)) -(assert_return (invoke "⁋") (i32.const 460)) -(assert_return (invoke "܀") (i32.const 461)) -(assert_return (invoke "჻") (i32.const 462)) -(assert_return (invoke "፨") (i32.const 463)) -(assert_return (invoke "〷") (i32.const 464)) -(assert_return (invoke "❡") (i32.const 465)) -(assert_return (invoke "⸏") (i32.const 466)) -(assert_return (invoke "⸐") (i32.const 467)) -(assert_return (invoke "⸑") (i32.const 468)) -(assert_return (invoke "⸎") (i32.const 469)) -(assert_return (invoke "\14") (i32.const 470)) -(assert_return (invoke "☙") (i32.const 471)) -(assert_return (invoke "⸿") (i32.const 472)) -(assert_return (invoke "〇") (i32.const 473)) -(assert_return (invoke "๛") (i32.const 474)) -(assert_return (invoke "ꙮ") (i32.const 475)) -(assert_return (invoke "ϓ") (i32.const 476)) -(assert_return (invoke "ϔ") (i32.const 477)) -(assert_return (invoke "ẛ") (i32.const 478)) - -(module - ;; Test that we can use indices instead of names to reference imports, - ;; exports, functions and parameters. - (import "spectest" "print_i32" (func (param i32))) - (func (import "spectest" "print_i32") (param i32)) - (func (param i32) (param i32) - (call 0 (local.get 0)) - (call 1 (local.get 1)) - ) - (export "print32" (func 2)) -) - -(assert_return (invoke "print32" (i32.const 42) (i32.const 123))) diff --git a/test/spec/nop.wast b/test/spec/nop.wast deleted file mode 100644 index e8fe2de4b5f..00000000000 --- a/test/spec/nop.wast +++ /dev/null @@ -1,426 +0,0 @@ -;; Test `nop` operator. - -(module - ;; Auxiliary definitions - (func $dummy) - (func $3-ary (param i32 i32 i32) (result i32) - local.get 0 local.get 1 local.get 2 i32.sub i32.add - ) - (memory 1) - - (func (export "as-func-first") (result i32) - (nop) (i32.const 1) - ) - (func (export "as-func-mid") (result i32) - (call $dummy) (nop) (i32.const 2) - ) - (func (export "as-func-last") (result i32) - (call $dummy) (i32.const 3) (nop) - ) - (func (export "as-func-everywhere") (result i32) - (nop) (nop) (call $dummy) (nop) (i32.const 4) (nop) (nop) - ) - - (func (export "as-drop-first") (param i32) - (nop) (local.get 0) (drop) - ) - (func (export "as-drop-last") (param i32) - (local.get 0) (nop) (drop) - ) - (func (export "as-drop-everywhere") (param i32) - (nop) (nop) (local.get 0) (nop) (nop) (drop) - ) - - (func (export "as-select-first") (param i32) (result i32) - (nop) (local.get 0) (local.get 0) (local.get 0) (select) - ) - (func (export "as-select-mid1") (param i32) (result i32) - (local.get 0) (nop) (local.get 0) (local.get 0) (select) - ) - (func (export "as-select-mid2") (param i32) (result i32) - (local.get 0) (local.get 0) (nop) (local.get 0) (select) - ) - (func (export "as-select-last") (param i32) (result i32) - (local.get 0) (local.get 0) (local.get 0) (nop) (select) - ) - (func (export "as-select-everywhere") (param i32) (result i32) - (nop) (local.get 0) (nop) (nop) (local.get 0) - (nop) (nop) (local.get 0) (nop) (nop) (select) - ) - - (func (export "as-block-first") (result i32) - (block (result i32) (nop) (i32.const 2)) - ) - (func (export "as-block-mid") (result i32) - (block (result i32) (call $dummy) (nop) (i32.const 2)) - ) - (func (export "as-block-last") (result i32) - (block (result i32) (nop) (call $dummy) (i32.const 3) (nop)) - ) - (func (export "as-block-everywhere") (result i32) - (block (result i32) - (nop) (nop) (call $dummy) (nop) (i32.const 4) (nop) (nop) - ) - ) - - (func (export "as-loop-first") (result i32) - (loop (result i32) (nop) (i32.const 2)) - ) - (func (export "as-loop-mid") (result i32) - (loop (result i32) (call $dummy) (nop) (i32.const 2)) - ) - (func (export "as-loop-last") (result i32) - (loop (result i32) (call $dummy) (i32.const 3) (nop)) - ) - (func (export "as-loop-everywhere") (result i32) - (loop (result i32) - (nop) (nop) (call $dummy) (nop) (i32.const 4) (nop) (nop) - ) - ) - - (func (export "as-if-condition") (param i32) - (local.get 0) (nop) (if (then (call $dummy))) - ) - (func (export "as-if-then") (param i32) - (if (local.get 0) (then (nop)) (else (call $dummy))) - ) - (func (export "as-if-else") (param i32) - (if (local.get 0) (then (call $dummy)) (else (nop))) - ) - - (func (export "as-br-first") (param i32) (result i32) - (block (result i32) (nop) (local.get 0) (br 0)) - ) - (func (export "as-br-last") (param i32) (result i32) - (block (result i32) (local.get 0) (nop) (br 0)) - ) - (func (export "as-br-everywhere") (param i32) (result i32) - (block (result i32) (nop) (nop) (local.get 0) (nop) (nop) (br 0)) - ) - - (func (export "as-br_if-first") (param i32) (result i32) - (block (result i32) (nop) (local.get 0) (local.get 0) (br_if 0)) - ) - (func (export "as-br_if-mid") (param i32) (result i32) - (block (result i32) (local.get 0) (nop) (local.get 0) (br_if 0)) - ) - (func (export "as-br_if-last") (param i32) (result i32) - (block (result i32) (local.get 0) (local.get 0) (nop) (br_if 0)) - ) - (func (export "as-br_if-everywhere") (param i32) (result i32) - (block (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (local.get 0) (nop) (nop) - (br_if 0) - ) - ) - - (func (export "as-br_table-first") (param i32) (result i32) - (block (result i32) (nop) (local.get 0) (local.get 0) (br_table 0 0)) - ) - (func (export "as-br_table-mid") (param i32) (result i32) - (block (result i32) (local.get 0) (nop) (local.get 0) (br_table 0 0)) - ) - (func (export "as-br_table-last") (param i32) (result i32) - (block (result i32) (local.get 0) (local.get 0) (nop) (br_table 0 0)) - ) - (func (export "as-br_table-everywhere") (param i32) (result i32) - (block (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (local.get 0) (nop) (nop) - (br_table 0 0) - ) - ) - - (func (export "as-return-first") (param i32) (result i32) - (nop) (local.get 0) (return) - ) - (func (export "as-return-last") (param i32) (result i32) - (local.get 0) (nop) (return) - ) - (func (export "as-return-everywhere") (param i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (return) - ) - - (func (export "as-call-first") (param i32 i32 i32) (result i32) - (nop) (local.get 0) (local.get 1) (local.get 2) (call $3-ary) - ) - (func (export "as-call-mid1") (param i32 i32 i32) (result i32) - (local.get 0) (nop) (local.get 1) (local.get 2) (call $3-ary) - ) - (func (export "as-call-mid2") (param i32 i32 i32) (result i32) - (local.get 0) (local.get 1) (nop) (local.get 2) (call $3-ary) - ) - (func (export "as-call-last") (param i32 i32 i32) (result i32) - (local.get 0) (local.get 1) (local.get 2) (nop) (call $3-ary) - ) - (func (export "as-call-everywhere") (param i32 i32 i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (local.get 1) - (nop) (nop) (local.get 2) (nop) (nop) (call $3-ary) - ) - - (func (export "as-unary-first") (param i32) (result i32) - (nop) (local.get 0) (i32.ctz) - ) - (func (export "as-unary-last") (param i32) (result i32) - (local.get 0) (nop) (i32.ctz) - ) - (func (export "as-unary-everywhere") (param i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (i32.ctz) - ) - - (func (export "as-binary-first") (param i32) (result i32) - (nop) (local.get 0) (local.get 0) (i32.add) - ) - (func (export "as-binary-mid") (param i32) (result i32) - (local.get 0) (nop) (local.get 0) (i32.add) - ) - (func (export "as-binary-last") (param i32) (result i32) - (local.get 0) (local.get 0) (nop) (i32.add) - ) - (func (export "as-binary-everywhere") (param i32) (result i32) - (nop) (local.get 0) (nop) (nop) (local.get 0) (nop) (nop) (i32.add) - ) - - (func (export "as-test-first") (param i32) (result i32) - (nop) (local.get 0) (i32.eqz) - ) - (func (export "as-test-last") (param i32) (result i32) - (local.get 0) (nop) (i32.eqz) - ) - (func (export "as-test-everywhere") (param i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) i32.eqz - ) - - (func (export "as-compare-first") (param i32) (result i32) - (nop) (local.get 0) (local.get 0) (i32.ne) - ) - (func (export "as-compare-mid") (param i32) (result i32) - (local.get 0) (nop) (local.get 0) (i32.ne) - ) - (func (export "as-compare-last") (param i32) (result i32) - (local.get 0) (local.get 0) (nop) (i32.lt_u) - ) - (func (export "as-compare-everywhere") (param i32) (result i32) - (nop) (local.get 0) (nop) (nop) (local.get 0) (nop) (nop) (i32.le_s) - ) - - (func (export "as-memory.grow-first") (param i32) (result i32) - (nop) (local.get 0) (memory.grow) - ) - (func (export "as-memory.grow-last") (param i32) (result i32) - (local.get 0) (nop) (memory.grow) - ) - (func (export "as-memory.grow-everywhere") (param i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (memory.grow) - ) - - (func $func (param i32 i32) (result i32) (local.get 0)) - (type $check (func (param i32 i32) (result i32))) - (table funcref (elem $func)) - (func (export "as-call_indirect-first") (result i32) - (block (result i32) - (nop) (i32.const 1) (i32.const 2) (i32.const 0) - (call_indirect (type $check)) - ) - ) - (func (export "as-call_indirect-mid1") (result i32) - (block (result i32) - (i32.const 1) (nop) (i32.const 2) (i32.const 0) - (call_indirect (type $check)) - ) - ) - (func (export "as-call_indirect-mid2") (result i32) - (block (result i32) - (i32.const 1) (i32.const 2) (nop) (i32.const 0) - (call_indirect (type $check)) - ) - ) - (func (export "as-call_indirect-last") (result i32) - (block (result i32) - (i32.const 1) (i32.const 2) (i32.const 0) (nop) - (call_indirect (type $check)) - ) - ) - (func (export "as-call_indirect-everywhere") (result i32) - (block (result i32) - (nop) (nop) (i32.const 1) (nop) (nop) (i32.const 2) (nop) (nop) (i32.const 0) (nop) (nop) - (call_indirect (type $check)) - ) - ) - - (func (export "as-local.set-first") (param i32) (result i32) - (nop) (i32.const 2) (local.set 0) (local.get 0) - ) - (func (export "as-local.set-last") (param i32) (result i32) - (i32.const 2) (nop) (local.set 0) (local.get 0) - ) - (func (export "as-local.set-everywhere") (param i32) (result i32) - (nop) (nop) (i32.const 2) (nop) (nop) (local.set 0) (local.get 0) - ) - - (func (export "as-local.tee-first") (param i32) (result i32) - (nop) (i32.const 2) (local.tee 0) - ) - (func (export "as-local.tee-last") (param i32) (result i32) - (i32.const 2) (nop) (local.tee 0) - ) - (func (export "as-local.tee-everywhere") (param i32) (result i32) - (nop) (nop) (i32.const 2) (nop) (nop) (local.tee 0) - ) - - (global $a (mut i32) (i32.const 0)) - (func (export "as-global.set-first") (result i32) - (nop) (i32.const 2) (global.set $a) (global.get $a) - ) - (func (export "as-global.set-last") (result i32) - (i32.const 2) (nop) (global.set $a) (global.get $a) - ) - (func (export "as-global.set-everywhere") (result i32) - (nop) (nop) (i32.const 2) (nop) (nop) (global.set 0) - (global.get $a) - ) - - (func (export "as-load-first") (param i32) (result i32) - (nop) (local.get 0) (i32.load) - ) - (func (export "as-load-last") (param i32) (result i32) - (local.get 0) (nop) (i32.load) - ) - (func (export "as-load-everywhere") (param i32) (result i32) - (nop) (nop) (local.get 0) (nop) (nop) (i32.load) - ) - - (func (export "as-store-first") (param i32 i32) - (nop) (local.get 0) (local.get 1) (i32.store) - ) - (func (export "as-store-mid") (param i32 i32) - (local.get 0) (nop) (local.get 1) (i32.store) - ) - (func (export "as-store-last") (param i32 i32) - (local.get 0) (local.get 1) (nop) (i32.store) - ) - (func (export "as-store-everywhere") (param i32 i32) - (nop) (nop) (local.get 0) (nop) (nop) (local.get 1) (nop) (nop) (i32.store) - ) -) - -(assert_return (invoke "as-func-first") (i32.const 1)) -(assert_return (invoke "as-func-mid") (i32.const 2)) -(assert_return (invoke "as-func-last") (i32.const 3)) -(assert_return (invoke "as-func-everywhere") (i32.const 4)) - -(assert_return (invoke "as-drop-first" (i32.const 0))) -(assert_return (invoke "as-drop-last" (i32.const 0))) -(assert_return (invoke "as-drop-everywhere" (i32.const 0))) - -(assert_return (invoke "as-select-first" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "as-select-mid1" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "as-select-mid2" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "as-select-last" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "as-select-everywhere" (i32.const 3)) (i32.const 3)) - -(assert_return (invoke "as-block-first") (i32.const 2)) -(assert_return (invoke "as-block-mid") (i32.const 2)) -(assert_return (invoke "as-block-last") (i32.const 3)) -(assert_return (invoke "as-block-everywhere") (i32.const 4)) - -(assert_return (invoke "as-loop-first") (i32.const 2)) -(assert_return (invoke "as-loop-mid") (i32.const 2)) -(assert_return (invoke "as-loop-last") (i32.const 3)) -(assert_return (invoke "as-loop-everywhere") (i32.const 4)) - -(assert_return (invoke "as-if-condition" (i32.const 0))) -(assert_return (invoke "as-if-condition" (i32.const -1))) -(assert_return (invoke "as-if-then" (i32.const 0))) -(assert_return (invoke "as-if-then" (i32.const 4))) -(assert_return (invoke "as-if-else" (i32.const 0))) -(assert_return (invoke "as-if-else" (i32.const 3))) - -(assert_return (invoke "as-br-first" (i32.const 5)) (i32.const 5)) -(assert_return (invoke "as-br-last" (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-br-everywhere" (i32.const 7)) (i32.const 7)) - -(assert_return (invoke "as-br_if-first" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "as-br_if-mid" (i32.const 5)) (i32.const 5)) -(assert_return (invoke "as-br_if-last" (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-br_if-everywhere" (i32.const 7)) (i32.const 7)) - -(assert_return (invoke "as-br_table-first" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "as-br_table-mid" (i32.const 5)) (i32.const 5)) -(assert_return (invoke "as-br_table-last" (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-br_table-everywhere" (i32.const 7)) (i32.const 7)) - -(assert_return (invoke "as-return-first" (i32.const 5)) (i32.const 5)) -(assert_return (invoke "as-return-last" (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-return-everywhere" (i32.const 7)) (i32.const 7)) - -(assert_return (invoke "as-call-first" (i32.const 3) (i32.const 1) (i32.const 2)) (i32.const 2)) -(assert_return (invoke "as-call-mid1" (i32.const 3) (i32.const 1) (i32.const 2)) (i32.const 2)) -(assert_return (invoke "as-call-mid2" (i32.const 0) (i32.const 3) (i32.const 1)) (i32.const 2)) -(assert_return (invoke "as-call-last" (i32.const 10) (i32.const 9) (i32.const -1)) (i32.const 20)) -(assert_return (invoke "as-call-everywhere" (i32.const 2) (i32.const 1) (i32.const 5)) (i32.const -2)) - -(assert_return (invoke "as-unary-first" (i32.const 30)) (i32.const 1)) -(assert_return (invoke "as-unary-last" (i32.const 30)) (i32.const 1)) -(assert_return (invoke "as-unary-everywhere" (i32.const 12)) (i32.const 2)) - -(assert_return (invoke "as-binary-first" (i32.const 3)) (i32.const 6)) -(assert_return (invoke "as-binary-mid" (i32.const 3)) (i32.const 6)) -(assert_return (invoke "as-binary-last" (i32.const 3)) (i32.const 6)) -(assert_return (invoke "as-binary-everywhere" (i32.const 3)) (i32.const 6)) - -(assert_return (invoke "as-test-first" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "as-test-last" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "as-test-everywhere" (i32.const 0)) (i32.const 1)) - -(assert_return (invoke "as-compare-first" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "as-compare-mid" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "as-compare-last" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "as-compare-everywhere" (i32.const 3)) (i32.const 1)) - -(assert_return (invoke "as-memory.grow-first" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "as-memory.grow-last" (i32.const 2)) (i32.const 1)) -(assert_return (invoke "as-memory.grow-everywhere" (i32.const 12)) (i32.const 3)) - -(assert_return (invoke "as-call_indirect-first") (i32.const 1)) -(assert_return (invoke "as-call_indirect-mid1") (i32.const 1)) -(assert_return (invoke "as-call_indirect-mid2") (i32.const 1)) -(assert_return (invoke "as-call_indirect-last") (i32.const 1)) -(assert_return (invoke "as-call_indirect-everywhere") (i32.const 1)) - -(assert_return (invoke "as-local.set-first" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "as-local.set-last" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "as-local.set-everywhere" (i32.const 1)) (i32.const 2)) - -(assert_return (invoke "as-local.tee-first" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "as-local.tee-last" (i32.const 1)) (i32.const 2)) -(assert_return (invoke "as-local.tee-everywhere" (i32.const 1)) (i32.const 2)) - -(assert_return (invoke "as-global.set-first") (i32.const 2)) -(assert_return (invoke "as-global.set-last") (i32.const 2)) -(assert_return (invoke "as-global.set-everywhere") (i32.const 2)) - -(assert_return (invoke "as-load-first" (i32.const 100)) (i32.const 0)) -(assert_return (invoke "as-load-last" (i32.const 100)) (i32.const 0)) -(assert_return (invoke "as-load-everywhere" (i32.const 100)) (i32.const 0)) - -(assert_return (invoke "as-store-first" (i32.const 0) (i32.const 1))) -(assert_return (invoke "as-store-mid" (i32.const 0) (i32.const 2))) -(assert_return (invoke "as-store-last" (i32.const 0) (i32.const 3))) -(assert_return (invoke "as-store-everywhere" (i32.const 0) (i32.const 4))) - -(assert_invalid - (module (func $type-i32 (result i32) (nop))) - "type mismatch" -) -(assert_invalid - (module (func $type-i64 (result i64) (nop))) - "type mismatch" -) -(assert_invalid - (module (func $type-f32 (result f32) (nop))) - "type mismatch" -) -(assert_invalid - (module (func $type-f64 (result f64) (nop))) - "type mismatch" -) diff --git a/test/spec/ref_as_non_null.wast b/test/spec/ref_as_non_null.wast deleted file mode 100644 index e597e7b9b2b..00000000000 --- a/test/spec/ref_as_non_null.wast +++ /dev/null @@ -1,28 +0,0 @@ -(module - (type $t (func (result i32))) - - (func $nn (param $r (ref $t)) (result i32) - (call_ref $t (ref.as_non_null (local.get $r))) - ) - (func $n (param $r (ref null $t)) (result i32) - (call_ref $t (ref.as_non_null (local.get $r))) - ) - - (elem func $f) - (func $f (result i32) (i32.const 7)) - - (func (export "nullable-null") (result i32) (call $n (ref.null $t))) - (func (export "nonnullable-f") (result i32) (call $nn (ref.func $f))) - (func (export "nullable-f") (result i32) (call $n (ref.func $f))) -) - -(assert_trap (invoke "nullable-null") "null reference") -(assert_return (invoke "nonnullable-f") (i32.const 7)) -(assert_return (invoke "nullable-f") (i32.const 7)) - -(module - (type $t (func)) - (func (param $r (ref $t)) (drop (ref.as_non_null (local.get $r)))) - (func (param $r (ref func)) (drop (ref.as_non_null (local.get $r)))) - (func (param $r (ref extern)) (drop (ref.as_non_null (local.get $r)))) -) diff --git a/test/spec/return.wast b/test/spec/return.wast deleted file mode 100644 index 7077f25b696..00000000000 --- a/test/spec/return.wast +++ /dev/null @@ -1,479 +0,0 @@ -;; Test `return` operator - -(module - ;; Auxiliary definition - (func $dummy) - - (func (export "type-i32") (drop (i32.ctz (return)))) - (func (export "type-i64") (drop (i64.ctz (return)))) - (func (export "type-f32") (drop (f32.neg (return)))) - (func (export "type-f64") (drop (f64.neg (return)))) - - (func (export "type-i32-value") (result i32) - (block (result i32) (i32.ctz (return (i32.const 1)))) - ) - (func (export "type-i64-value") (result i64) - (block (result i64) (i64.ctz (return (i64.const 2)))) - ) - (func (export "type-f32-value") (result f32) - (block (result f32) (f32.neg (return (f32.const 3)))) - ) - (func (export "type-f64-value") (result f64) - (block (result f64) (f64.neg (return (f64.const 4)))) - ) - - (func (export "nullary") (return)) - (func (export "unary") (result f64) (return (f64.const 3))) - - (func (export "as-func-first") (result i32) - (return (i32.const 1)) (i32.const 2) - ) - (func (export "as-func-mid") (result i32) - (call $dummy) (return (i32.const 2)) (i32.const 3) - ) - (func (export "as-func-last") - (nop) (call $dummy) (return) - ) - (func (export "as-func-value") (result i32) - (nop) (call $dummy) (return (i32.const 3)) - ) - - (func (export "as-block-first") - (block (return) (call $dummy)) - ) - (func (export "as-block-mid") - (block (call $dummy) (return) (call $dummy)) - ) - (func (export "as-block-last") - (block (nop) (call $dummy) (return)) - ) - (func (export "as-block-value") (result i32) - (block (result i32) (nop) (call $dummy) (return (i32.const 2))) - ) - - (func (export "as-loop-first") (result i32) - (loop (result i32) (return (i32.const 3)) (i32.const 2)) - ) - (func (export "as-loop-mid") (result i32) - (loop (result i32) (call $dummy) (return (i32.const 4)) (i32.const 2)) - ) - (func (export "as-loop-last") (result i32) - (loop (result i32) (nop) (call $dummy) (return (i32.const 5))) - ) - - (func (export "as-br-value") (result i32) - (block (result i32) (br 0 (return (i32.const 9)))) - ) - - (func (export "as-br_if-cond") - (block (br_if 0 (return))) - ) - (func (export "as-br_if-value") (result i32) - (block (result i32) - (drop (br_if 0 (return (i32.const 8)) (i32.const 1))) (i32.const 7) - ) - ) - (func (export "as-br_if-value-cond") (result i32) - (block (result i32) - (drop (br_if 0 (i32.const 6) (return (i32.const 9)))) (i32.const 7) - ) - ) - - (func (export "as-br_table-index") (result i64) - (block (br_table 0 0 0 (return (i64.const 9)))) (i64.const -1) - ) - (func (export "as-br_table-value") (result i32) - (block (result i32) - (br_table 0 0 0 (return (i32.const 10)) (i32.const 1)) (i32.const 7) - ) - ) - (func (export "as-br_table-value-index") (result i32) - (block (result i32) - (br_table 0 0 (i32.const 6) (return (i32.const 11))) (i32.const 7) - ) - ) - - (func (export "as-return-value") (result i64) - (return (return (i64.const 7))) - ) - - (func (export "as-if-cond") (result i32) - (if (result i32) - (return (i32.const 2)) (then (i32.const 0)) (else (i32.const 1)) - ) - ) - (func (export "as-if-then") (param i32 i32) (result i32) - (if (result i32) - (local.get 0) (then (return (i32.const 3))) (else (local.get 1)) - ) - ) - (func (export "as-if-else") (param i32 i32) (result i32) - (if (result i32) - (local.get 0) (then (local.get 1)) (else (return (i32.const 4))) - ) - ) - - (func (export "as-select-first") (param i32 i32) (result i32) - (select (return (i32.const 5)) (local.get 0) (local.get 1)) - ) - (func (export "as-select-second") (param i32 i32) (result i32) - (select (local.get 0) (return (i32.const 6)) (local.get 1)) - ) - (func (export "as-select-cond") (result i32) - (select (i32.const 0) (i32.const 1) (return (i32.const 7))) - ) - - (func $f (param i32 i32 i32) (result i32) (i32.const -1)) - (func (export "as-call-first") (result i32) - (call $f (return (i32.const 12)) (i32.const 2) (i32.const 3)) - ) - (func (export "as-call-mid") (result i32) - (call $f (i32.const 1) (return (i32.const 13)) (i32.const 3)) - ) - (func (export "as-call-last") (result i32) - (call $f (i32.const 1) (i32.const 2) (return (i32.const 14))) - ) - - (type $sig (func (param i32 i32 i32) (result i32))) - (table funcref (elem $f)) - (func (export "as-call_indirect-func") (result i32) - (call_indirect (type $sig) - (return (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3) - ) - ) - (func (export "as-call_indirect-first") (result i32) - (call_indirect (type $sig) - (i32.const 0) (return (i32.const 21)) (i32.const 2) (i32.const 3) - ) - ) - (func (export "as-call_indirect-mid") (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (return (i32.const 22)) (i32.const 3) - ) - ) - (func (export "as-call_indirect-last") (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (i32.const 2) (return (i32.const 23)) - ) - ) - - (func (export "as-local.set-value") (result i32) (local f32) - (local.set 0 (return (i32.const 17))) (i32.const -1) - ) - (func (export "as-local.tee-value") (result i32) (local i32) - (local.tee 0 (return (i32.const 1))) - ) - (global $a (mut i32) (i32.const 0)) - (func (export "as-global.set-value") (result i32) - (global.set $a (return (i32.const 1))) - ) - - (memory 1) - (func (export "as-load-address") (result f32) - (f32.load (return (f32.const 1.7))) - ) - (func (export "as-loadN-address") (result i64) - (i64.load8_s (return (i64.const 30))) - ) - - (func (export "as-store-address") (result i32) - (f64.store (return (i32.const 30)) (f64.const 7)) (i32.const -1) - ) - (func (export "as-store-value") (result i32) - (i64.store (i32.const 2) (return (i32.const 31))) (i32.const -1) - ) - - (func (export "as-storeN-address") (result i32) - (i32.store8 (return (i32.const 32)) (i32.const 7)) (i32.const -1) - ) - (func (export "as-storeN-value") (result i32) - (i64.store16 (i32.const 2) (return (i32.const 33))) (i32.const -1) - ) - - (func (export "as-unary-operand") (result f32) - (f32.neg (return (f32.const 3.4))) - ) - - (func (export "as-binary-left") (result i32) - (i32.add (return (i32.const 3)) (i32.const 10)) - ) - (func (export "as-binary-right") (result i64) - (i64.sub (i64.const 10) (return (i64.const 45))) - ) - - (func (export "as-test-operand") (result i32) - (i32.eqz (return (i32.const 44))) - ) - - (func (export "as-compare-left") (result i32) - (f64.le (return (i32.const 43)) (f64.const 10)) - ) - (func (export "as-compare-right") (result i32) - (f32.ne (f32.const 10) (return (i32.const 42))) - ) - - (func (export "as-convert-operand") (result i32) - (i32.wrap_i64 (return (i32.const 41))) - ) - - (func (export "as-memory.grow-size") (result i32) - (memory.grow (return (i32.const 40))) - ) -) - -(assert_return (invoke "type-i32")) -(assert_return (invoke "type-i64")) -(assert_return (invoke "type-f32")) -(assert_return (invoke "type-f64")) - -(assert_return (invoke "type-i32-value") (i32.const 1)) -(assert_return (invoke "type-i64-value") (i64.const 2)) -(assert_return (invoke "type-f32-value") (f32.const 3)) -(assert_return (invoke "type-f64-value") (f64.const 4)) - -(assert_return (invoke "nullary")) -(assert_return (invoke "unary") (f64.const 3)) - -(assert_return (invoke "as-func-first") (i32.const 1)) -(assert_return (invoke "as-func-mid") (i32.const 2)) -(assert_return (invoke "as-func-last")) -(assert_return (invoke "as-func-value") (i32.const 3)) - -(assert_return (invoke "as-block-first")) -(assert_return (invoke "as-block-mid")) -(assert_return (invoke "as-block-last")) -(assert_return (invoke "as-block-value") (i32.const 2)) - -(assert_return (invoke "as-loop-first") (i32.const 3)) -(assert_return (invoke "as-loop-mid") (i32.const 4)) -(assert_return (invoke "as-loop-last") (i32.const 5)) - -(assert_return (invoke "as-br-value") (i32.const 9)) - -(assert_return (invoke "as-br_if-cond")) -(assert_return (invoke "as-br_if-value") (i32.const 8)) -(assert_return (invoke "as-br_if-value-cond") (i32.const 9)) - -(assert_return (invoke "as-br_table-index") (i64.const 9)) -(assert_return (invoke "as-br_table-value") (i32.const 10)) -(assert_return (invoke "as-br_table-value-index") (i32.const 11)) - -(assert_return (invoke "as-return-value") (i64.const 7)) - -(assert_return (invoke "as-if-cond") (i32.const 2)) -(assert_return (invoke "as-if-then" (i32.const 1) (i32.const 6)) (i32.const 3)) -(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 6)) (i32.const 4)) -(assert_return (invoke "as-if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) - -(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-first" (i32.const 1) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-second" (i32.const 1) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-cond") (i32.const 7)) - -(assert_return (invoke "as-call-first") (i32.const 12)) -(assert_return (invoke "as-call-mid") (i32.const 13)) -(assert_return (invoke "as-call-last") (i32.const 14)) - -(assert_return (invoke "as-call_indirect-func") (i32.const 20)) -(assert_return (invoke "as-call_indirect-first") (i32.const 21)) -(assert_return (invoke "as-call_indirect-mid") (i32.const 22)) -(assert_return (invoke "as-call_indirect-last") (i32.const 23)) - -(assert_return (invoke "as-local.set-value") (i32.const 17)) -(assert_return (invoke "as-local.tee-value") (i32.const 1)) -(assert_return (invoke "as-global.set-value") (i32.const 1)) - -(assert_return (invoke "as-load-address") (f32.const 1.7)) -(assert_return (invoke "as-loadN-address") (i64.const 30)) - -(assert_return (invoke "as-store-address") (i32.const 30)) -(assert_return (invoke "as-store-value") (i32.const 31)) -(assert_return (invoke "as-storeN-address") (i32.const 32)) -(assert_return (invoke "as-storeN-value") (i32.const 33)) - -(assert_return (invoke "as-unary-operand") (f32.const 3.4)) - -(assert_return (invoke "as-binary-left") (i32.const 3)) -(assert_return (invoke "as-binary-right") (i64.const 45)) - -(assert_return (invoke "as-test-operand") (i32.const 44)) - -(assert_return (invoke "as-compare-left") (i32.const 43)) -(assert_return (invoke "as-compare-right") (i32.const 42)) - -(assert_return (invoke "as-convert-operand") (i32.const 41)) - -(assert_return (invoke "as-memory.grow-size") (i32.const 40)) - -(assert_invalid - (module (func $type-value-empty-vs-num (result i32) (return))) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-block (result i32) - (i32.const 0) - (block (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-loop (result i32) - (i32.const 0) - (loop (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-then (result i32) - (i32.const 0) (i32.const 0) - (if (then (return))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-else (result i32) - (i32.const 0) (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (return))) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-br (result i32) - (i32.const 0) - (block (br 0 (return))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-br_if (result i32) - (i32.const 0) - (block (br_if 0 (return) (i32.const 1))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-br_table (result i32) - (i32.const 0) - (block (br_table 0 (return))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-return (result i32) - (return (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-select (result i32) - (select (return) (i32.const 1) (i32.const 2)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-call (result i32) - (call 1 (return)) - ) - (func (param i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-value-empty-vs-num-in-call_indirect (result i32) - (block (result i32) - (call_indirect (type $sig) - (return) (i32.const 0) - ) - ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-local.set (result i32) - (local i32) - (local.set 0 (return)) (local.get 0) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-value-empty-vs-num-in-local.tee (result i32) - (local i32) - (local.tee 0 (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (global $x (mut i32) (i32.const 0)) - (func $type-value-empty-vs-num-in-global.set (result i32) - (global.set $x (return)) (global.get $x) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-value-empty-vs-num-in-memory.grow (result i32) - (memory.grow (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 0) - (func $type-value-empty-vs-num-in-load (result i32) - (i32.load (return)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-vs-num-in-store (result i32) - (i32.store (return) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module (func $type-value-void-vs-num (result f64) (return (nop)))) - "type mismatch" -) -(assert_invalid - (module (func $type-value-num-vs-num (result f64) (return (i64.const 1)))) - "type mismatch" -) - diff --git a/test/spec/return_call.wast b/test/spec/return_call.wast deleted file mode 100644 index 9423159ffe0..00000000000 --- a/test/spec/return_call.wast +++ /dev/null @@ -1,202 +0,0 @@ -;; Test `return_call` operator - -(module - ;; Auxiliary definitions - (func $const-i32 (result i32) (i32.const 0x132)) - (func $const-i64 (result i64) (i64.const 0x164)) - (func $const-f32 (result f32) (f32.const 0xf32)) - (func $const-f64 (result f64) (f64.const 0xf64)) - - (func $id-i32 (param i32) (result i32) (local.get 0)) - (func $id-i64 (param i64) (result i64) (local.get 0)) - (func $id-f32 (param f32) (result f32) (local.get 0)) - (func $id-f64 (param f64) (result f64) (local.get 0)) - - (func $f32-i32 (param f32 i32) (result i32) (local.get 1)) - (func $i32-i64 (param i32 i64) (result i64) (local.get 1)) - (func $f64-f32 (param f64 f32) (result f32) (local.get 1)) - (func $i64-f64 (param i64 f64) (result f64) (local.get 1)) - - ;; Typing - - (func (export "type-i32") (result i32) (return_call $const-i32)) - (func (export "type-i64") (result i64) (return_call $const-i64)) - (func (export "type-f32") (result f32) (return_call $const-f32)) - (func (export "type-f64") (result f64) (return_call $const-f64)) - - (func (export "type-first-i32") (result i32) (return_call $id-i32 (i32.const 32))) - (func (export "type-first-i64") (result i64) (return_call $id-i64 (i64.const 64))) - (func (export "type-first-f32") (result f32) (return_call $id-f32 (f32.const 1.32))) - (func (export "type-first-f64") (result f64) (return_call $id-f64 (f64.const 1.64))) - - (func (export "type-second-i32") (result i32) - (return_call $f32-i32 (f32.const 32.1) (i32.const 32)) - ) - (func (export "type-second-i64") (result i64) - (return_call $i32-i64 (i32.const 32) (i64.const 64)) - ) - (func (export "type-second-f32") (result f32) - (return_call $f64-f32 (f64.const 64) (f32.const 32)) - ) - (func (export "type-second-f64") (result f64) - (return_call $i64-f64 (i64.const 64) (f64.const 64.1)) - ) - - ;; Recursion - - (func $fac-acc (export "fac-acc") (param i64 i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 1)) - (else - (return_call $fac-acc - (i64.sub (local.get 0) (i64.const 1)) - (i64.mul (local.get 0) (local.get 1)) - ) - ) - ) - ) - - (func $count (export "count") (param i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 0)) - (else (return_call $count (i64.sub (local.get 0) (i64.const 1)))) - ) - ) - - (func $even (export "even") (param i64) (result i32) - (if (result i32) (i64.eqz (local.get 0)) - (then (i32.const 44)) - (else (return_call $odd (i64.sub (local.get 0) (i64.const 1)))) - ) - ) - (func $odd (export "odd") (param i64) (result i32) - (if (result i32) (i64.eqz (local.get 0)) - (then (i32.const 99)) - (else (return_call $even (i64.sub (local.get 0) (i64.const 1)))) - ) - ) -) - -(assert_return (invoke "type-i32") (i32.const 0x132)) -(assert_return (invoke "type-i64") (i64.const 0x164)) -(assert_return (invoke "type-f32") (f32.const 0xf32)) -(assert_return (invoke "type-f64") (f64.const 0xf64)) - -(assert_return (invoke "type-first-i32") (i32.const 32)) -(assert_return (invoke "type-first-i64") (i64.const 64)) -(assert_return (invoke "type-first-f32") (f32.const 1.32)) -(assert_return (invoke "type-first-f64") (f64.const 1.64)) - -(assert_return (invoke "type-second-i32") (i32.const 32)) -(assert_return (invoke "type-second-i64") (i64.const 64)) -(assert_return (invoke "type-second-f32") (f32.const 32)) -(assert_return (invoke "type-second-f64") (f64.const 64.1)) - -(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120)) -(assert_return - (invoke "fac-acc" (i64.const 25) (i64.const 1)) - (i64.const 7034535277573963776) -) - -(assert_return (invoke "count" (i64.const 0)) (i64.const 0)) -(assert_return (invoke "count" (i64.const 1000)) (i64.const 0)) -(assert_return (invoke "count" (i64.const 1000000)) (i64.const 0)) - -(assert_return (invoke "even" (i64.const 0)) (i32.const 44)) -(assert_return (invoke "even" (i64.const 1)) (i32.const 99)) -(assert_return (invoke "even" (i64.const 100)) (i32.const 44)) -(assert_return (invoke "even" (i64.const 77)) (i32.const 99)) -(assert_return (invoke "even" (i64.const 1000000)) (i32.const 44)) -(assert_return (invoke "even" (i64.const 1000001)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 0)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 1)) (i32.const 44)) -(assert_return (invoke "odd" (i64.const 200)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 77)) (i32.const 44)) -(assert_return (invoke "odd" (i64.const 1000000)) (i32.const 99)) -(assert_return (invoke "odd" (i64.const 999999)) (i32.const 44)) - - -;; Invalid typing - -(assert_invalid - (module - (func $type-void-vs-num (result i32) (return_call 1) (i32.const 0)) - (func) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-num-vs-num (result i32) (return_call 1) (i32.const 0)) - (func (result i64) (i64.const 1)) - ) - "type mismatch" -) - -(assert_invalid - (module - (func $arity-0-vs-1 (return_call 1)) - (func (param i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $arity-0-vs-2 (return_call 1)) - (func (param f64 i32)) - ) - "type mismatch" -) - -;; (module -;; (func $arity-1-vs-0 (i32.const 1) (return_call 1)) -;; (func) -;; ) - -;; (module -;; (func $arity-2-vs-0 (f64.const 2) (i32.const 1) (return_call 1)) -;; (func) -;; ) - -(assert_invalid - (module - (func $type-first-void-vs-num (return_call 1 (nop) (i32.const 1))) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-void-vs-num (return_call 1 (i32.const 1) (nop))) - (func (param i32 i32)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-first-num-vs-num (return_call 1 (f64.const 1) (i32.const 1))) - (func (param i32 f64)) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-second-num-vs-num (return_call 1 (i32.const 1) (f64.const 1))) - (func (param f64 i32)) - ) - "type mismatch" -) - - -;; Unbound function - -(assert_invalid - (module (func $unbound-func (return_call 1))) - "unknown function" -) -(assert_invalid - (module (func $large-func (return_call 1012321300))) - "unknown function" -) diff --git a/test/spec/return_call_ref.wast b/test/spec/return_call_ref.wast deleted file mode 100644 index 6bb5d2a147e..00000000000 --- a/test/spec/return_call_ref.wast +++ /dev/null @@ -1,377 +0,0 @@ -;; Test `return_call_ref` operator - -(module - ;; Auxiliary definitions - (type $proc (func)) - (type $-i32 (func (result i32))) - (type $-i64 (func (result i64))) - (type $-f32 (func (result f32))) - (type $-f64 (func (result f64))) - - (type $i32-i32 (func (param i32) (result i32))) - (type $i64-i64 (func (param i64) (result i64))) - (type $f32-f32 (func (param f32) (result f32))) - (type $f64-f64 (func (param f64) (result f64))) - - (type $f32-i32 (func (param f32 i32) (result i32))) - (type $i32-i64 (func (param i32 i64) (result i64))) - (type $f64-f32 (func (param f64 f32) (result f32))) - (type $i64-f64 (func (param i64 f64) (result f64))) - - (type $i64i64-i64 (func (param i64 i64) (result i64))) - - (func $const-i32 (result i32) (i32.const 0x132)) - (func $const-i64 (result i64) (i64.const 0x164)) - (func $const-f32 (result f32) (f32.const 0xf32)) - (func $const-f64 (result f64) (f64.const 0xf64)) - - (func $id-i32 (param i32) (result i32) (local.get 0)) - (func $id-i64 (param i64) (result i64) (local.get 0)) - (func $id-f32 (param f32) (result f32) (local.get 0)) - (func $id-f64 (param f64) (result f64) (local.get 0)) - - (func $f32-i32 (param f32 i32) (result i32) (local.get 1)) - (func $i32-i64 (param i32 i64) (result i64) (local.get 1)) - (func $f64-f32 (param f64 f32) (result f32) (local.get 1)) - (func $i64-f64 (param i64 f64) (result f64) (local.get 1)) - - (global $const-i32 (ref $-i32) (ref.func $const-i32)) - (global $const-i64 (ref $-i64) (ref.func $const-i64)) - (global $const-f32 (ref $-f32) (ref.func $const-f32)) - (global $const-f64 (ref $-f64) (ref.func $const-f64)) - - (global $id-i32 (ref $i32-i32) (ref.func $id-i32)) - (global $id-i64 (ref $i64-i64) (ref.func $id-i64)) - (global $id-f32 (ref $f32-f32) (ref.func $id-f32)) - (global $id-f64 (ref $f64-f64) (ref.func $id-f64)) - - (global $f32-i32 (ref $f32-i32) (ref.func $f32-i32)) - (global $i32-i64 (ref $i32-i64) (ref.func $i32-i64)) - (global $f64-f32 (ref $f64-f32) (ref.func $f64-f32)) - (global $i64-f64 (ref $i64-f64) (ref.func $i64-f64)) - - (elem declare func - $const-i32 $const-i64 $const-f32 $const-f64 - $id-i32 $id-i64 $id-f32 $id-f64 - $f32-i32 $i32-i64 $f64-f32 $i64-f64 - ) - - ;; Typing - - (func (export "type-i32") (result i32) - (return_call_ref $-i32 (global.get $const-i32)) - ) - (func (export "type-i64") (result i64) - (return_call_ref $-i64 (global.get $const-i64)) - ) - (func (export "type-f32") (result f32) - (return_call_ref $-f32 (global.get $const-f32)) - ) - (func (export "type-f64") (result f64) - (return_call_ref $-f64 (global.get $const-f64)) - ) - - (func (export "type-first-i32") (result i32) - (return_call_ref $i32-i32 (i32.const 32) (global.get $id-i32)) - ) - (func (export "type-first-i64") (result i64) - (return_call_ref $i64-i64 (i64.const 64) (global.get $id-i64)) - ) - (func (export "type-first-f32") (result f32) - (return_call_ref $f32-f32 (f32.const 1.32) (global.get $id-f32)) - ) - (func (export "type-first-f64") (result f64) - (return_call_ref $f64-f64 (f64.const 1.64) (global.get $id-f64)) - ) - - (func (export "type-second-i32") (result i32) - (return_call_ref $f32-i32 (f32.const 32.1) (i32.const 32) (global.get $f32-i32)) - ) - (func (export "type-second-i64") (result i64) - (return_call_ref $i32-i64 (i32.const 32) (i64.const 64) (global.get $i32-i64)) - ) - (func (export "type-second-f32") (result f32) - (return_call_ref $f64-f32 (f64.const 64) (f32.const 32) (global.get $f64-f32)) - ) - (func (export "type-second-f64") (result f64) - (return_call_ref $i64-f64 (i64.const 64) (f64.const 64.1) (global.get $i64-f64)) - ) - - ;; Null - - (func (export "null") - (return_call_ref $proc (ref.null $proc)) - ) - - ;; Recursion - - (global $fac-acc (ref $i64i64-i64) (ref.func $fac-acc)) - - (elem declare func $fac-acc) - (func $fac-acc (export "fac-acc") (param i64 i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 1)) - (else - (return_call_ref $i64i64-i64 - (i64.sub (local.get 0) (i64.const 1)) - (i64.mul (local.get 0) (local.get 1)) - (global.get $fac-acc) - ) - ) - ) - ) - - (global $count (ref $i64-i64) (ref.func $count)) - - (elem declare func $count) - (func $count (export "count") (param i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (local.get 0)) - (else - (return_call_ref $i64-i64 - (i64.sub (local.get 0) (i64.const 1)) - (global.get $count) - ) - ) - ) - ) - - (global $even (ref $i64-i64) (ref.func $even)) - (global $odd (ref $i64-i64) (ref.func $odd)) - - (elem declare func $even) - (func $even (export "even") (param i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 44)) - (else - (return_call_ref $i64-i64 - (i64.sub (local.get 0) (i64.const 1)) - (global.get $odd) - ) - ) - ) - ) - (elem declare func $odd) - (func $odd (export "odd") (param i64) (result i64) - (if (result i64) (i64.eqz (local.get 0)) - (then (i64.const 99)) - (else - (return_call_ref $i64-i64 - (i64.sub (local.get 0) (i64.const 1)) - (global.get $even) - ) - ) - ) - ) -) - -(assert_return (invoke "type-i32") (i32.const 0x132)) -(assert_return (invoke "type-i64") (i64.const 0x164)) -(assert_return (invoke "type-f32") (f32.const 0xf32)) -(assert_return (invoke "type-f64") (f64.const 0xf64)) - -(assert_return (invoke "type-first-i32") (i32.const 32)) -(assert_return (invoke "type-first-i64") (i64.const 64)) -(assert_return (invoke "type-first-f32") (f32.const 1.32)) -(assert_return (invoke "type-first-f64") (f64.const 1.64)) - -(assert_return (invoke "type-second-i32") (i32.const 32)) -(assert_return (invoke "type-second-i64") (i64.const 64)) -(assert_return (invoke "type-second-f32") (f32.const 32)) -(assert_return (invoke "type-second-f64") (f64.const 64.1)) - -(assert_trap (invoke "null") "null function reference") - -(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1)) -(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120)) -(assert_return - (invoke "fac-acc" (i64.const 25) (i64.const 1)) - (i64.const 7034535277573963776) -) - -(assert_return (invoke "count" (i64.const 0)) (i64.const 0)) -(assert_return (invoke "count" (i64.const 1000)) (i64.const 0)) -(assert_return (invoke "count" (i64.const 1000000)) (i64.const 0)) - -(assert_return (invoke "even" (i64.const 0)) (i64.const 44)) -(assert_return (invoke "even" (i64.const 1)) (i64.const 99)) -(assert_return (invoke "even" (i64.const 100)) (i64.const 44)) -(assert_return (invoke "even" (i64.const 77)) (i64.const 99)) -(assert_return (invoke "even" (i64.const 1000000)) (i64.const 44)) -(assert_return (invoke "even" (i64.const 1000001)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 0)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 1)) (i64.const 44)) -(assert_return (invoke "odd" (i64.const 200)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 77)) (i64.const 44)) -(assert_return (invoke "odd" (i64.const 1000000)) (i64.const 99)) -(assert_return (invoke "odd" (i64.const 999999)) (i64.const 44)) - - -;; More typing - -(module - (type $t (func)) - (type $t1 (func (result (ref $t)))) - (type $t2 (func (result (ref null $t)))) - (type $t3 (func (result (ref func)))) - (type $t4 (func (result (ref null func)))) - (elem declare func $f11 $f22 $f33 $f44) - (func $f11 (result (ref $t)) (return_call_ref $t1 (ref.func $f11))) - (func $f21 (result (ref null $t)) (return_call_ref $t1 (ref.func $f11))) - (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) - (func $f31 (result (ref func)) (return_call_ref $t1 (ref.func $f11))) - (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) - (func $f41 (result (ref null func)) (return_call_ref $t1 (ref.func $f11))) - (func $f42 (result (ref null func)) (return_call_ref $t2 (ref.func $f22))) - (func $f43 (result (ref null func)) (return_call_ref $t3 (ref.func $f33))) - (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) -) - -(assert_invalid - (module - (type $t (func)) - (type $t2 (func (result (ref null $t)))) - (elem declare func $f22) - (func $f12 (result (ref $t)) (return_call_ref $t2 (ref.func $f22))) - (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (type $t3 (func (result (ref func)))) - (elem declare func $f33) - (func $f13 (result (ref $t)) (return_call_ref $t3 (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (type $t4 (func (result (ref null func)))) - (elem declare func $f44) - (func $f14 (result (ref $t)) (return_call_ref $t4 (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (type $t3 (func (result (ref func)))) - (elem declare func $f33) - (func $f23 (result (ref null $t)) (return_call_ref $t3 (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (type $t4 (func (result (ref null func)))) - (elem declare func $f44) - (func $f24 (result (ref null $t)) (return_call_ref $t4 (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t4 (func (result (ref null func)))) - (elem declare func $f44) - (func $f34 (result (ref func)) (return_call_ref $t4 (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) - ) - "type mismatch" -) - - -;; Unreachable typing. - -(module - (type $t (func (result i32))) - (func (export "unreachable") (result i32) - (return_call_ref $t (unreachable)) - ) -) -(assert_trap (invoke "unreachable") "unreachable") - -(module - (elem declare func $f) - (type $t (func (param i32) (result i32))) - (func $f (param i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result i32) - (return_call_ref $t - (unreachable) - (ref.func $f) - ) - ) -) -(assert_trap (invoke "unreachable") "unreachable") - -(module - (elem declare func $f) - (type $t (func (param i32) (result i32))) - (func $f (param i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result i32) - (unreachable) - (return_call_ref $t - (i32.const 0) - (ref.func $f) - ) - (i32.const 0) - ) -) -(assert_trap (invoke "unreachable") "unreachable") - -(assert_invalid - (module - (elem declare func $f) - (type $t (func (param i32) (result i32))) - (func $f (param i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result i32) - (unreachable) - (i64.const 0) - (ref.func $f) - (return_call_ref $t) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (elem declare func $f) - (type $t (func (param i32) (result i32))) - (func $f (param i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result i32) - (unreachable) - (ref.func $f) - (return_call_ref $t) - (i64.const 0) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (func $f (param $r externref) - (return_call_ref $t (local.get $r)) - ) - ) - "type mismatch" -) diff --git a/test/spec/skip-stack-guard-page.wast b/test/spec/skip-stack-guard-page.wast deleted file mode 100644 index a472e681488..00000000000 --- a/test/spec/skip-stack-guard-page.wast +++ /dev/null @@ -1,2284 +0,0 @@ -;; This tests that the stack overflow guard page can't be skipped by a function with more than a page of locals. -(module - (memory 1) - (export "test-guard-page-skip" (func $test-guard-page-skip)) - - (func $test-guard-page-skip - (param $depth i32) - (if (i32.eq (local.get $depth) (i32.const 0)) - (then (call $function-with-many-locals)) - (else (call $test-guard-page-skip (i32.sub (local.get $depth) (i32.const 1)))) - ) - ) - - (func $function-with-many-locals - - ;; 1056 i64 = 8448 bytes of locals - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x000-0x007 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x008-0x00f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x010-0x017 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x018-0x01f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x020-0x027 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x028-0x02f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x030-0x037 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x038-0x03f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x040-0x047 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x048-0x04f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x050-0x057 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x058-0x05f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x060-0x067 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x068-0x06f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x070-0x077 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x078-0x07f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x080-0x087 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x088-0x08f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x090-0x097 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x098-0x09f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0a0-0x0a7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0a8-0x0af - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0b0-0x0b7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0b8-0x0bf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0c0-0x0c7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0c8-0x0cf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0d0-0x0d7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0d8-0x0df - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0e0-0x0e7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0e8-0x0ef - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0f0-0x0f7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x0f8-0x0ff - - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x100-0x107 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x108-0x10f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x110-0x117 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x118-0x11f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x120-0x127 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x128-0x12f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x130-0x137 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x138-0x13f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x140-0x147 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x148-0x14f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x150-0x157 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x158-0x15f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x160-0x167 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x168-0x16f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x170-0x177 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x178-0x17f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x180-0x187 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x188-0x18f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x190-0x197 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x198-0x19f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1a0-0x1a7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1a8-0x1af - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1b0-0x1b7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1b8-0x1bf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1c0-0x1c7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1c8-0x1cf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1d0-0x1d7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1d8-0x1df - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1e0-0x1e7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1e8-0x1ef - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1f0-0x1f7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x1f8-0x1ff - - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x200-0x207 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x208-0x20f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x210-0x217 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x218-0x21f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x220-0x227 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x228-0x22f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x230-0x237 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x238-0x23f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x240-0x247 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x248-0x24f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x250-0x257 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x258-0x25f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x260-0x267 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x268-0x26f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x270-0x277 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x278-0x27f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x280-0x287 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x288-0x28f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x290-0x297 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x298-0x29f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2a0-0x2a7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2a8-0x2af - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2b0-0x2b7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2b8-0x2bf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2c0-0x2c7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2c8-0x2cf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2d0-0x2d7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2d8-0x2df - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2e0-0x2e7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2e8-0x2ef - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2f0-0x2f7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x2f8-0x2ff - - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x300-0x307 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x308-0x30f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x310-0x317 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x318-0x31f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x320-0x327 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x328-0x32f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x330-0x337 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x338-0x33f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x340-0x347 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x348-0x34f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x350-0x357 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x358-0x35f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x360-0x367 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x368-0x36f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x370-0x377 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x378-0x37f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x380-0x387 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x388-0x38f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x390-0x397 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x398-0x39f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3a0-0x3a7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3a8-0x3af - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3b0-0x3b7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3b8-0x3bf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3c0-0x3c7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3c8-0x3cf - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3d0-0x3d7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3d8-0x3df - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3e0-0x3e7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3e8-0x3ef - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3f0-0x3f7 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x3f8-0x3ff - - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x400-0x407 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x408-0x40f - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x410-0x417 - (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) (local i64) ;; 0x418-0x41f - - ;; recurse first to try to make the callee access the stack below the space allocated for the locals before the locals themselves have been initialized. - (call $function-with-many-locals) - - ;; load from memory into the locals - (local.set 0x000 (i64.load offset=0x000 align=1 (i32.const 0))) - (local.set 0x001 (i64.load offset=0x001 align=1 (i32.const 0))) - (local.set 0x002 (i64.load offset=0x002 align=1 (i32.const 0))) - (local.set 0x003 (i64.load offset=0x003 align=1 (i32.const 0))) - (local.set 0x004 (i64.load offset=0x004 align=1 (i32.const 0))) - (local.set 0x005 (i64.load offset=0x005 align=1 (i32.const 0))) - (local.set 0x006 (i64.load offset=0x006 align=1 (i32.const 0))) - (local.set 0x007 (i64.load offset=0x007 align=1 (i32.const 0))) - (local.set 0x008 (i64.load offset=0x008 align=1 (i32.const 0))) - (local.set 0x009 (i64.load offset=0x009 align=1 (i32.const 0))) - (local.set 0x00a (i64.load offset=0x00a align=1 (i32.const 0))) - (local.set 0x00b (i64.load offset=0x00b align=1 (i32.const 0))) - (local.set 0x00c (i64.load offset=0x00c align=1 (i32.const 0))) - (local.set 0x00d (i64.load offset=0x00d align=1 (i32.const 0))) - (local.set 0x00e (i64.load offset=0x00e align=1 (i32.const 0))) - (local.set 0x00f (i64.load offset=0x00f align=1 (i32.const 0))) - (local.set 0x010 (i64.load offset=0x010 align=1 (i32.const 0))) - (local.set 0x011 (i64.load offset=0x011 align=1 (i32.const 0))) - (local.set 0x012 (i64.load offset=0x012 align=1 (i32.const 0))) - (local.set 0x013 (i64.load offset=0x013 align=1 (i32.const 0))) - (local.set 0x014 (i64.load offset=0x014 align=1 (i32.const 0))) - (local.set 0x015 (i64.load offset=0x015 align=1 (i32.const 0))) - (local.set 0x016 (i64.load offset=0x016 align=1 (i32.const 0))) - (local.set 0x017 (i64.load offset=0x017 align=1 (i32.const 0))) - (local.set 0x018 (i64.load offset=0x018 align=1 (i32.const 0))) - (local.set 0x019 (i64.load offset=0x019 align=1 (i32.const 0))) - (local.set 0x01a (i64.load offset=0x01a align=1 (i32.const 0))) - (local.set 0x01b (i64.load offset=0x01b align=1 (i32.const 0))) - (local.set 0x01c (i64.load offset=0x01c align=1 (i32.const 0))) - (local.set 0x01d (i64.load offset=0x01d align=1 (i32.const 0))) - (local.set 0x01e (i64.load offset=0x01e align=1 (i32.const 0))) - (local.set 0x01f (i64.load offset=0x01f align=1 (i32.const 0))) - (local.set 0x020 (i64.load offset=0x020 align=1 (i32.const 0))) - (local.set 0x021 (i64.load offset=0x021 align=1 (i32.const 0))) - (local.set 0x022 (i64.load offset=0x022 align=1 (i32.const 0))) - (local.set 0x023 (i64.load offset=0x023 align=1 (i32.const 0))) - (local.set 0x024 (i64.load offset=0x024 align=1 (i32.const 0))) - (local.set 0x025 (i64.load offset=0x025 align=1 (i32.const 0))) - (local.set 0x026 (i64.load offset=0x026 align=1 (i32.const 0))) - (local.set 0x027 (i64.load offset=0x027 align=1 (i32.const 0))) - (local.set 0x028 (i64.load offset=0x028 align=1 (i32.const 0))) - (local.set 0x029 (i64.load offset=0x029 align=1 (i32.const 0))) - (local.set 0x02a (i64.load offset=0x02a align=1 (i32.const 0))) - (local.set 0x02b (i64.load offset=0x02b align=1 (i32.const 0))) - (local.set 0x02c (i64.load offset=0x02c align=1 (i32.const 0))) - (local.set 0x02d (i64.load offset=0x02d align=1 (i32.const 0))) - (local.set 0x02e (i64.load offset=0x02e align=1 (i32.const 0))) - (local.set 0x02f (i64.load offset=0x02f align=1 (i32.const 0))) - (local.set 0x030 (i64.load offset=0x030 align=1 (i32.const 0))) - (local.set 0x031 (i64.load offset=0x031 align=1 (i32.const 0))) - (local.set 0x032 (i64.load offset=0x032 align=1 (i32.const 0))) - (local.set 0x033 (i64.load offset=0x033 align=1 (i32.const 0))) - (local.set 0x034 (i64.load offset=0x034 align=1 (i32.const 0))) - (local.set 0x035 (i64.load offset=0x035 align=1 (i32.const 0))) - (local.set 0x036 (i64.load offset=0x036 align=1 (i32.const 0))) - (local.set 0x037 (i64.load offset=0x037 align=1 (i32.const 0))) - (local.set 0x038 (i64.load offset=0x038 align=1 (i32.const 0))) - (local.set 0x039 (i64.load offset=0x039 align=1 (i32.const 0))) - (local.set 0x03a (i64.load offset=0x03a align=1 (i32.const 0))) - (local.set 0x03b (i64.load offset=0x03b align=1 (i32.const 0))) - (local.set 0x03c (i64.load offset=0x03c align=1 (i32.const 0))) - (local.set 0x03d (i64.load offset=0x03d align=1 (i32.const 0))) - (local.set 0x03e (i64.load offset=0x03e align=1 (i32.const 0))) - (local.set 0x03f (i64.load offset=0x03f align=1 (i32.const 0))) - (local.set 0x040 (i64.load offset=0x040 align=1 (i32.const 0))) - (local.set 0x041 (i64.load offset=0x041 align=1 (i32.const 0))) - (local.set 0x042 (i64.load offset=0x042 align=1 (i32.const 0))) - (local.set 0x043 (i64.load offset=0x043 align=1 (i32.const 0))) - (local.set 0x044 (i64.load offset=0x044 align=1 (i32.const 0))) - (local.set 0x045 (i64.load offset=0x045 align=1 (i32.const 0))) - (local.set 0x046 (i64.load offset=0x046 align=1 (i32.const 0))) - (local.set 0x047 (i64.load offset=0x047 align=1 (i32.const 0))) - (local.set 0x048 (i64.load offset=0x048 align=1 (i32.const 0))) - (local.set 0x049 (i64.load offset=0x049 align=1 (i32.const 0))) - (local.set 0x04a (i64.load offset=0x04a align=1 (i32.const 0))) - (local.set 0x04b (i64.load offset=0x04b align=1 (i32.const 0))) - (local.set 0x04c (i64.load offset=0x04c align=1 (i32.const 0))) - (local.set 0x04d (i64.load offset=0x04d align=1 (i32.const 0))) - (local.set 0x04e (i64.load offset=0x04e align=1 (i32.const 0))) - (local.set 0x04f (i64.load offset=0x04f align=1 (i32.const 0))) - (local.set 0x050 (i64.load offset=0x050 align=1 (i32.const 0))) - (local.set 0x051 (i64.load offset=0x051 align=1 (i32.const 0))) - (local.set 0x052 (i64.load offset=0x052 align=1 (i32.const 0))) - (local.set 0x053 (i64.load offset=0x053 align=1 (i32.const 0))) - (local.set 0x054 (i64.load offset=0x054 align=1 (i32.const 0))) - (local.set 0x055 (i64.load offset=0x055 align=1 (i32.const 0))) - (local.set 0x056 (i64.load offset=0x056 align=1 (i32.const 0))) - (local.set 0x057 (i64.load offset=0x057 align=1 (i32.const 0))) - (local.set 0x058 (i64.load offset=0x058 align=1 (i32.const 0))) - (local.set 0x059 (i64.load offset=0x059 align=1 (i32.const 0))) - (local.set 0x05a (i64.load offset=0x05a align=1 (i32.const 0))) - (local.set 0x05b (i64.load offset=0x05b align=1 (i32.const 0))) - (local.set 0x05c (i64.load offset=0x05c align=1 (i32.const 0))) - (local.set 0x05d (i64.load offset=0x05d align=1 (i32.const 0))) - (local.set 0x05e (i64.load offset=0x05e align=1 (i32.const 0))) - (local.set 0x05f (i64.load offset=0x05f align=1 (i32.const 0))) - (local.set 0x060 (i64.load offset=0x060 align=1 (i32.const 0))) - (local.set 0x061 (i64.load offset=0x061 align=1 (i32.const 0))) - (local.set 0x062 (i64.load offset=0x062 align=1 (i32.const 0))) - (local.set 0x063 (i64.load offset=0x063 align=1 (i32.const 0))) - (local.set 0x064 (i64.load offset=0x064 align=1 (i32.const 0))) - (local.set 0x065 (i64.load offset=0x065 align=1 (i32.const 0))) - (local.set 0x066 (i64.load offset=0x066 align=1 (i32.const 0))) - (local.set 0x067 (i64.load offset=0x067 align=1 (i32.const 0))) - (local.set 0x068 (i64.load offset=0x068 align=1 (i32.const 0))) - (local.set 0x069 (i64.load offset=0x069 align=1 (i32.const 0))) - (local.set 0x06a (i64.load offset=0x06a align=1 (i32.const 0))) - (local.set 0x06b (i64.load offset=0x06b align=1 (i32.const 0))) - (local.set 0x06c (i64.load offset=0x06c align=1 (i32.const 0))) - (local.set 0x06d (i64.load offset=0x06d align=1 (i32.const 0))) - (local.set 0x06e (i64.load offset=0x06e align=1 (i32.const 0))) - (local.set 0x06f (i64.load offset=0x06f align=1 (i32.const 0))) - (local.set 0x070 (i64.load offset=0x070 align=1 (i32.const 0))) - (local.set 0x071 (i64.load offset=0x071 align=1 (i32.const 0))) - (local.set 0x072 (i64.load offset=0x072 align=1 (i32.const 0))) - (local.set 0x073 (i64.load offset=0x073 align=1 (i32.const 0))) - (local.set 0x074 (i64.load offset=0x074 align=1 (i32.const 0))) - (local.set 0x075 (i64.load offset=0x075 align=1 (i32.const 0))) - (local.set 0x076 (i64.load offset=0x076 align=1 (i32.const 0))) - (local.set 0x077 (i64.load offset=0x077 align=1 (i32.const 0))) - (local.set 0x078 (i64.load offset=0x078 align=1 (i32.const 0))) - (local.set 0x079 (i64.load offset=0x079 align=1 (i32.const 0))) - (local.set 0x07a (i64.load offset=0x07a align=1 (i32.const 0))) - (local.set 0x07b (i64.load offset=0x07b align=1 (i32.const 0))) - (local.set 0x07c (i64.load offset=0x07c align=1 (i32.const 0))) - (local.set 0x07d (i64.load offset=0x07d align=1 (i32.const 0))) - (local.set 0x07e (i64.load offset=0x07e align=1 (i32.const 0))) - (local.set 0x07f (i64.load offset=0x07f align=1 (i32.const 0))) - (local.set 0x080 (i64.load offset=0x080 align=1 (i32.const 0))) - (local.set 0x081 (i64.load offset=0x081 align=1 (i32.const 0))) - (local.set 0x082 (i64.load offset=0x082 align=1 (i32.const 0))) - (local.set 0x083 (i64.load offset=0x083 align=1 (i32.const 0))) - (local.set 0x084 (i64.load offset=0x084 align=1 (i32.const 0))) - (local.set 0x085 (i64.load offset=0x085 align=1 (i32.const 0))) - (local.set 0x086 (i64.load offset=0x086 align=1 (i32.const 0))) - (local.set 0x087 (i64.load offset=0x087 align=1 (i32.const 0))) - (local.set 0x088 (i64.load offset=0x088 align=1 (i32.const 0))) - (local.set 0x089 (i64.load offset=0x089 align=1 (i32.const 0))) - (local.set 0x08a (i64.load offset=0x08a align=1 (i32.const 0))) - (local.set 0x08b (i64.load offset=0x08b align=1 (i32.const 0))) - (local.set 0x08c (i64.load offset=0x08c align=1 (i32.const 0))) - (local.set 0x08d (i64.load offset=0x08d align=1 (i32.const 0))) - (local.set 0x08e (i64.load offset=0x08e align=1 (i32.const 0))) - (local.set 0x08f (i64.load offset=0x08f align=1 (i32.const 0))) - (local.set 0x090 (i64.load offset=0x090 align=1 (i32.const 0))) - (local.set 0x091 (i64.load offset=0x091 align=1 (i32.const 0))) - (local.set 0x092 (i64.load offset=0x092 align=1 (i32.const 0))) - (local.set 0x093 (i64.load offset=0x093 align=1 (i32.const 0))) - (local.set 0x094 (i64.load offset=0x094 align=1 (i32.const 0))) - (local.set 0x095 (i64.load offset=0x095 align=1 (i32.const 0))) - (local.set 0x096 (i64.load offset=0x096 align=1 (i32.const 0))) - (local.set 0x097 (i64.load offset=0x097 align=1 (i32.const 0))) - (local.set 0x098 (i64.load offset=0x098 align=1 (i32.const 0))) - (local.set 0x099 (i64.load offset=0x099 align=1 (i32.const 0))) - (local.set 0x09a (i64.load offset=0x09a align=1 (i32.const 0))) - (local.set 0x09b (i64.load offset=0x09b align=1 (i32.const 0))) - (local.set 0x09c (i64.load offset=0x09c align=1 (i32.const 0))) - (local.set 0x09d (i64.load offset=0x09d align=1 (i32.const 0))) - (local.set 0x09e (i64.load offset=0x09e align=1 (i32.const 0))) - (local.set 0x09f (i64.load offset=0x09f align=1 (i32.const 0))) - (local.set 0x0a0 (i64.load offset=0x0a0 align=1 (i32.const 0))) - (local.set 0x0a1 (i64.load offset=0x0a1 align=1 (i32.const 0))) - (local.set 0x0a2 (i64.load offset=0x0a2 align=1 (i32.const 0))) - (local.set 0x0a3 (i64.load offset=0x0a3 align=1 (i32.const 0))) - (local.set 0x0a4 (i64.load offset=0x0a4 align=1 (i32.const 0))) - (local.set 0x0a5 (i64.load offset=0x0a5 align=1 (i32.const 0))) - (local.set 0x0a6 (i64.load offset=0x0a6 align=1 (i32.const 0))) - (local.set 0x0a7 (i64.load offset=0x0a7 align=1 (i32.const 0))) - (local.set 0x0a8 (i64.load offset=0x0a8 align=1 (i32.const 0))) - (local.set 0x0a9 (i64.load offset=0x0a9 align=1 (i32.const 0))) - (local.set 0x0aa (i64.load offset=0x0aa align=1 (i32.const 0))) - (local.set 0x0ab (i64.load offset=0x0ab align=1 (i32.const 0))) - (local.set 0x0ac (i64.load offset=0x0ac align=1 (i32.const 0))) - (local.set 0x0ad (i64.load offset=0x0ad align=1 (i32.const 0))) - (local.set 0x0ae (i64.load offset=0x0ae align=1 (i32.const 0))) - (local.set 0x0af (i64.load offset=0x0af align=1 (i32.const 0))) - (local.set 0x0b0 (i64.load offset=0x0b0 align=1 (i32.const 0))) - (local.set 0x0b1 (i64.load offset=0x0b1 align=1 (i32.const 0))) - (local.set 0x0b2 (i64.load offset=0x0b2 align=1 (i32.const 0))) - (local.set 0x0b3 (i64.load offset=0x0b3 align=1 (i32.const 0))) - (local.set 0x0b4 (i64.load offset=0x0b4 align=1 (i32.const 0))) - (local.set 0x0b5 (i64.load offset=0x0b5 align=1 (i32.const 0))) - (local.set 0x0b6 (i64.load offset=0x0b6 align=1 (i32.const 0))) - (local.set 0x0b7 (i64.load offset=0x0b7 align=1 (i32.const 0))) - (local.set 0x0b8 (i64.load offset=0x0b8 align=1 (i32.const 0))) - (local.set 0x0b9 (i64.load offset=0x0b9 align=1 (i32.const 0))) - (local.set 0x0ba (i64.load offset=0x0ba align=1 (i32.const 0))) - (local.set 0x0bb (i64.load offset=0x0bb align=1 (i32.const 0))) - (local.set 0x0bc (i64.load offset=0x0bc align=1 (i32.const 0))) - (local.set 0x0bd (i64.load offset=0x0bd align=1 (i32.const 0))) - (local.set 0x0be (i64.load offset=0x0be align=1 (i32.const 0))) - (local.set 0x0bf (i64.load offset=0x0bf align=1 (i32.const 0))) - (local.set 0x0c0 (i64.load offset=0x0c0 align=1 (i32.const 0))) - (local.set 0x0c1 (i64.load offset=0x0c1 align=1 (i32.const 0))) - (local.set 0x0c2 (i64.load offset=0x0c2 align=1 (i32.const 0))) - (local.set 0x0c3 (i64.load offset=0x0c3 align=1 (i32.const 0))) - (local.set 0x0c4 (i64.load offset=0x0c4 align=1 (i32.const 0))) - (local.set 0x0c5 (i64.load offset=0x0c5 align=1 (i32.const 0))) - (local.set 0x0c6 (i64.load offset=0x0c6 align=1 (i32.const 0))) - (local.set 0x0c7 (i64.load offset=0x0c7 align=1 (i32.const 0))) - (local.set 0x0c8 (i64.load offset=0x0c8 align=1 (i32.const 0))) - (local.set 0x0c9 (i64.load offset=0x0c9 align=1 (i32.const 0))) - (local.set 0x0ca (i64.load offset=0x0ca align=1 (i32.const 0))) - (local.set 0x0cb (i64.load offset=0x0cb align=1 (i32.const 0))) - (local.set 0x0cc (i64.load offset=0x0cc align=1 (i32.const 0))) - (local.set 0x0cd (i64.load offset=0x0cd align=1 (i32.const 0))) - (local.set 0x0ce (i64.load offset=0x0ce align=1 (i32.const 0))) - (local.set 0x0cf (i64.load offset=0x0cf align=1 (i32.const 0))) - (local.set 0x0d0 (i64.load offset=0x0d0 align=1 (i32.const 0))) - (local.set 0x0d1 (i64.load offset=0x0d1 align=1 (i32.const 0))) - (local.set 0x0d2 (i64.load offset=0x0d2 align=1 (i32.const 0))) - (local.set 0x0d3 (i64.load offset=0x0d3 align=1 (i32.const 0))) - (local.set 0x0d4 (i64.load offset=0x0d4 align=1 (i32.const 0))) - (local.set 0x0d5 (i64.load offset=0x0d5 align=1 (i32.const 0))) - (local.set 0x0d6 (i64.load offset=0x0d6 align=1 (i32.const 0))) - (local.set 0x0d7 (i64.load offset=0x0d7 align=1 (i32.const 0))) - (local.set 0x0d8 (i64.load offset=0x0d8 align=1 (i32.const 0))) - (local.set 0x0d9 (i64.load offset=0x0d9 align=1 (i32.const 0))) - (local.set 0x0da (i64.load offset=0x0da align=1 (i32.const 0))) - (local.set 0x0db (i64.load offset=0x0db align=1 (i32.const 0))) - (local.set 0x0dc (i64.load offset=0x0dc align=1 (i32.const 0))) - (local.set 0x0dd (i64.load offset=0x0dd align=1 (i32.const 0))) - (local.set 0x0de (i64.load offset=0x0de align=1 (i32.const 0))) - (local.set 0x0df (i64.load offset=0x0df align=1 (i32.const 0))) - (local.set 0x0e0 (i64.load offset=0x0e0 align=1 (i32.const 0))) - (local.set 0x0e1 (i64.load offset=0x0e1 align=1 (i32.const 0))) - (local.set 0x0e2 (i64.load offset=0x0e2 align=1 (i32.const 0))) - (local.set 0x0e3 (i64.load offset=0x0e3 align=1 (i32.const 0))) - (local.set 0x0e4 (i64.load offset=0x0e4 align=1 (i32.const 0))) - (local.set 0x0e5 (i64.load offset=0x0e5 align=1 (i32.const 0))) - (local.set 0x0e6 (i64.load offset=0x0e6 align=1 (i32.const 0))) - (local.set 0x0e7 (i64.load offset=0x0e7 align=1 (i32.const 0))) - (local.set 0x0e8 (i64.load offset=0x0e8 align=1 (i32.const 0))) - (local.set 0x0e9 (i64.load offset=0x0e9 align=1 (i32.const 0))) - (local.set 0x0ea (i64.load offset=0x0ea align=1 (i32.const 0))) - (local.set 0x0eb (i64.load offset=0x0eb align=1 (i32.const 0))) - (local.set 0x0ec (i64.load offset=0x0ec align=1 (i32.const 0))) - (local.set 0x0ed (i64.load offset=0x0ed align=1 (i32.const 0))) - (local.set 0x0ee (i64.load offset=0x0ee align=1 (i32.const 0))) - (local.set 0x0ef (i64.load offset=0x0ef align=1 (i32.const 0))) - (local.set 0x0f0 (i64.load offset=0x0f0 align=1 (i32.const 0))) - (local.set 0x0f1 (i64.load offset=0x0f1 align=1 (i32.const 0))) - (local.set 0x0f2 (i64.load offset=0x0f2 align=1 (i32.const 0))) - (local.set 0x0f3 (i64.load offset=0x0f3 align=1 (i32.const 0))) - (local.set 0x0f4 (i64.load offset=0x0f4 align=1 (i32.const 0))) - (local.set 0x0f5 (i64.load offset=0x0f5 align=1 (i32.const 0))) - (local.set 0x0f6 (i64.load offset=0x0f6 align=1 (i32.const 0))) - (local.set 0x0f7 (i64.load offset=0x0f7 align=1 (i32.const 0))) - (local.set 0x0f8 (i64.load offset=0x0f8 align=1 (i32.const 0))) - (local.set 0x0f9 (i64.load offset=0x0f9 align=1 (i32.const 0))) - (local.set 0x0fa (i64.load offset=0x0fa align=1 (i32.const 0))) - (local.set 0x0fb (i64.load offset=0x0fb align=1 (i32.const 0))) - (local.set 0x0fc (i64.load offset=0x0fc align=1 (i32.const 0))) - (local.set 0x0fd (i64.load offset=0x0fd align=1 (i32.const 0))) - (local.set 0x0fe (i64.load offset=0x0fe align=1 (i32.const 0))) - (local.set 0x0ff (i64.load offset=0x0ff align=1 (i32.const 0))) - (local.set 0x100 (i64.load offset=0x100 align=1 (i32.const 0))) - (local.set 0x101 (i64.load offset=0x101 align=1 (i32.const 0))) - (local.set 0x102 (i64.load offset=0x102 align=1 (i32.const 0))) - (local.set 0x103 (i64.load offset=0x103 align=1 (i32.const 0))) - (local.set 0x104 (i64.load offset=0x104 align=1 (i32.const 0))) - (local.set 0x105 (i64.load offset=0x105 align=1 (i32.const 0))) - (local.set 0x106 (i64.load offset=0x106 align=1 (i32.const 0))) - (local.set 0x107 (i64.load offset=0x107 align=1 (i32.const 0))) - (local.set 0x108 (i64.load offset=0x108 align=1 (i32.const 0))) - (local.set 0x109 (i64.load offset=0x109 align=1 (i32.const 0))) - (local.set 0x10a (i64.load offset=0x10a align=1 (i32.const 0))) - (local.set 0x10b (i64.load offset=0x10b align=1 (i32.const 0))) - (local.set 0x10c (i64.load offset=0x10c align=1 (i32.const 0))) - (local.set 0x10d (i64.load offset=0x10d align=1 (i32.const 0))) - (local.set 0x10e (i64.load offset=0x10e align=1 (i32.const 0))) - (local.set 0x10f (i64.load offset=0x10f align=1 (i32.const 0))) - (local.set 0x110 (i64.load offset=0x110 align=1 (i32.const 0))) - (local.set 0x111 (i64.load offset=0x111 align=1 (i32.const 0))) - (local.set 0x112 (i64.load offset=0x112 align=1 (i32.const 0))) - (local.set 0x113 (i64.load offset=0x113 align=1 (i32.const 0))) - (local.set 0x114 (i64.load offset=0x114 align=1 (i32.const 0))) - (local.set 0x115 (i64.load offset=0x115 align=1 (i32.const 0))) - (local.set 0x116 (i64.load offset=0x116 align=1 (i32.const 0))) - (local.set 0x117 (i64.load offset=0x117 align=1 (i32.const 0))) - (local.set 0x118 (i64.load offset=0x118 align=1 (i32.const 0))) - (local.set 0x119 (i64.load offset=0x119 align=1 (i32.const 0))) - (local.set 0x11a (i64.load offset=0x11a align=1 (i32.const 0))) - (local.set 0x11b (i64.load offset=0x11b align=1 (i32.const 0))) - (local.set 0x11c (i64.load offset=0x11c align=1 (i32.const 0))) - (local.set 0x11d (i64.load offset=0x11d align=1 (i32.const 0))) - (local.set 0x11e (i64.load offset=0x11e align=1 (i32.const 0))) - (local.set 0x11f (i64.load offset=0x11f align=1 (i32.const 0))) - (local.set 0x120 (i64.load offset=0x120 align=1 (i32.const 0))) - (local.set 0x121 (i64.load offset=0x121 align=1 (i32.const 0))) - (local.set 0x122 (i64.load offset=0x122 align=1 (i32.const 0))) - (local.set 0x123 (i64.load offset=0x123 align=1 (i32.const 0))) - (local.set 0x124 (i64.load offset=0x124 align=1 (i32.const 0))) - (local.set 0x125 (i64.load offset=0x125 align=1 (i32.const 0))) - (local.set 0x126 (i64.load offset=0x126 align=1 (i32.const 0))) - (local.set 0x127 (i64.load offset=0x127 align=1 (i32.const 0))) - (local.set 0x128 (i64.load offset=0x128 align=1 (i32.const 0))) - (local.set 0x129 (i64.load offset=0x129 align=1 (i32.const 0))) - (local.set 0x12a (i64.load offset=0x12a align=1 (i32.const 0))) - (local.set 0x12b (i64.load offset=0x12b align=1 (i32.const 0))) - (local.set 0x12c (i64.load offset=0x12c align=1 (i32.const 0))) - (local.set 0x12d (i64.load offset=0x12d align=1 (i32.const 0))) - (local.set 0x12e (i64.load offset=0x12e align=1 (i32.const 0))) - (local.set 0x12f (i64.load offset=0x12f align=1 (i32.const 0))) - (local.set 0x130 (i64.load offset=0x130 align=1 (i32.const 0))) - (local.set 0x131 (i64.load offset=0x131 align=1 (i32.const 0))) - (local.set 0x132 (i64.load offset=0x132 align=1 (i32.const 0))) - (local.set 0x133 (i64.load offset=0x133 align=1 (i32.const 0))) - (local.set 0x134 (i64.load offset=0x134 align=1 (i32.const 0))) - (local.set 0x135 (i64.load offset=0x135 align=1 (i32.const 0))) - (local.set 0x136 (i64.load offset=0x136 align=1 (i32.const 0))) - (local.set 0x137 (i64.load offset=0x137 align=1 (i32.const 0))) - (local.set 0x138 (i64.load offset=0x138 align=1 (i32.const 0))) - (local.set 0x139 (i64.load offset=0x139 align=1 (i32.const 0))) - (local.set 0x13a (i64.load offset=0x13a align=1 (i32.const 0))) - (local.set 0x13b (i64.load offset=0x13b align=1 (i32.const 0))) - (local.set 0x13c (i64.load offset=0x13c align=1 (i32.const 0))) - (local.set 0x13d (i64.load offset=0x13d align=1 (i32.const 0))) - (local.set 0x13e (i64.load offset=0x13e align=1 (i32.const 0))) - (local.set 0x13f (i64.load offset=0x13f align=1 (i32.const 0))) - (local.set 0x140 (i64.load offset=0x140 align=1 (i32.const 0))) - (local.set 0x141 (i64.load offset=0x141 align=1 (i32.const 0))) - (local.set 0x142 (i64.load offset=0x142 align=1 (i32.const 0))) - (local.set 0x143 (i64.load offset=0x143 align=1 (i32.const 0))) - (local.set 0x144 (i64.load offset=0x144 align=1 (i32.const 0))) - (local.set 0x145 (i64.load offset=0x145 align=1 (i32.const 0))) - (local.set 0x146 (i64.load offset=0x146 align=1 (i32.const 0))) - (local.set 0x147 (i64.load offset=0x147 align=1 (i32.const 0))) - (local.set 0x148 (i64.load offset=0x148 align=1 (i32.const 0))) - (local.set 0x149 (i64.load offset=0x149 align=1 (i32.const 0))) - (local.set 0x14a (i64.load offset=0x14a align=1 (i32.const 0))) - (local.set 0x14b (i64.load offset=0x14b align=1 (i32.const 0))) - (local.set 0x14c (i64.load offset=0x14c align=1 (i32.const 0))) - (local.set 0x14d (i64.load offset=0x14d align=1 (i32.const 0))) - (local.set 0x14e (i64.load offset=0x14e align=1 (i32.const 0))) - (local.set 0x14f (i64.load offset=0x14f align=1 (i32.const 0))) - (local.set 0x150 (i64.load offset=0x150 align=1 (i32.const 0))) - (local.set 0x151 (i64.load offset=0x151 align=1 (i32.const 0))) - (local.set 0x152 (i64.load offset=0x152 align=1 (i32.const 0))) - (local.set 0x153 (i64.load offset=0x153 align=1 (i32.const 0))) - (local.set 0x154 (i64.load offset=0x154 align=1 (i32.const 0))) - (local.set 0x155 (i64.load offset=0x155 align=1 (i32.const 0))) - (local.set 0x156 (i64.load offset=0x156 align=1 (i32.const 0))) - (local.set 0x157 (i64.load offset=0x157 align=1 (i32.const 0))) - (local.set 0x158 (i64.load offset=0x158 align=1 (i32.const 0))) - (local.set 0x159 (i64.load offset=0x159 align=1 (i32.const 0))) - (local.set 0x15a (i64.load offset=0x15a align=1 (i32.const 0))) - (local.set 0x15b (i64.load offset=0x15b align=1 (i32.const 0))) - (local.set 0x15c (i64.load offset=0x15c align=1 (i32.const 0))) - (local.set 0x15d (i64.load offset=0x15d align=1 (i32.const 0))) - (local.set 0x15e (i64.load offset=0x15e align=1 (i32.const 0))) - (local.set 0x15f (i64.load offset=0x15f align=1 (i32.const 0))) - (local.set 0x160 (i64.load offset=0x160 align=1 (i32.const 0))) - (local.set 0x161 (i64.load offset=0x161 align=1 (i32.const 0))) - (local.set 0x162 (i64.load offset=0x162 align=1 (i32.const 0))) - (local.set 0x163 (i64.load offset=0x163 align=1 (i32.const 0))) - (local.set 0x164 (i64.load offset=0x164 align=1 (i32.const 0))) - (local.set 0x165 (i64.load offset=0x165 align=1 (i32.const 0))) - (local.set 0x166 (i64.load offset=0x166 align=1 (i32.const 0))) - (local.set 0x167 (i64.load offset=0x167 align=1 (i32.const 0))) - (local.set 0x168 (i64.load offset=0x168 align=1 (i32.const 0))) - (local.set 0x169 (i64.load offset=0x169 align=1 (i32.const 0))) - (local.set 0x16a (i64.load offset=0x16a align=1 (i32.const 0))) - (local.set 0x16b (i64.load offset=0x16b align=1 (i32.const 0))) - (local.set 0x16c (i64.load offset=0x16c align=1 (i32.const 0))) - (local.set 0x16d (i64.load offset=0x16d align=1 (i32.const 0))) - (local.set 0x16e (i64.load offset=0x16e align=1 (i32.const 0))) - (local.set 0x16f (i64.load offset=0x16f align=1 (i32.const 0))) - (local.set 0x170 (i64.load offset=0x170 align=1 (i32.const 0))) - (local.set 0x171 (i64.load offset=0x171 align=1 (i32.const 0))) - (local.set 0x172 (i64.load offset=0x172 align=1 (i32.const 0))) - (local.set 0x173 (i64.load offset=0x173 align=1 (i32.const 0))) - (local.set 0x174 (i64.load offset=0x174 align=1 (i32.const 0))) - (local.set 0x175 (i64.load offset=0x175 align=1 (i32.const 0))) - (local.set 0x176 (i64.load offset=0x176 align=1 (i32.const 0))) - (local.set 0x177 (i64.load offset=0x177 align=1 (i32.const 0))) - (local.set 0x178 (i64.load offset=0x178 align=1 (i32.const 0))) - (local.set 0x179 (i64.load offset=0x179 align=1 (i32.const 0))) - (local.set 0x17a (i64.load offset=0x17a align=1 (i32.const 0))) - (local.set 0x17b (i64.load offset=0x17b align=1 (i32.const 0))) - (local.set 0x17c (i64.load offset=0x17c align=1 (i32.const 0))) - (local.set 0x17d (i64.load offset=0x17d align=1 (i32.const 0))) - (local.set 0x17e (i64.load offset=0x17e align=1 (i32.const 0))) - (local.set 0x17f (i64.load offset=0x17f align=1 (i32.const 0))) - (local.set 0x180 (i64.load offset=0x180 align=1 (i32.const 0))) - (local.set 0x181 (i64.load offset=0x181 align=1 (i32.const 0))) - (local.set 0x182 (i64.load offset=0x182 align=1 (i32.const 0))) - (local.set 0x183 (i64.load offset=0x183 align=1 (i32.const 0))) - (local.set 0x184 (i64.load offset=0x184 align=1 (i32.const 0))) - (local.set 0x185 (i64.load offset=0x185 align=1 (i32.const 0))) - (local.set 0x186 (i64.load offset=0x186 align=1 (i32.const 0))) - (local.set 0x187 (i64.load offset=0x187 align=1 (i32.const 0))) - (local.set 0x188 (i64.load offset=0x188 align=1 (i32.const 0))) - (local.set 0x189 (i64.load offset=0x189 align=1 (i32.const 0))) - (local.set 0x18a (i64.load offset=0x18a align=1 (i32.const 0))) - (local.set 0x18b (i64.load offset=0x18b align=1 (i32.const 0))) - (local.set 0x18c (i64.load offset=0x18c align=1 (i32.const 0))) - (local.set 0x18d (i64.load offset=0x18d align=1 (i32.const 0))) - (local.set 0x18e (i64.load offset=0x18e align=1 (i32.const 0))) - (local.set 0x18f (i64.load offset=0x18f align=1 (i32.const 0))) - (local.set 0x190 (i64.load offset=0x190 align=1 (i32.const 0))) - (local.set 0x191 (i64.load offset=0x191 align=1 (i32.const 0))) - (local.set 0x192 (i64.load offset=0x192 align=1 (i32.const 0))) - (local.set 0x193 (i64.load offset=0x193 align=1 (i32.const 0))) - (local.set 0x194 (i64.load offset=0x194 align=1 (i32.const 0))) - (local.set 0x195 (i64.load offset=0x195 align=1 (i32.const 0))) - (local.set 0x196 (i64.load offset=0x196 align=1 (i32.const 0))) - (local.set 0x197 (i64.load offset=0x197 align=1 (i32.const 0))) - (local.set 0x198 (i64.load offset=0x198 align=1 (i32.const 0))) - (local.set 0x199 (i64.load offset=0x199 align=1 (i32.const 0))) - (local.set 0x19a (i64.load offset=0x19a align=1 (i32.const 0))) - (local.set 0x19b (i64.load offset=0x19b align=1 (i32.const 0))) - (local.set 0x19c (i64.load offset=0x19c align=1 (i32.const 0))) - (local.set 0x19d (i64.load offset=0x19d align=1 (i32.const 0))) - (local.set 0x19e (i64.load offset=0x19e align=1 (i32.const 0))) - (local.set 0x19f (i64.load offset=0x19f align=1 (i32.const 0))) - (local.set 0x1a0 (i64.load offset=0x1a0 align=1 (i32.const 0))) - (local.set 0x1a1 (i64.load offset=0x1a1 align=1 (i32.const 0))) - (local.set 0x1a2 (i64.load offset=0x1a2 align=1 (i32.const 0))) - (local.set 0x1a3 (i64.load offset=0x1a3 align=1 (i32.const 0))) - (local.set 0x1a4 (i64.load offset=0x1a4 align=1 (i32.const 0))) - (local.set 0x1a5 (i64.load offset=0x1a5 align=1 (i32.const 0))) - (local.set 0x1a6 (i64.load offset=0x1a6 align=1 (i32.const 0))) - (local.set 0x1a7 (i64.load offset=0x1a7 align=1 (i32.const 0))) - (local.set 0x1a8 (i64.load offset=0x1a8 align=1 (i32.const 0))) - (local.set 0x1a9 (i64.load offset=0x1a9 align=1 (i32.const 0))) - (local.set 0x1aa (i64.load offset=0x1aa align=1 (i32.const 0))) - (local.set 0x1ab (i64.load offset=0x1ab align=1 (i32.const 0))) - (local.set 0x1ac (i64.load offset=0x1ac align=1 (i32.const 0))) - (local.set 0x1ad (i64.load offset=0x1ad align=1 (i32.const 0))) - (local.set 0x1ae (i64.load offset=0x1ae align=1 (i32.const 0))) - (local.set 0x1af (i64.load offset=0x1af align=1 (i32.const 0))) - (local.set 0x1b0 (i64.load offset=0x1b0 align=1 (i32.const 0))) - (local.set 0x1b1 (i64.load offset=0x1b1 align=1 (i32.const 0))) - (local.set 0x1b2 (i64.load offset=0x1b2 align=1 (i32.const 0))) - (local.set 0x1b3 (i64.load offset=0x1b3 align=1 (i32.const 0))) - (local.set 0x1b4 (i64.load offset=0x1b4 align=1 (i32.const 0))) - (local.set 0x1b5 (i64.load offset=0x1b5 align=1 (i32.const 0))) - (local.set 0x1b6 (i64.load offset=0x1b6 align=1 (i32.const 0))) - (local.set 0x1b7 (i64.load offset=0x1b7 align=1 (i32.const 0))) - (local.set 0x1b8 (i64.load offset=0x1b8 align=1 (i32.const 0))) - (local.set 0x1b9 (i64.load offset=0x1b9 align=1 (i32.const 0))) - (local.set 0x1ba (i64.load offset=0x1ba align=1 (i32.const 0))) - (local.set 0x1bb (i64.load offset=0x1bb align=1 (i32.const 0))) - (local.set 0x1bc (i64.load offset=0x1bc align=1 (i32.const 0))) - (local.set 0x1bd (i64.load offset=0x1bd align=1 (i32.const 0))) - (local.set 0x1be (i64.load offset=0x1be align=1 (i32.const 0))) - (local.set 0x1bf (i64.load offset=0x1bf align=1 (i32.const 0))) - (local.set 0x1c0 (i64.load offset=0x1c0 align=1 (i32.const 0))) - (local.set 0x1c1 (i64.load offset=0x1c1 align=1 (i32.const 0))) - (local.set 0x1c2 (i64.load offset=0x1c2 align=1 (i32.const 0))) - (local.set 0x1c3 (i64.load offset=0x1c3 align=1 (i32.const 0))) - (local.set 0x1c4 (i64.load offset=0x1c4 align=1 (i32.const 0))) - (local.set 0x1c5 (i64.load offset=0x1c5 align=1 (i32.const 0))) - (local.set 0x1c6 (i64.load offset=0x1c6 align=1 (i32.const 0))) - (local.set 0x1c7 (i64.load offset=0x1c7 align=1 (i32.const 0))) - (local.set 0x1c8 (i64.load offset=0x1c8 align=1 (i32.const 0))) - (local.set 0x1c9 (i64.load offset=0x1c9 align=1 (i32.const 0))) - (local.set 0x1ca (i64.load offset=0x1ca align=1 (i32.const 0))) - (local.set 0x1cb (i64.load offset=0x1cb align=1 (i32.const 0))) - (local.set 0x1cc (i64.load offset=0x1cc align=1 (i32.const 0))) - (local.set 0x1cd (i64.load offset=0x1cd align=1 (i32.const 0))) - (local.set 0x1ce (i64.load offset=0x1ce align=1 (i32.const 0))) - (local.set 0x1cf (i64.load offset=0x1cf align=1 (i32.const 0))) - (local.set 0x1d0 (i64.load offset=0x1d0 align=1 (i32.const 0))) - (local.set 0x1d1 (i64.load offset=0x1d1 align=1 (i32.const 0))) - (local.set 0x1d2 (i64.load offset=0x1d2 align=1 (i32.const 0))) - (local.set 0x1d3 (i64.load offset=0x1d3 align=1 (i32.const 0))) - (local.set 0x1d4 (i64.load offset=0x1d4 align=1 (i32.const 0))) - (local.set 0x1d5 (i64.load offset=0x1d5 align=1 (i32.const 0))) - (local.set 0x1d6 (i64.load offset=0x1d6 align=1 (i32.const 0))) - (local.set 0x1d7 (i64.load offset=0x1d7 align=1 (i32.const 0))) - (local.set 0x1d8 (i64.load offset=0x1d8 align=1 (i32.const 0))) - (local.set 0x1d9 (i64.load offset=0x1d9 align=1 (i32.const 0))) - (local.set 0x1da (i64.load offset=0x1da align=1 (i32.const 0))) - (local.set 0x1db (i64.load offset=0x1db align=1 (i32.const 0))) - (local.set 0x1dc (i64.load offset=0x1dc align=1 (i32.const 0))) - (local.set 0x1dd (i64.load offset=0x1dd align=1 (i32.const 0))) - (local.set 0x1de (i64.load offset=0x1de align=1 (i32.const 0))) - (local.set 0x1df (i64.load offset=0x1df align=1 (i32.const 0))) - (local.set 0x1e0 (i64.load offset=0x1e0 align=1 (i32.const 0))) - (local.set 0x1e1 (i64.load offset=0x1e1 align=1 (i32.const 0))) - (local.set 0x1e2 (i64.load offset=0x1e2 align=1 (i32.const 0))) - (local.set 0x1e3 (i64.load offset=0x1e3 align=1 (i32.const 0))) - (local.set 0x1e4 (i64.load offset=0x1e4 align=1 (i32.const 0))) - (local.set 0x1e5 (i64.load offset=0x1e5 align=1 (i32.const 0))) - (local.set 0x1e6 (i64.load offset=0x1e6 align=1 (i32.const 0))) - (local.set 0x1e7 (i64.load offset=0x1e7 align=1 (i32.const 0))) - (local.set 0x1e8 (i64.load offset=0x1e8 align=1 (i32.const 0))) - (local.set 0x1e9 (i64.load offset=0x1e9 align=1 (i32.const 0))) - (local.set 0x1ea (i64.load offset=0x1ea align=1 (i32.const 0))) - (local.set 0x1eb (i64.load offset=0x1eb align=1 (i32.const 0))) - (local.set 0x1ec (i64.load offset=0x1ec align=1 (i32.const 0))) - (local.set 0x1ed (i64.load offset=0x1ed align=1 (i32.const 0))) - (local.set 0x1ee (i64.load offset=0x1ee align=1 (i32.const 0))) - (local.set 0x1ef (i64.load offset=0x1ef align=1 (i32.const 0))) - (local.set 0x1f0 (i64.load offset=0x1f0 align=1 (i32.const 0))) - (local.set 0x1f1 (i64.load offset=0x1f1 align=1 (i32.const 0))) - (local.set 0x1f2 (i64.load offset=0x1f2 align=1 (i32.const 0))) - (local.set 0x1f3 (i64.load offset=0x1f3 align=1 (i32.const 0))) - (local.set 0x1f4 (i64.load offset=0x1f4 align=1 (i32.const 0))) - (local.set 0x1f5 (i64.load offset=0x1f5 align=1 (i32.const 0))) - (local.set 0x1f6 (i64.load offset=0x1f6 align=1 (i32.const 0))) - (local.set 0x1f7 (i64.load offset=0x1f7 align=1 (i32.const 0))) - (local.set 0x1f8 (i64.load offset=0x1f8 align=1 (i32.const 0))) - (local.set 0x1f9 (i64.load offset=0x1f9 align=1 (i32.const 0))) - (local.set 0x1fa (i64.load offset=0x1fa align=1 (i32.const 0))) - (local.set 0x1fb (i64.load offset=0x1fb align=1 (i32.const 0))) - (local.set 0x1fc (i64.load offset=0x1fc align=1 (i32.const 0))) - (local.set 0x1fd (i64.load offset=0x1fd align=1 (i32.const 0))) - (local.set 0x1fe (i64.load offset=0x1fe align=1 (i32.const 0))) - (local.set 0x1ff (i64.load offset=0x1ff align=1 (i32.const 0))) - (local.set 0x200 (i64.load offset=0x200 align=1 (i32.const 0))) - (local.set 0x201 (i64.load offset=0x201 align=1 (i32.const 0))) - (local.set 0x202 (i64.load offset=0x202 align=1 (i32.const 0))) - (local.set 0x203 (i64.load offset=0x203 align=1 (i32.const 0))) - (local.set 0x204 (i64.load offset=0x204 align=1 (i32.const 0))) - (local.set 0x205 (i64.load offset=0x205 align=1 (i32.const 0))) - (local.set 0x206 (i64.load offset=0x206 align=1 (i32.const 0))) - (local.set 0x207 (i64.load offset=0x207 align=1 (i32.const 0))) - (local.set 0x208 (i64.load offset=0x208 align=1 (i32.const 0))) - (local.set 0x209 (i64.load offset=0x209 align=1 (i32.const 0))) - (local.set 0x20a (i64.load offset=0x20a align=1 (i32.const 0))) - (local.set 0x20b (i64.load offset=0x20b align=1 (i32.const 0))) - (local.set 0x20c (i64.load offset=0x20c align=1 (i32.const 0))) - (local.set 0x20d (i64.load offset=0x20d align=1 (i32.const 0))) - (local.set 0x20e (i64.load offset=0x20e align=1 (i32.const 0))) - (local.set 0x20f (i64.load offset=0x20f align=1 (i32.const 0))) - (local.set 0x210 (i64.load offset=0x210 align=1 (i32.const 0))) - (local.set 0x211 (i64.load offset=0x211 align=1 (i32.const 0))) - (local.set 0x212 (i64.load offset=0x212 align=1 (i32.const 0))) - (local.set 0x213 (i64.load offset=0x213 align=1 (i32.const 0))) - (local.set 0x214 (i64.load offset=0x214 align=1 (i32.const 0))) - (local.set 0x215 (i64.load offset=0x215 align=1 (i32.const 0))) - (local.set 0x216 (i64.load offset=0x216 align=1 (i32.const 0))) - (local.set 0x217 (i64.load offset=0x217 align=1 (i32.const 0))) - (local.set 0x218 (i64.load offset=0x218 align=1 (i32.const 0))) - (local.set 0x219 (i64.load offset=0x219 align=1 (i32.const 0))) - (local.set 0x21a (i64.load offset=0x21a align=1 (i32.const 0))) - (local.set 0x21b (i64.load offset=0x21b align=1 (i32.const 0))) - (local.set 0x21c (i64.load offset=0x21c align=1 (i32.const 0))) - (local.set 0x21d (i64.load offset=0x21d align=1 (i32.const 0))) - (local.set 0x21e (i64.load offset=0x21e align=1 (i32.const 0))) - (local.set 0x21f (i64.load offset=0x21f align=1 (i32.const 0))) - (local.set 0x220 (i64.load offset=0x220 align=1 (i32.const 0))) - (local.set 0x221 (i64.load offset=0x221 align=1 (i32.const 0))) - (local.set 0x222 (i64.load offset=0x222 align=1 (i32.const 0))) - (local.set 0x223 (i64.load offset=0x223 align=1 (i32.const 0))) - (local.set 0x224 (i64.load offset=0x224 align=1 (i32.const 0))) - (local.set 0x225 (i64.load offset=0x225 align=1 (i32.const 0))) - (local.set 0x226 (i64.load offset=0x226 align=1 (i32.const 0))) - (local.set 0x227 (i64.load offset=0x227 align=1 (i32.const 0))) - (local.set 0x228 (i64.load offset=0x228 align=1 (i32.const 0))) - (local.set 0x229 (i64.load offset=0x229 align=1 (i32.const 0))) - (local.set 0x22a (i64.load offset=0x22a align=1 (i32.const 0))) - (local.set 0x22b (i64.load offset=0x22b align=1 (i32.const 0))) - (local.set 0x22c (i64.load offset=0x22c align=1 (i32.const 0))) - (local.set 0x22d (i64.load offset=0x22d align=1 (i32.const 0))) - (local.set 0x22e (i64.load offset=0x22e align=1 (i32.const 0))) - (local.set 0x22f (i64.load offset=0x22f align=1 (i32.const 0))) - (local.set 0x230 (i64.load offset=0x230 align=1 (i32.const 0))) - (local.set 0x231 (i64.load offset=0x231 align=1 (i32.const 0))) - (local.set 0x232 (i64.load offset=0x232 align=1 (i32.const 0))) - (local.set 0x233 (i64.load offset=0x233 align=1 (i32.const 0))) - (local.set 0x234 (i64.load offset=0x234 align=1 (i32.const 0))) - (local.set 0x235 (i64.load offset=0x235 align=1 (i32.const 0))) - (local.set 0x236 (i64.load offset=0x236 align=1 (i32.const 0))) - (local.set 0x237 (i64.load offset=0x237 align=1 (i32.const 0))) - (local.set 0x238 (i64.load offset=0x238 align=1 (i32.const 0))) - (local.set 0x239 (i64.load offset=0x239 align=1 (i32.const 0))) - (local.set 0x23a (i64.load offset=0x23a align=1 (i32.const 0))) - (local.set 0x23b (i64.load offset=0x23b align=1 (i32.const 0))) - (local.set 0x23c (i64.load offset=0x23c align=1 (i32.const 0))) - (local.set 0x23d (i64.load offset=0x23d align=1 (i32.const 0))) - (local.set 0x23e (i64.load offset=0x23e align=1 (i32.const 0))) - (local.set 0x23f (i64.load offset=0x23f align=1 (i32.const 0))) - (local.set 0x240 (i64.load offset=0x240 align=1 (i32.const 0))) - (local.set 0x241 (i64.load offset=0x241 align=1 (i32.const 0))) - (local.set 0x242 (i64.load offset=0x242 align=1 (i32.const 0))) - (local.set 0x243 (i64.load offset=0x243 align=1 (i32.const 0))) - (local.set 0x244 (i64.load offset=0x244 align=1 (i32.const 0))) - (local.set 0x245 (i64.load offset=0x245 align=1 (i32.const 0))) - (local.set 0x246 (i64.load offset=0x246 align=1 (i32.const 0))) - (local.set 0x247 (i64.load offset=0x247 align=1 (i32.const 0))) - (local.set 0x248 (i64.load offset=0x248 align=1 (i32.const 0))) - (local.set 0x249 (i64.load offset=0x249 align=1 (i32.const 0))) - (local.set 0x24a (i64.load offset=0x24a align=1 (i32.const 0))) - (local.set 0x24b (i64.load offset=0x24b align=1 (i32.const 0))) - (local.set 0x24c (i64.load offset=0x24c align=1 (i32.const 0))) - (local.set 0x24d (i64.load offset=0x24d align=1 (i32.const 0))) - (local.set 0x24e (i64.load offset=0x24e align=1 (i32.const 0))) - (local.set 0x24f (i64.load offset=0x24f align=1 (i32.const 0))) - (local.set 0x250 (i64.load offset=0x250 align=1 (i32.const 0))) - (local.set 0x251 (i64.load offset=0x251 align=1 (i32.const 0))) - (local.set 0x252 (i64.load offset=0x252 align=1 (i32.const 0))) - (local.set 0x253 (i64.load offset=0x253 align=1 (i32.const 0))) - (local.set 0x254 (i64.load offset=0x254 align=1 (i32.const 0))) - (local.set 0x255 (i64.load offset=0x255 align=1 (i32.const 0))) - (local.set 0x256 (i64.load offset=0x256 align=1 (i32.const 0))) - (local.set 0x257 (i64.load offset=0x257 align=1 (i32.const 0))) - (local.set 0x258 (i64.load offset=0x258 align=1 (i32.const 0))) - (local.set 0x259 (i64.load offset=0x259 align=1 (i32.const 0))) - (local.set 0x25a (i64.load offset=0x25a align=1 (i32.const 0))) - (local.set 0x25b (i64.load offset=0x25b align=1 (i32.const 0))) - (local.set 0x25c (i64.load offset=0x25c align=1 (i32.const 0))) - (local.set 0x25d (i64.load offset=0x25d align=1 (i32.const 0))) - (local.set 0x25e (i64.load offset=0x25e align=1 (i32.const 0))) - (local.set 0x25f (i64.load offset=0x25f align=1 (i32.const 0))) - (local.set 0x260 (i64.load offset=0x260 align=1 (i32.const 0))) - (local.set 0x261 (i64.load offset=0x261 align=1 (i32.const 0))) - (local.set 0x262 (i64.load offset=0x262 align=1 (i32.const 0))) - (local.set 0x263 (i64.load offset=0x263 align=1 (i32.const 0))) - (local.set 0x264 (i64.load offset=0x264 align=1 (i32.const 0))) - (local.set 0x265 (i64.load offset=0x265 align=1 (i32.const 0))) - (local.set 0x266 (i64.load offset=0x266 align=1 (i32.const 0))) - (local.set 0x267 (i64.load offset=0x267 align=1 (i32.const 0))) - (local.set 0x268 (i64.load offset=0x268 align=1 (i32.const 0))) - (local.set 0x269 (i64.load offset=0x269 align=1 (i32.const 0))) - (local.set 0x26a (i64.load offset=0x26a align=1 (i32.const 0))) - (local.set 0x26b (i64.load offset=0x26b align=1 (i32.const 0))) - (local.set 0x26c (i64.load offset=0x26c align=1 (i32.const 0))) - (local.set 0x26d (i64.load offset=0x26d align=1 (i32.const 0))) - (local.set 0x26e (i64.load offset=0x26e align=1 (i32.const 0))) - (local.set 0x26f (i64.load offset=0x26f align=1 (i32.const 0))) - (local.set 0x270 (i64.load offset=0x270 align=1 (i32.const 0))) - (local.set 0x271 (i64.load offset=0x271 align=1 (i32.const 0))) - (local.set 0x272 (i64.load offset=0x272 align=1 (i32.const 0))) - (local.set 0x273 (i64.load offset=0x273 align=1 (i32.const 0))) - (local.set 0x274 (i64.load offset=0x274 align=1 (i32.const 0))) - (local.set 0x275 (i64.load offset=0x275 align=1 (i32.const 0))) - (local.set 0x276 (i64.load offset=0x276 align=1 (i32.const 0))) - (local.set 0x277 (i64.load offset=0x277 align=1 (i32.const 0))) - (local.set 0x278 (i64.load offset=0x278 align=1 (i32.const 0))) - (local.set 0x279 (i64.load offset=0x279 align=1 (i32.const 0))) - (local.set 0x27a (i64.load offset=0x27a align=1 (i32.const 0))) - (local.set 0x27b (i64.load offset=0x27b align=1 (i32.const 0))) - (local.set 0x27c (i64.load offset=0x27c align=1 (i32.const 0))) - (local.set 0x27d (i64.load offset=0x27d align=1 (i32.const 0))) - (local.set 0x27e (i64.load offset=0x27e align=1 (i32.const 0))) - (local.set 0x27f (i64.load offset=0x27f align=1 (i32.const 0))) - (local.set 0x280 (i64.load offset=0x280 align=1 (i32.const 0))) - (local.set 0x281 (i64.load offset=0x281 align=1 (i32.const 0))) - (local.set 0x282 (i64.load offset=0x282 align=1 (i32.const 0))) - (local.set 0x283 (i64.load offset=0x283 align=1 (i32.const 0))) - (local.set 0x284 (i64.load offset=0x284 align=1 (i32.const 0))) - (local.set 0x285 (i64.load offset=0x285 align=1 (i32.const 0))) - (local.set 0x286 (i64.load offset=0x286 align=1 (i32.const 0))) - (local.set 0x287 (i64.load offset=0x287 align=1 (i32.const 0))) - (local.set 0x288 (i64.load offset=0x288 align=1 (i32.const 0))) - (local.set 0x289 (i64.load offset=0x289 align=1 (i32.const 0))) - (local.set 0x28a (i64.load offset=0x28a align=1 (i32.const 0))) - (local.set 0x28b (i64.load offset=0x28b align=1 (i32.const 0))) - (local.set 0x28c (i64.load offset=0x28c align=1 (i32.const 0))) - (local.set 0x28d (i64.load offset=0x28d align=1 (i32.const 0))) - (local.set 0x28e (i64.load offset=0x28e align=1 (i32.const 0))) - (local.set 0x28f (i64.load offset=0x28f align=1 (i32.const 0))) - (local.set 0x290 (i64.load offset=0x290 align=1 (i32.const 0))) - (local.set 0x291 (i64.load offset=0x291 align=1 (i32.const 0))) - (local.set 0x292 (i64.load offset=0x292 align=1 (i32.const 0))) - (local.set 0x293 (i64.load offset=0x293 align=1 (i32.const 0))) - (local.set 0x294 (i64.load offset=0x294 align=1 (i32.const 0))) - (local.set 0x295 (i64.load offset=0x295 align=1 (i32.const 0))) - (local.set 0x296 (i64.load offset=0x296 align=1 (i32.const 0))) - (local.set 0x297 (i64.load offset=0x297 align=1 (i32.const 0))) - (local.set 0x298 (i64.load offset=0x298 align=1 (i32.const 0))) - (local.set 0x299 (i64.load offset=0x299 align=1 (i32.const 0))) - (local.set 0x29a (i64.load offset=0x29a align=1 (i32.const 0))) - (local.set 0x29b (i64.load offset=0x29b align=1 (i32.const 0))) - (local.set 0x29c (i64.load offset=0x29c align=1 (i32.const 0))) - (local.set 0x29d (i64.load offset=0x29d align=1 (i32.const 0))) - (local.set 0x29e (i64.load offset=0x29e align=1 (i32.const 0))) - (local.set 0x29f (i64.load offset=0x29f align=1 (i32.const 0))) - (local.set 0x2a0 (i64.load offset=0x2a0 align=1 (i32.const 0))) - (local.set 0x2a1 (i64.load offset=0x2a1 align=1 (i32.const 0))) - (local.set 0x2a2 (i64.load offset=0x2a2 align=1 (i32.const 0))) - (local.set 0x2a3 (i64.load offset=0x2a3 align=1 (i32.const 0))) - (local.set 0x2a4 (i64.load offset=0x2a4 align=1 (i32.const 0))) - (local.set 0x2a5 (i64.load offset=0x2a5 align=1 (i32.const 0))) - (local.set 0x2a6 (i64.load offset=0x2a6 align=1 (i32.const 0))) - (local.set 0x2a7 (i64.load offset=0x2a7 align=1 (i32.const 0))) - (local.set 0x2a8 (i64.load offset=0x2a8 align=1 (i32.const 0))) - (local.set 0x2a9 (i64.load offset=0x2a9 align=1 (i32.const 0))) - (local.set 0x2aa (i64.load offset=0x2aa align=1 (i32.const 0))) - (local.set 0x2ab (i64.load offset=0x2ab align=1 (i32.const 0))) - (local.set 0x2ac (i64.load offset=0x2ac align=1 (i32.const 0))) - (local.set 0x2ad (i64.load offset=0x2ad align=1 (i32.const 0))) - (local.set 0x2ae (i64.load offset=0x2ae align=1 (i32.const 0))) - (local.set 0x2af (i64.load offset=0x2af align=1 (i32.const 0))) - (local.set 0x2b0 (i64.load offset=0x2b0 align=1 (i32.const 0))) - (local.set 0x2b1 (i64.load offset=0x2b1 align=1 (i32.const 0))) - (local.set 0x2b2 (i64.load offset=0x2b2 align=1 (i32.const 0))) - (local.set 0x2b3 (i64.load offset=0x2b3 align=1 (i32.const 0))) - (local.set 0x2b4 (i64.load offset=0x2b4 align=1 (i32.const 0))) - (local.set 0x2b5 (i64.load offset=0x2b5 align=1 (i32.const 0))) - (local.set 0x2b6 (i64.load offset=0x2b6 align=1 (i32.const 0))) - (local.set 0x2b7 (i64.load offset=0x2b7 align=1 (i32.const 0))) - (local.set 0x2b8 (i64.load offset=0x2b8 align=1 (i32.const 0))) - (local.set 0x2b9 (i64.load offset=0x2b9 align=1 (i32.const 0))) - (local.set 0x2ba (i64.load offset=0x2ba align=1 (i32.const 0))) - (local.set 0x2bb (i64.load offset=0x2bb align=1 (i32.const 0))) - (local.set 0x2bc (i64.load offset=0x2bc align=1 (i32.const 0))) - (local.set 0x2bd (i64.load offset=0x2bd align=1 (i32.const 0))) - (local.set 0x2be (i64.load offset=0x2be align=1 (i32.const 0))) - (local.set 0x2bf (i64.load offset=0x2bf align=1 (i32.const 0))) - (local.set 0x2c0 (i64.load offset=0x2c0 align=1 (i32.const 0))) - (local.set 0x2c1 (i64.load offset=0x2c1 align=1 (i32.const 0))) - (local.set 0x2c2 (i64.load offset=0x2c2 align=1 (i32.const 0))) - (local.set 0x2c3 (i64.load offset=0x2c3 align=1 (i32.const 0))) - (local.set 0x2c4 (i64.load offset=0x2c4 align=1 (i32.const 0))) - (local.set 0x2c5 (i64.load offset=0x2c5 align=1 (i32.const 0))) - (local.set 0x2c6 (i64.load offset=0x2c6 align=1 (i32.const 0))) - (local.set 0x2c7 (i64.load offset=0x2c7 align=1 (i32.const 0))) - (local.set 0x2c8 (i64.load offset=0x2c8 align=1 (i32.const 0))) - (local.set 0x2c9 (i64.load offset=0x2c9 align=1 (i32.const 0))) - (local.set 0x2ca (i64.load offset=0x2ca align=1 (i32.const 0))) - (local.set 0x2cb (i64.load offset=0x2cb align=1 (i32.const 0))) - (local.set 0x2cc (i64.load offset=0x2cc align=1 (i32.const 0))) - (local.set 0x2cd (i64.load offset=0x2cd align=1 (i32.const 0))) - (local.set 0x2ce (i64.load offset=0x2ce align=1 (i32.const 0))) - (local.set 0x2cf (i64.load offset=0x2cf align=1 (i32.const 0))) - (local.set 0x2d0 (i64.load offset=0x2d0 align=1 (i32.const 0))) - (local.set 0x2d1 (i64.load offset=0x2d1 align=1 (i32.const 0))) - (local.set 0x2d2 (i64.load offset=0x2d2 align=1 (i32.const 0))) - (local.set 0x2d3 (i64.load offset=0x2d3 align=1 (i32.const 0))) - (local.set 0x2d4 (i64.load offset=0x2d4 align=1 (i32.const 0))) - (local.set 0x2d5 (i64.load offset=0x2d5 align=1 (i32.const 0))) - (local.set 0x2d6 (i64.load offset=0x2d6 align=1 (i32.const 0))) - (local.set 0x2d7 (i64.load offset=0x2d7 align=1 (i32.const 0))) - (local.set 0x2d8 (i64.load offset=0x2d8 align=1 (i32.const 0))) - (local.set 0x2d9 (i64.load offset=0x2d9 align=1 (i32.const 0))) - (local.set 0x2da (i64.load offset=0x2da align=1 (i32.const 0))) - (local.set 0x2db (i64.load offset=0x2db align=1 (i32.const 0))) - (local.set 0x2dc (i64.load offset=0x2dc align=1 (i32.const 0))) - (local.set 0x2dd (i64.load offset=0x2dd align=1 (i32.const 0))) - (local.set 0x2de (i64.load offset=0x2de align=1 (i32.const 0))) - (local.set 0x2df (i64.load offset=0x2df align=1 (i32.const 0))) - (local.set 0x2e0 (i64.load offset=0x2e0 align=1 (i32.const 0))) - (local.set 0x2e1 (i64.load offset=0x2e1 align=1 (i32.const 0))) - (local.set 0x2e2 (i64.load offset=0x2e2 align=1 (i32.const 0))) - (local.set 0x2e3 (i64.load offset=0x2e3 align=1 (i32.const 0))) - (local.set 0x2e4 (i64.load offset=0x2e4 align=1 (i32.const 0))) - (local.set 0x2e5 (i64.load offset=0x2e5 align=1 (i32.const 0))) - (local.set 0x2e6 (i64.load offset=0x2e6 align=1 (i32.const 0))) - (local.set 0x2e7 (i64.load offset=0x2e7 align=1 (i32.const 0))) - (local.set 0x2e8 (i64.load offset=0x2e8 align=1 (i32.const 0))) - (local.set 0x2e9 (i64.load offset=0x2e9 align=1 (i32.const 0))) - (local.set 0x2ea (i64.load offset=0x2ea align=1 (i32.const 0))) - (local.set 0x2eb (i64.load offset=0x2eb align=1 (i32.const 0))) - (local.set 0x2ec (i64.load offset=0x2ec align=1 (i32.const 0))) - (local.set 0x2ed (i64.load offset=0x2ed align=1 (i32.const 0))) - (local.set 0x2ee (i64.load offset=0x2ee align=1 (i32.const 0))) - (local.set 0x2ef (i64.load offset=0x2ef align=1 (i32.const 0))) - (local.set 0x2f0 (i64.load offset=0x2f0 align=1 (i32.const 0))) - (local.set 0x2f1 (i64.load offset=0x2f1 align=1 (i32.const 0))) - (local.set 0x2f2 (i64.load offset=0x2f2 align=1 (i32.const 0))) - (local.set 0x2f3 (i64.load offset=0x2f3 align=1 (i32.const 0))) - (local.set 0x2f4 (i64.load offset=0x2f4 align=1 (i32.const 0))) - (local.set 0x2f5 (i64.load offset=0x2f5 align=1 (i32.const 0))) - (local.set 0x2f6 (i64.load offset=0x2f6 align=1 (i32.const 0))) - (local.set 0x2f7 (i64.load offset=0x2f7 align=1 (i32.const 0))) - (local.set 0x2f8 (i64.load offset=0x2f8 align=1 (i32.const 0))) - (local.set 0x2f9 (i64.load offset=0x2f9 align=1 (i32.const 0))) - (local.set 0x2fa (i64.load offset=0x2fa align=1 (i32.const 0))) - (local.set 0x2fb (i64.load offset=0x2fb align=1 (i32.const 0))) - (local.set 0x2fc (i64.load offset=0x2fc align=1 (i32.const 0))) - (local.set 0x2fd (i64.load offset=0x2fd align=1 (i32.const 0))) - (local.set 0x2fe (i64.load offset=0x2fe align=1 (i32.const 0))) - (local.set 0x2ff (i64.load offset=0x2ff align=1 (i32.const 0))) - (local.set 0x300 (i64.load offset=0x300 align=1 (i32.const 0))) - (local.set 0x301 (i64.load offset=0x301 align=1 (i32.const 0))) - (local.set 0x302 (i64.load offset=0x302 align=1 (i32.const 0))) - (local.set 0x303 (i64.load offset=0x303 align=1 (i32.const 0))) - (local.set 0x304 (i64.load offset=0x304 align=1 (i32.const 0))) - (local.set 0x305 (i64.load offset=0x305 align=1 (i32.const 0))) - (local.set 0x306 (i64.load offset=0x306 align=1 (i32.const 0))) - (local.set 0x307 (i64.load offset=0x307 align=1 (i32.const 0))) - (local.set 0x308 (i64.load offset=0x308 align=1 (i32.const 0))) - (local.set 0x309 (i64.load offset=0x309 align=1 (i32.const 0))) - (local.set 0x30a (i64.load offset=0x30a align=1 (i32.const 0))) - (local.set 0x30b (i64.load offset=0x30b align=1 (i32.const 0))) - (local.set 0x30c (i64.load offset=0x30c align=1 (i32.const 0))) - (local.set 0x30d (i64.load offset=0x30d align=1 (i32.const 0))) - (local.set 0x30e (i64.load offset=0x30e align=1 (i32.const 0))) - (local.set 0x30f (i64.load offset=0x30f align=1 (i32.const 0))) - (local.set 0x310 (i64.load offset=0x310 align=1 (i32.const 0))) - (local.set 0x311 (i64.load offset=0x311 align=1 (i32.const 0))) - (local.set 0x312 (i64.load offset=0x312 align=1 (i32.const 0))) - (local.set 0x313 (i64.load offset=0x313 align=1 (i32.const 0))) - (local.set 0x314 (i64.load offset=0x314 align=1 (i32.const 0))) - (local.set 0x315 (i64.load offset=0x315 align=1 (i32.const 0))) - (local.set 0x316 (i64.load offset=0x316 align=1 (i32.const 0))) - (local.set 0x317 (i64.load offset=0x317 align=1 (i32.const 0))) - (local.set 0x318 (i64.load offset=0x318 align=1 (i32.const 0))) - (local.set 0x319 (i64.load offset=0x319 align=1 (i32.const 0))) - (local.set 0x31a (i64.load offset=0x31a align=1 (i32.const 0))) - (local.set 0x31b (i64.load offset=0x31b align=1 (i32.const 0))) - (local.set 0x31c (i64.load offset=0x31c align=1 (i32.const 0))) - (local.set 0x31d (i64.load offset=0x31d align=1 (i32.const 0))) - (local.set 0x31e (i64.load offset=0x31e align=1 (i32.const 0))) - (local.set 0x31f (i64.load offset=0x31f align=1 (i32.const 0))) - (local.set 0x320 (i64.load offset=0x320 align=1 (i32.const 0))) - (local.set 0x321 (i64.load offset=0x321 align=1 (i32.const 0))) - (local.set 0x322 (i64.load offset=0x322 align=1 (i32.const 0))) - (local.set 0x323 (i64.load offset=0x323 align=1 (i32.const 0))) - (local.set 0x324 (i64.load offset=0x324 align=1 (i32.const 0))) - (local.set 0x325 (i64.load offset=0x325 align=1 (i32.const 0))) - (local.set 0x326 (i64.load offset=0x326 align=1 (i32.const 0))) - (local.set 0x327 (i64.load offset=0x327 align=1 (i32.const 0))) - (local.set 0x328 (i64.load offset=0x328 align=1 (i32.const 0))) - (local.set 0x329 (i64.load offset=0x329 align=1 (i32.const 0))) - (local.set 0x32a (i64.load offset=0x32a align=1 (i32.const 0))) - (local.set 0x32b (i64.load offset=0x32b align=1 (i32.const 0))) - (local.set 0x32c (i64.load offset=0x32c align=1 (i32.const 0))) - (local.set 0x32d (i64.load offset=0x32d align=1 (i32.const 0))) - (local.set 0x32e (i64.load offset=0x32e align=1 (i32.const 0))) - (local.set 0x32f (i64.load offset=0x32f align=1 (i32.const 0))) - (local.set 0x330 (i64.load offset=0x330 align=1 (i32.const 0))) - (local.set 0x331 (i64.load offset=0x331 align=1 (i32.const 0))) - (local.set 0x332 (i64.load offset=0x332 align=1 (i32.const 0))) - (local.set 0x333 (i64.load offset=0x333 align=1 (i32.const 0))) - (local.set 0x334 (i64.load offset=0x334 align=1 (i32.const 0))) - (local.set 0x335 (i64.load offset=0x335 align=1 (i32.const 0))) - (local.set 0x336 (i64.load offset=0x336 align=1 (i32.const 0))) - (local.set 0x337 (i64.load offset=0x337 align=1 (i32.const 0))) - (local.set 0x338 (i64.load offset=0x338 align=1 (i32.const 0))) - (local.set 0x339 (i64.load offset=0x339 align=1 (i32.const 0))) - (local.set 0x33a (i64.load offset=0x33a align=1 (i32.const 0))) - (local.set 0x33b (i64.load offset=0x33b align=1 (i32.const 0))) - (local.set 0x33c (i64.load offset=0x33c align=1 (i32.const 0))) - (local.set 0x33d (i64.load offset=0x33d align=1 (i32.const 0))) - (local.set 0x33e (i64.load offset=0x33e align=1 (i32.const 0))) - (local.set 0x33f (i64.load offset=0x33f align=1 (i32.const 0))) - (local.set 0x340 (i64.load offset=0x340 align=1 (i32.const 0))) - (local.set 0x341 (i64.load offset=0x341 align=1 (i32.const 0))) - (local.set 0x342 (i64.load offset=0x342 align=1 (i32.const 0))) - (local.set 0x343 (i64.load offset=0x343 align=1 (i32.const 0))) - (local.set 0x344 (i64.load offset=0x344 align=1 (i32.const 0))) - (local.set 0x345 (i64.load offset=0x345 align=1 (i32.const 0))) - (local.set 0x346 (i64.load offset=0x346 align=1 (i32.const 0))) - (local.set 0x347 (i64.load offset=0x347 align=1 (i32.const 0))) - (local.set 0x348 (i64.load offset=0x348 align=1 (i32.const 0))) - (local.set 0x349 (i64.load offset=0x349 align=1 (i32.const 0))) - (local.set 0x34a (i64.load offset=0x34a align=1 (i32.const 0))) - (local.set 0x34b (i64.load offset=0x34b align=1 (i32.const 0))) - (local.set 0x34c (i64.load offset=0x34c align=1 (i32.const 0))) - (local.set 0x34d (i64.load offset=0x34d align=1 (i32.const 0))) - (local.set 0x34e (i64.load offset=0x34e align=1 (i32.const 0))) - (local.set 0x34f (i64.load offset=0x34f align=1 (i32.const 0))) - (local.set 0x350 (i64.load offset=0x350 align=1 (i32.const 0))) - (local.set 0x351 (i64.load offset=0x351 align=1 (i32.const 0))) - (local.set 0x352 (i64.load offset=0x352 align=1 (i32.const 0))) - (local.set 0x353 (i64.load offset=0x353 align=1 (i32.const 0))) - (local.set 0x354 (i64.load offset=0x354 align=1 (i32.const 0))) - (local.set 0x355 (i64.load offset=0x355 align=1 (i32.const 0))) - (local.set 0x356 (i64.load offset=0x356 align=1 (i32.const 0))) - (local.set 0x357 (i64.load offset=0x357 align=1 (i32.const 0))) - (local.set 0x358 (i64.load offset=0x358 align=1 (i32.const 0))) - (local.set 0x359 (i64.load offset=0x359 align=1 (i32.const 0))) - (local.set 0x35a (i64.load offset=0x35a align=1 (i32.const 0))) - (local.set 0x35b (i64.load offset=0x35b align=1 (i32.const 0))) - (local.set 0x35c (i64.load offset=0x35c align=1 (i32.const 0))) - (local.set 0x35d (i64.load offset=0x35d align=1 (i32.const 0))) - (local.set 0x35e (i64.load offset=0x35e align=1 (i32.const 0))) - (local.set 0x35f (i64.load offset=0x35f align=1 (i32.const 0))) - (local.set 0x360 (i64.load offset=0x360 align=1 (i32.const 0))) - (local.set 0x361 (i64.load offset=0x361 align=1 (i32.const 0))) - (local.set 0x362 (i64.load offset=0x362 align=1 (i32.const 0))) - (local.set 0x363 (i64.load offset=0x363 align=1 (i32.const 0))) - (local.set 0x364 (i64.load offset=0x364 align=1 (i32.const 0))) - (local.set 0x365 (i64.load offset=0x365 align=1 (i32.const 0))) - (local.set 0x366 (i64.load offset=0x366 align=1 (i32.const 0))) - (local.set 0x367 (i64.load offset=0x367 align=1 (i32.const 0))) - (local.set 0x368 (i64.load offset=0x368 align=1 (i32.const 0))) - (local.set 0x369 (i64.load offset=0x369 align=1 (i32.const 0))) - (local.set 0x36a (i64.load offset=0x36a align=1 (i32.const 0))) - (local.set 0x36b (i64.load offset=0x36b align=1 (i32.const 0))) - (local.set 0x36c (i64.load offset=0x36c align=1 (i32.const 0))) - (local.set 0x36d (i64.load offset=0x36d align=1 (i32.const 0))) - (local.set 0x36e (i64.load offset=0x36e align=1 (i32.const 0))) - (local.set 0x36f (i64.load offset=0x36f align=1 (i32.const 0))) - (local.set 0x370 (i64.load offset=0x370 align=1 (i32.const 0))) - (local.set 0x371 (i64.load offset=0x371 align=1 (i32.const 0))) - (local.set 0x372 (i64.load offset=0x372 align=1 (i32.const 0))) - (local.set 0x373 (i64.load offset=0x373 align=1 (i32.const 0))) - (local.set 0x374 (i64.load offset=0x374 align=1 (i32.const 0))) - (local.set 0x375 (i64.load offset=0x375 align=1 (i32.const 0))) - (local.set 0x376 (i64.load offset=0x376 align=1 (i32.const 0))) - (local.set 0x377 (i64.load offset=0x377 align=1 (i32.const 0))) - (local.set 0x378 (i64.load offset=0x378 align=1 (i32.const 0))) - (local.set 0x379 (i64.load offset=0x379 align=1 (i32.const 0))) - (local.set 0x37a (i64.load offset=0x37a align=1 (i32.const 0))) - (local.set 0x37b (i64.load offset=0x37b align=1 (i32.const 0))) - (local.set 0x37c (i64.load offset=0x37c align=1 (i32.const 0))) - (local.set 0x37d (i64.load offset=0x37d align=1 (i32.const 0))) - (local.set 0x37e (i64.load offset=0x37e align=1 (i32.const 0))) - (local.set 0x37f (i64.load offset=0x37f align=1 (i32.const 0))) - (local.set 0x380 (i64.load offset=0x380 align=1 (i32.const 0))) - (local.set 0x381 (i64.load offset=0x381 align=1 (i32.const 0))) - (local.set 0x382 (i64.load offset=0x382 align=1 (i32.const 0))) - (local.set 0x383 (i64.load offset=0x383 align=1 (i32.const 0))) - (local.set 0x384 (i64.load offset=0x384 align=1 (i32.const 0))) - (local.set 0x385 (i64.load offset=0x385 align=1 (i32.const 0))) - (local.set 0x386 (i64.load offset=0x386 align=1 (i32.const 0))) - (local.set 0x387 (i64.load offset=0x387 align=1 (i32.const 0))) - (local.set 0x388 (i64.load offset=0x388 align=1 (i32.const 0))) - (local.set 0x389 (i64.load offset=0x389 align=1 (i32.const 0))) - (local.set 0x38a (i64.load offset=0x38a align=1 (i32.const 0))) - (local.set 0x38b (i64.load offset=0x38b align=1 (i32.const 0))) - (local.set 0x38c (i64.load offset=0x38c align=1 (i32.const 0))) - (local.set 0x38d (i64.load offset=0x38d align=1 (i32.const 0))) - (local.set 0x38e (i64.load offset=0x38e align=1 (i32.const 0))) - (local.set 0x38f (i64.load offset=0x38f align=1 (i32.const 0))) - (local.set 0x390 (i64.load offset=0x390 align=1 (i32.const 0))) - (local.set 0x391 (i64.load offset=0x391 align=1 (i32.const 0))) - (local.set 0x392 (i64.load offset=0x392 align=1 (i32.const 0))) - (local.set 0x393 (i64.load offset=0x393 align=1 (i32.const 0))) - (local.set 0x394 (i64.load offset=0x394 align=1 (i32.const 0))) - (local.set 0x395 (i64.load offset=0x395 align=1 (i32.const 0))) - (local.set 0x396 (i64.load offset=0x396 align=1 (i32.const 0))) - (local.set 0x397 (i64.load offset=0x397 align=1 (i32.const 0))) - (local.set 0x398 (i64.load offset=0x398 align=1 (i32.const 0))) - (local.set 0x399 (i64.load offset=0x399 align=1 (i32.const 0))) - (local.set 0x39a (i64.load offset=0x39a align=1 (i32.const 0))) - (local.set 0x39b (i64.load offset=0x39b align=1 (i32.const 0))) - (local.set 0x39c (i64.load offset=0x39c align=1 (i32.const 0))) - (local.set 0x39d (i64.load offset=0x39d align=1 (i32.const 0))) - (local.set 0x39e (i64.load offset=0x39e align=1 (i32.const 0))) - (local.set 0x39f (i64.load offset=0x39f align=1 (i32.const 0))) - (local.set 0x3a0 (i64.load offset=0x3a0 align=1 (i32.const 0))) - (local.set 0x3a1 (i64.load offset=0x3a1 align=1 (i32.const 0))) - (local.set 0x3a2 (i64.load offset=0x3a2 align=1 (i32.const 0))) - (local.set 0x3a3 (i64.load offset=0x3a3 align=1 (i32.const 0))) - (local.set 0x3a4 (i64.load offset=0x3a4 align=1 (i32.const 0))) - (local.set 0x3a5 (i64.load offset=0x3a5 align=1 (i32.const 0))) - (local.set 0x3a6 (i64.load offset=0x3a6 align=1 (i32.const 0))) - (local.set 0x3a7 (i64.load offset=0x3a7 align=1 (i32.const 0))) - (local.set 0x3a8 (i64.load offset=0x3a8 align=1 (i32.const 0))) - (local.set 0x3a9 (i64.load offset=0x3a9 align=1 (i32.const 0))) - (local.set 0x3aa (i64.load offset=0x3aa align=1 (i32.const 0))) - (local.set 0x3ab (i64.load offset=0x3ab align=1 (i32.const 0))) - (local.set 0x3ac (i64.load offset=0x3ac align=1 (i32.const 0))) - (local.set 0x3ad (i64.load offset=0x3ad align=1 (i32.const 0))) - (local.set 0x3ae (i64.load offset=0x3ae align=1 (i32.const 0))) - (local.set 0x3af (i64.load offset=0x3af align=1 (i32.const 0))) - (local.set 0x3b0 (i64.load offset=0x3b0 align=1 (i32.const 0))) - (local.set 0x3b1 (i64.load offset=0x3b1 align=1 (i32.const 0))) - (local.set 0x3b2 (i64.load offset=0x3b2 align=1 (i32.const 0))) - (local.set 0x3b3 (i64.load offset=0x3b3 align=1 (i32.const 0))) - (local.set 0x3b4 (i64.load offset=0x3b4 align=1 (i32.const 0))) - (local.set 0x3b5 (i64.load offset=0x3b5 align=1 (i32.const 0))) - (local.set 0x3b6 (i64.load offset=0x3b6 align=1 (i32.const 0))) - (local.set 0x3b7 (i64.load offset=0x3b7 align=1 (i32.const 0))) - (local.set 0x3b8 (i64.load offset=0x3b8 align=1 (i32.const 0))) - (local.set 0x3b9 (i64.load offset=0x3b9 align=1 (i32.const 0))) - (local.set 0x3ba (i64.load offset=0x3ba align=1 (i32.const 0))) - (local.set 0x3bb (i64.load offset=0x3bb align=1 (i32.const 0))) - (local.set 0x3bc (i64.load offset=0x3bc align=1 (i32.const 0))) - (local.set 0x3bd (i64.load offset=0x3bd align=1 (i32.const 0))) - (local.set 0x3be (i64.load offset=0x3be align=1 (i32.const 0))) - (local.set 0x3bf (i64.load offset=0x3bf align=1 (i32.const 0))) - (local.set 0x3c0 (i64.load offset=0x3c0 align=1 (i32.const 0))) - (local.set 0x3c1 (i64.load offset=0x3c1 align=1 (i32.const 0))) - (local.set 0x3c2 (i64.load offset=0x3c2 align=1 (i32.const 0))) - (local.set 0x3c3 (i64.load offset=0x3c3 align=1 (i32.const 0))) - (local.set 0x3c4 (i64.load offset=0x3c4 align=1 (i32.const 0))) - (local.set 0x3c5 (i64.load offset=0x3c5 align=1 (i32.const 0))) - (local.set 0x3c6 (i64.load offset=0x3c6 align=1 (i32.const 0))) - (local.set 0x3c7 (i64.load offset=0x3c7 align=1 (i32.const 0))) - (local.set 0x3c8 (i64.load offset=0x3c8 align=1 (i32.const 0))) - (local.set 0x3c9 (i64.load offset=0x3c9 align=1 (i32.const 0))) - (local.set 0x3ca (i64.load offset=0x3ca align=1 (i32.const 0))) - (local.set 0x3cb (i64.load offset=0x3cb align=1 (i32.const 0))) - (local.set 0x3cc (i64.load offset=0x3cc align=1 (i32.const 0))) - (local.set 0x3cd (i64.load offset=0x3cd align=1 (i32.const 0))) - (local.set 0x3ce (i64.load offset=0x3ce align=1 (i32.const 0))) - (local.set 0x3cf (i64.load offset=0x3cf align=1 (i32.const 0))) - (local.set 0x3d0 (i64.load offset=0x3d0 align=1 (i32.const 0))) - (local.set 0x3d1 (i64.load offset=0x3d1 align=1 (i32.const 0))) - (local.set 0x3d2 (i64.load offset=0x3d2 align=1 (i32.const 0))) - (local.set 0x3d3 (i64.load offset=0x3d3 align=1 (i32.const 0))) - (local.set 0x3d4 (i64.load offset=0x3d4 align=1 (i32.const 0))) - (local.set 0x3d5 (i64.load offset=0x3d5 align=1 (i32.const 0))) - (local.set 0x3d6 (i64.load offset=0x3d6 align=1 (i32.const 0))) - (local.set 0x3d7 (i64.load offset=0x3d7 align=1 (i32.const 0))) - (local.set 0x3d8 (i64.load offset=0x3d8 align=1 (i32.const 0))) - (local.set 0x3d9 (i64.load offset=0x3d9 align=1 (i32.const 0))) - (local.set 0x3da (i64.load offset=0x3da align=1 (i32.const 0))) - (local.set 0x3db (i64.load offset=0x3db align=1 (i32.const 0))) - (local.set 0x3dc (i64.load offset=0x3dc align=1 (i32.const 0))) - (local.set 0x3dd (i64.load offset=0x3dd align=1 (i32.const 0))) - (local.set 0x3de (i64.load offset=0x3de align=1 (i32.const 0))) - (local.set 0x3df (i64.load offset=0x3df align=1 (i32.const 0))) - (local.set 0x3e0 (i64.load offset=0x3e0 align=1 (i32.const 0))) - (local.set 0x3e1 (i64.load offset=0x3e1 align=1 (i32.const 0))) - (local.set 0x3e2 (i64.load offset=0x3e2 align=1 (i32.const 0))) - (local.set 0x3e3 (i64.load offset=0x3e3 align=1 (i32.const 0))) - (local.set 0x3e4 (i64.load offset=0x3e4 align=1 (i32.const 0))) - (local.set 0x3e5 (i64.load offset=0x3e5 align=1 (i32.const 0))) - (local.set 0x3e6 (i64.load offset=0x3e6 align=1 (i32.const 0))) - (local.set 0x3e7 (i64.load offset=0x3e7 align=1 (i32.const 0))) - (local.set 0x3e8 (i64.load offset=0x3e8 align=1 (i32.const 0))) - (local.set 0x3e9 (i64.load offset=0x3e9 align=1 (i32.const 0))) - (local.set 0x3ea (i64.load offset=0x3ea align=1 (i32.const 0))) - (local.set 0x3eb (i64.load offset=0x3eb align=1 (i32.const 0))) - (local.set 0x3ec (i64.load offset=0x3ec align=1 (i32.const 0))) - (local.set 0x3ed (i64.load offset=0x3ed align=1 (i32.const 0))) - (local.set 0x3ee (i64.load offset=0x3ee align=1 (i32.const 0))) - (local.set 0x3ef (i64.load offset=0x3ef align=1 (i32.const 0))) - (local.set 0x3f0 (i64.load offset=0x3f0 align=1 (i32.const 0))) - (local.set 0x3f1 (i64.load offset=0x3f1 align=1 (i32.const 0))) - (local.set 0x3f2 (i64.load offset=0x3f2 align=1 (i32.const 0))) - (local.set 0x3f3 (i64.load offset=0x3f3 align=1 (i32.const 0))) - (local.set 0x3f4 (i64.load offset=0x3f4 align=1 (i32.const 0))) - (local.set 0x3f5 (i64.load offset=0x3f5 align=1 (i32.const 0))) - (local.set 0x3f6 (i64.load offset=0x3f6 align=1 (i32.const 0))) - (local.set 0x3f7 (i64.load offset=0x3f7 align=1 (i32.const 0))) - (local.set 0x3f8 (i64.load offset=0x3f8 align=1 (i32.const 0))) - (local.set 0x3f9 (i64.load offset=0x3f9 align=1 (i32.const 0))) - (local.set 0x3fa (i64.load offset=0x3fa align=1 (i32.const 0))) - (local.set 0x3fb (i64.load offset=0x3fb align=1 (i32.const 0))) - (local.set 0x3fc (i64.load offset=0x3fc align=1 (i32.const 0))) - (local.set 0x3fd (i64.load offset=0x3fd align=1 (i32.const 0))) - (local.set 0x3fe (i64.load offset=0x3fe align=1 (i32.const 0))) - (local.set 0x3ff (i64.load offset=0x3ff align=1 (i32.const 0))) - (local.set 0x400 (i64.load offset=0x400 align=1 (i32.const 0))) - (local.set 0x401 (i64.load offset=0x401 align=1 (i32.const 0))) - (local.set 0x402 (i64.load offset=0x402 align=1 (i32.const 0))) - (local.set 0x403 (i64.load offset=0x403 align=1 (i32.const 0))) - (local.set 0x404 (i64.load offset=0x404 align=1 (i32.const 0))) - (local.set 0x405 (i64.load offset=0x405 align=1 (i32.const 0))) - (local.set 0x406 (i64.load offset=0x406 align=1 (i32.const 0))) - (local.set 0x407 (i64.load offset=0x407 align=1 (i32.const 0))) - (local.set 0x408 (i64.load offset=0x408 align=1 (i32.const 0))) - (local.set 0x409 (i64.load offset=0x409 align=1 (i32.const 0))) - (local.set 0x40a (i64.load offset=0x40a align=1 (i32.const 0))) - (local.set 0x40b (i64.load offset=0x40b align=1 (i32.const 0))) - (local.set 0x40c (i64.load offset=0x40c align=1 (i32.const 0))) - (local.set 0x40d (i64.load offset=0x40d align=1 (i32.const 0))) - (local.set 0x40e (i64.load offset=0x40e align=1 (i32.const 0))) - (local.set 0x40f (i64.load offset=0x40f align=1 (i32.const 0))) - (local.set 0x410 (i64.load offset=0x410 align=1 (i32.const 0))) - (local.set 0x411 (i64.load offset=0x411 align=1 (i32.const 0))) - (local.set 0x412 (i64.load offset=0x412 align=1 (i32.const 0))) - (local.set 0x413 (i64.load offset=0x413 align=1 (i32.const 0))) - (local.set 0x414 (i64.load offset=0x414 align=1 (i32.const 0))) - (local.set 0x415 (i64.load offset=0x415 align=1 (i32.const 0))) - (local.set 0x416 (i64.load offset=0x416 align=1 (i32.const 0))) - (local.set 0x417 (i64.load offset=0x417 align=1 (i32.const 0))) - (local.set 0x418 (i64.load offset=0x418 align=1 (i32.const 0))) - (local.set 0x419 (i64.load offset=0x419 align=1 (i32.const 0))) - (local.set 0x41a (i64.load offset=0x41a align=1 (i32.const 0))) - (local.set 0x41b (i64.load offset=0x41b align=1 (i32.const 0))) - (local.set 0x41c (i64.load offset=0x41c align=1 (i32.const 0))) - (local.set 0x41d (i64.load offset=0x41d align=1 (i32.const 0))) - (local.set 0x41e (i64.load offset=0x41e align=1 (i32.const 0))) - (local.set 0x41f (i64.load offset=0x41f align=1 (i32.const 0))) - - ;; store the locals back to memory - (i64.store offset=0x000 align=1 (i32.const 0) (local.get 0x000)) - (i64.store offset=0x001 align=1 (i32.const 0) (local.get 0x001)) - (i64.store offset=0x002 align=1 (i32.const 0) (local.get 0x002)) - (i64.store offset=0x003 align=1 (i32.const 0) (local.get 0x003)) - (i64.store offset=0x004 align=1 (i32.const 0) (local.get 0x004)) - (i64.store offset=0x005 align=1 (i32.const 0) (local.get 0x005)) - (i64.store offset=0x006 align=1 (i32.const 0) (local.get 0x006)) - (i64.store offset=0x007 align=1 (i32.const 0) (local.get 0x007)) - (i64.store offset=0x008 align=1 (i32.const 0) (local.get 0x008)) - (i64.store offset=0x009 align=1 (i32.const 0) (local.get 0x009)) - (i64.store offset=0x00a align=1 (i32.const 0) (local.get 0x00a)) - (i64.store offset=0x00b align=1 (i32.const 0) (local.get 0x00b)) - (i64.store offset=0x00c align=1 (i32.const 0) (local.get 0x00c)) - (i64.store offset=0x00d align=1 (i32.const 0) (local.get 0x00d)) - (i64.store offset=0x00e align=1 (i32.const 0) (local.get 0x00e)) - (i64.store offset=0x00f align=1 (i32.const 0) (local.get 0x00f)) - (i64.store offset=0x010 align=1 (i32.const 0) (local.get 0x010)) - (i64.store offset=0x011 align=1 (i32.const 0) (local.get 0x011)) - (i64.store offset=0x012 align=1 (i32.const 0) (local.get 0x012)) - (i64.store offset=0x013 align=1 (i32.const 0) (local.get 0x013)) - (i64.store offset=0x014 align=1 (i32.const 0) (local.get 0x014)) - (i64.store offset=0x015 align=1 (i32.const 0) (local.get 0x015)) - (i64.store offset=0x016 align=1 (i32.const 0) (local.get 0x016)) - (i64.store offset=0x017 align=1 (i32.const 0) (local.get 0x017)) - (i64.store offset=0x018 align=1 (i32.const 0) (local.get 0x018)) - (i64.store offset=0x019 align=1 (i32.const 0) (local.get 0x019)) - (i64.store offset=0x01a align=1 (i32.const 0) (local.get 0x01a)) - (i64.store offset=0x01b align=1 (i32.const 0) (local.get 0x01b)) - (i64.store offset=0x01c align=1 (i32.const 0) (local.get 0x01c)) - (i64.store offset=0x01d align=1 (i32.const 0) (local.get 0x01d)) - (i64.store offset=0x01e align=1 (i32.const 0) (local.get 0x01e)) - (i64.store offset=0x01f align=1 (i32.const 0) (local.get 0x01f)) - (i64.store offset=0x020 align=1 (i32.const 0) (local.get 0x020)) - (i64.store offset=0x021 align=1 (i32.const 0) (local.get 0x021)) - (i64.store offset=0x022 align=1 (i32.const 0) (local.get 0x022)) - (i64.store offset=0x023 align=1 (i32.const 0) (local.get 0x023)) - (i64.store offset=0x024 align=1 (i32.const 0) (local.get 0x024)) - (i64.store offset=0x025 align=1 (i32.const 0) (local.get 0x025)) - (i64.store offset=0x026 align=1 (i32.const 0) (local.get 0x026)) - (i64.store offset=0x027 align=1 (i32.const 0) (local.get 0x027)) - (i64.store offset=0x028 align=1 (i32.const 0) (local.get 0x028)) - (i64.store offset=0x029 align=1 (i32.const 0) (local.get 0x029)) - (i64.store offset=0x02a align=1 (i32.const 0) (local.get 0x02a)) - (i64.store offset=0x02b align=1 (i32.const 0) (local.get 0x02b)) - (i64.store offset=0x02c align=1 (i32.const 0) (local.get 0x02c)) - (i64.store offset=0x02d align=1 (i32.const 0) (local.get 0x02d)) - (i64.store offset=0x02e align=1 (i32.const 0) (local.get 0x02e)) - (i64.store offset=0x02f align=1 (i32.const 0) (local.get 0x02f)) - (i64.store offset=0x030 align=1 (i32.const 0) (local.get 0x030)) - (i64.store offset=0x031 align=1 (i32.const 0) (local.get 0x031)) - (i64.store offset=0x032 align=1 (i32.const 0) (local.get 0x032)) - (i64.store offset=0x033 align=1 (i32.const 0) (local.get 0x033)) - (i64.store offset=0x034 align=1 (i32.const 0) (local.get 0x034)) - (i64.store offset=0x035 align=1 (i32.const 0) (local.get 0x035)) - (i64.store offset=0x036 align=1 (i32.const 0) (local.get 0x036)) - (i64.store offset=0x037 align=1 (i32.const 0) (local.get 0x037)) - (i64.store offset=0x038 align=1 (i32.const 0) (local.get 0x038)) - (i64.store offset=0x039 align=1 (i32.const 0) (local.get 0x039)) - (i64.store offset=0x03a align=1 (i32.const 0) (local.get 0x03a)) - (i64.store offset=0x03b align=1 (i32.const 0) (local.get 0x03b)) - (i64.store offset=0x03c align=1 (i32.const 0) (local.get 0x03c)) - (i64.store offset=0x03d align=1 (i32.const 0) (local.get 0x03d)) - (i64.store offset=0x03e align=1 (i32.const 0) (local.get 0x03e)) - (i64.store offset=0x03f align=1 (i32.const 0) (local.get 0x03f)) - (i64.store offset=0x040 align=1 (i32.const 0) (local.get 0x040)) - (i64.store offset=0x041 align=1 (i32.const 0) (local.get 0x041)) - (i64.store offset=0x042 align=1 (i32.const 0) (local.get 0x042)) - (i64.store offset=0x043 align=1 (i32.const 0) (local.get 0x043)) - (i64.store offset=0x044 align=1 (i32.const 0) (local.get 0x044)) - (i64.store offset=0x045 align=1 (i32.const 0) (local.get 0x045)) - (i64.store offset=0x046 align=1 (i32.const 0) (local.get 0x046)) - (i64.store offset=0x047 align=1 (i32.const 0) (local.get 0x047)) - (i64.store offset=0x048 align=1 (i32.const 0) (local.get 0x048)) - (i64.store offset=0x049 align=1 (i32.const 0) (local.get 0x049)) - (i64.store offset=0x04a align=1 (i32.const 0) (local.get 0x04a)) - (i64.store offset=0x04b align=1 (i32.const 0) (local.get 0x04b)) - (i64.store offset=0x04c align=1 (i32.const 0) (local.get 0x04c)) - (i64.store offset=0x04d align=1 (i32.const 0) (local.get 0x04d)) - (i64.store offset=0x04e align=1 (i32.const 0) (local.get 0x04e)) - (i64.store offset=0x04f align=1 (i32.const 0) (local.get 0x04f)) - (i64.store offset=0x050 align=1 (i32.const 0) (local.get 0x050)) - (i64.store offset=0x051 align=1 (i32.const 0) (local.get 0x051)) - (i64.store offset=0x052 align=1 (i32.const 0) (local.get 0x052)) - (i64.store offset=0x053 align=1 (i32.const 0) (local.get 0x053)) - (i64.store offset=0x054 align=1 (i32.const 0) (local.get 0x054)) - (i64.store offset=0x055 align=1 (i32.const 0) (local.get 0x055)) - (i64.store offset=0x056 align=1 (i32.const 0) (local.get 0x056)) - (i64.store offset=0x057 align=1 (i32.const 0) (local.get 0x057)) - (i64.store offset=0x058 align=1 (i32.const 0) (local.get 0x058)) - (i64.store offset=0x059 align=1 (i32.const 0) (local.get 0x059)) - (i64.store offset=0x05a align=1 (i32.const 0) (local.get 0x05a)) - (i64.store offset=0x05b align=1 (i32.const 0) (local.get 0x05b)) - (i64.store offset=0x05c align=1 (i32.const 0) (local.get 0x05c)) - (i64.store offset=0x05d align=1 (i32.const 0) (local.get 0x05d)) - (i64.store offset=0x05e align=1 (i32.const 0) (local.get 0x05e)) - (i64.store offset=0x05f align=1 (i32.const 0) (local.get 0x05f)) - (i64.store offset=0x060 align=1 (i32.const 0) (local.get 0x060)) - (i64.store offset=0x061 align=1 (i32.const 0) (local.get 0x061)) - (i64.store offset=0x062 align=1 (i32.const 0) (local.get 0x062)) - (i64.store offset=0x063 align=1 (i32.const 0) (local.get 0x063)) - (i64.store offset=0x064 align=1 (i32.const 0) (local.get 0x064)) - (i64.store offset=0x065 align=1 (i32.const 0) (local.get 0x065)) - (i64.store offset=0x066 align=1 (i32.const 0) (local.get 0x066)) - (i64.store offset=0x067 align=1 (i32.const 0) (local.get 0x067)) - (i64.store offset=0x068 align=1 (i32.const 0) (local.get 0x068)) - (i64.store offset=0x069 align=1 (i32.const 0) (local.get 0x069)) - (i64.store offset=0x06a align=1 (i32.const 0) (local.get 0x06a)) - (i64.store offset=0x06b align=1 (i32.const 0) (local.get 0x06b)) - (i64.store offset=0x06c align=1 (i32.const 0) (local.get 0x06c)) - (i64.store offset=0x06d align=1 (i32.const 0) (local.get 0x06d)) - (i64.store offset=0x06e align=1 (i32.const 0) (local.get 0x06e)) - (i64.store offset=0x06f align=1 (i32.const 0) (local.get 0x06f)) - (i64.store offset=0x070 align=1 (i32.const 0) (local.get 0x070)) - (i64.store offset=0x071 align=1 (i32.const 0) (local.get 0x071)) - (i64.store offset=0x072 align=1 (i32.const 0) (local.get 0x072)) - (i64.store offset=0x073 align=1 (i32.const 0) (local.get 0x073)) - (i64.store offset=0x074 align=1 (i32.const 0) (local.get 0x074)) - (i64.store offset=0x075 align=1 (i32.const 0) (local.get 0x075)) - (i64.store offset=0x076 align=1 (i32.const 0) (local.get 0x076)) - (i64.store offset=0x077 align=1 (i32.const 0) (local.get 0x077)) - (i64.store offset=0x078 align=1 (i32.const 0) (local.get 0x078)) - (i64.store offset=0x079 align=1 (i32.const 0) (local.get 0x079)) - (i64.store offset=0x07a align=1 (i32.const 0) (local.get 0x07a)) - (i64.store offset=0x07b align=1 (i32.const 0) (local.get 0x07b)) - (i64.store offset=0x07c align=1 (i32.const 0) (local.get 0x07c)) - (i64.store offset=0x07d align=1 (i32.const 0) (local.get 0x07d)) - (i64.store offset=0x07e align=1 (i32.const 0) (local.get 0x07e)) - (i64.store offset=0x07f align=1 (i32.const 0) (local.get 0x07f)) - (i64.store offset=0x080 align=1 (i32.const 0) (local.get 0x080)) - (i64.store offset=0x081 align=1 (i32.const 0) (local.get 0x081)) - (i64.store offset=0x082 align=1 (i32.const 0) (local.get 0x082)) - (i64.store offset=0x083 align=1 (i32.const 0) (local.get 0x083)) - (i64.store offset=0x084 align=1 (i32.const 0) (local.get 0x084)) - (i64.store offset=0x085 align=1 (i32.const 0) (local.get 0x085)) - (i64.store offset=0x086 align=1 (i32.const 0) (local.get 0x086)) - (i64.store offset=0x087 align=1 (i32.const 0) (local.get 0x087)) - (i64.store offset=0x088 align=1 (i32.const 0) (local.get 0x088)) - (i64.store offset=0x089 align=1 (i32.const 0) (local.get 0x089)) - (i64.store offset=0x08a align=1 (i32.const 0) (local.get 0x08a)) - (i64.store offset=0x08b align=1 (i32.const 0) (local.get 0x08b)) - (i64.store offset=0x08c align=1 (i32.const 0) (local.get 0x08c)) - (i64.store offset=0x08d align=1 (i32.const 0) (local.get 0x08d)) - (i64.store offset=0x08e align=1 (i32.const 0) (local.get 0x08e)) - (i64.store offset=0x08f align=1 (i32.const 0) (local.get 0x08f)) - (i64.store offset=0x090 align=1 (i32.const 0) (local.get 0x090)) - (i64.store offset=0x091 align=1 (i32.const 0) (local.get 0x091)) - (i64.store offset=0x092 align=1 (i32.const 0) (local.get 0x092)) - (i64.store offset=0x093 align=1 (i32.const 0) (local.get 0x093)) - (i64.store offset=0x094 align=1 (i32.const 0) (local.get 0x094)) - (i64.store offset=0x095 align=1 (i32.const 0) (local.get 0x095)) - (i64.store offset=0x096 align=1 (i32.const 0) (local.get 0x096)) - (i64.store offset=0x097 align=1 (i32.const 0) (local.get 0x097)) - (i64.store offset=0x098 align=1 (i32.const 0) (local.get 0x098)) - (i64.store offset=0x099 align=1 (i32.const 0) (local.get 0x099)) - (i64.store offset=0x09a align=1 (i32.const 0) (local.get 0x09a)) - (i64.store offset=0x09b align=1 (i32.const 0) (local.get 0x09b)) - (i64.store offset=0x09c align=1 (i32.const 0) (local.get 0x09c)) - (i64.store offset=0x09d align=1 (i32.const 0) (local.get 0x09d)) - (i64.store offset=0x09e align=1 (i32.const 0) (local.get 0x09e)) - (i64.store offset=0x09f align=1 (i32.const 0) (local.get 0x09f)) - (i64.store offset=0x0a0 align=1 (i32.const 0) (local.get 0x0a0)) - (i64.store offset=0x0a1 align=1 (i32.const 0) (local.get 0x0a1)) - (i64.store offset=0x0a2 align=1 (i32.const 0) (local.get 0x0a2)) - (i64.store offset=0x0a3 align=1 (i32.const 0) (local.get 0x0a3)) - (i64.store offset=0x0a4 align=1 (i32.const 0) (local.get 0x0a4)) - (i64.store offset=0x0a5 align=1 (i32.const 0) (local.get 0x0a5)) - (i64.store offset=0x0a6 align=1 (i32.const 0) (local.get 0x0a6)) - (i64.store offset=0x0a7 align=1 (i32.const 0) (local.get 0x0a7)) - (i64.store offset=0x0a8 align=1 (i32.const 0) (local.get 0x0a8)) - (i64.store offset=0x0a9 align=1 (i32.const 0) (local.get 0x0a9)) - (i64.store offset=0x0aa align=1 (i32.const 0) (local.get 0x0aa)) - (i64.store offset=0x0ab align=1 (i32.const 0) (local.get 0x0ab)) - (i64.store offset=0x0ac align=1 (i32.const 0) (local.get 0x0ac)) - (i64.store offset=0x0ad align=1 (i32.const 0) (local.get 0x0ad)) - (i64.store offset=0x0ae align=1 (i32.const 0) (local.get 0x0ae)) - (i64.store offset=0x0af align=1 (i32.const 0) (local.get 0x0af)) - (i64.store offset=0x0b0 align=1 (i32.const 0) (local.get 0x0b0)) - (i64.store offset=0x0b1 align=1 (i32.const 0) (local.get 0x0b1)) - (i64.store offset=0x0b2 align=1 (i32.const 0) (local.get 0x0b2)) - (i64.store offset=0x0b3 align=1 (i32.const 0) (local.get 0x0b3)) - (i64.store offset=0x0b4 align=1 (i32.const 0) (local.get 0x0b4)) - (i64.store offset=0x0b5 align=1 (i32.const 0) (local.get 0x0b5)) - (i64.store offset=0x0b6 align=1 (i32.const 0) (local.get 0x0b6)) - (i64.store offset=0x0b7 align=1 (i32.const 0) (local.get 0x0b7)) - (i64.store offset=0x0b8 align=1 (i32.const 0) (local.get 0x0b8)) - (i64.store offset=0x0b9 align=1 (i32.const 0) (local.get 0x0b9)) - (i64.store offset=0x0ba align=1 (i32.const 0) (local.get 0x0ba)) - (i64.store offset=0x0bb align=1 (i32.const 0) (local.get 0x0bb)) - (i64.store offset=0x0bc align=1 (i32.const 0) (local.get 0x0bc)) - (i64.store offset=0x0bd align=1 (i32.const 0) (local.get 0x0bd)) - (i64.store offset=0x0be align=1 (i32.const 0) (local.get 0x0be)) - (i64.store offset=0x0bf align=1 (i32.const 0) (local.get 0x0bf)) - (i64.store offset=0x0c0 align=1 (i32.const 0) (local.get 0x0c0)) - (i64.store offset=0x0c1 align=1 (i32.const 0) (local.get 0x0c1)) - (i64.store offset=0x0c2 align=1 (i32.const 0) (local.get 0x0c2)) - (i64.store offset=0x0c3 align=1 (i32.const 0) (local.get 0x0c3)) - (i64.store offset=0x0c4 align=1 (i32.const 0) (local.get 0x0c4)) - (i64.store offset=0x0c5 align=1 (i32.const 0) (local.get 0x0c5)) - (i64.store offset=0x0c6 align=1 (i32.const 0) (local.get 0x0c6)) - (i64.store offset=0x0c7 align=1 (i32.const 0) (local.get 0x0c7)) - (i64.store offset=0x0c8 align=1 (i32.const 0) (local.get 0x0c8)) - (i64.store offset=0x0c9 align=1 (i32.const 0) (local.get 0x0c9)) - (i64.store offset=0x0ca align=1 (i32.const 0) (local.get 0x0ca)) - (i64.store offset=0x0cb align=1 (i32.const 0) (local.get 0x0cb)) - (i64.store offset=0x0cc align=1 (i32.const 0) (local.get 0x0cc)) - (i64.store offset=0x0cd align=1 (i32.const 0) (local.get 0x0cd)) - (i64.store offset=0x0ce align=1 (i32.const 0) (local.get 0x0ce)) - (i64.store offset=0x0cf align=1 (i32.const 0) (local.get 0x0cf)) - (i64.store offset=0x0d0 align=1 (i32.const 0) (local.get 0x0d0)) - (i64.store offset=0x0d1 align=1 (i32.const 0) (local.get 0x0d1)) - (i64.store offset=0x0d2 align=1 (i32.const 0) (local.get 0x0d2)) - (i64.store offset=0x0d3 align=1 (i32.const 0) (local.get 0x0d3)) - (i64.store offset=0x0d4 align=1 (i32.const 0) (local.get 0x0d4)) - (i64.store offset=0x0d5 align=1 (i32.const 0) (local.get 0x0d5)) - (i64.store offset=0x0d6 align=1 (i32.const 0) (local.get 0x0d6)) - (i64.store offset=0x0d7 align=1 (i32.const 0) (local.get 0x0d7)) - (i64.store offset=0x0d8 align=1 (i32.const 0) (local.get 0x0d8)) - (i64.store offset=0x0d9 align=1 (i32.const 0) (local.get 0x0d9)) - (i64.store offset=0x0da align=1 (i32.const 0) (local.get 0x0da)) - (i64.store offset=0x0db align=1 (i32.const 0) (local.get 0x0db)) - (i64.store offset=0x0dc align=1 (i32.const 0) (local.get 0x0dc)) - (i64.store offset=0x0dd align=1 (i32.const 0) (local.get 0x0dd)) - (i64.store offset=0x0de align=1 (i32.const 0) (local.get 0x0de)) - (i64.store offset=0x0df align=1 (i32.const 0) (local.get 0x0df)) - (i64.store offset=0x0e0 align=1 (i32.const 0) (local.get 0x0e0)) - (i64.store offset=0x0e1 align=1 (i32.const 0) (local.get 0x0e1)) - (i64.store offset=0x0e2 align=1 (i32.const 0) (local.get 0x0e2)) - (i64.store offset=0x0e3 align=1 (i32.const 0) (local.get 0x0e3)) - (i64.store offset=0x0e4 align=1 (i32.const 0) (local.get 0x0e4)) - (i64.store offset=0x0e5 align=1 (i32.const 0) (local.get 0x0e5)) - (i64.store offset=0x0e6 align=1 (i32.const 0) (local.get 0x0e6)) - (i64.store offset=0x0e7 align=1 (i32.const 0) (local.get 0x0e7)) - (i64.store offset=0x0e8 align=1 (i32.const 0) (local.get 0x0e8)) - (i64.store offset=0x0e9 align=1 (i32.const 0) (local.get 0x0e9)) - (i64.store offset=0x0ea align=1 (i32.const 0) (local.get 0x0ea)) - (i64.store offset=0x0eb align=1 (i32.const 0) (local.get 0x0eb)) - (i64.store offset=0x0ec align=1 (i32.const 0) (local.get 0x0ec)) - (i64.store offset=0x0ed align=1 (i32.const 0) (local.get 0x0ed)) - (i64.store offset=0x0ee align=1 (i32.const 0) (local.get 0x0ee)) - (i64.store offset=0x0ef align=1 (i32.const 0) (local.get 0x0ef)) - (i64.store offset=0x0f0 align=1 (i32.const 0) (local.get 0x0f0)) - (i64.store offset=0x0f1 align=1 (i32.const 0) (local.get 0x0f1)) - (i64.store offset=0x0f2 align=1 (i32.const 0) (local.get 0x0f2)) - (i64.store offset=0x0f3 align=1 (i32.const 0) (local.get 0x0f3)) - (i64.store offset=0x0f4 align=1 (i32.const 0) (local.get 0x0f4)) - (i64.store offset=0x0f5 align=1 (i32.const 0) (local.get 0x0f5)) - (i64.store offset=0x0f6 align=1 (i32.const 0) (local.get 0x0f6)) - (i64.store offset=0x0f7 align=1 (i32.const 0) (local.get 0x0f7)) - (i64.store offset=0x0f8 align=1 (i32.const 0) (local.get 0x0f8)) - (i64.store offset=0x0f9 align=1 (i32.const 0) (local.get 0x0f9)) - (i64.store offset=0x0fa align=1 (i32.const 0) (local.get 0x0fa)) - (i64.store offset=0x0fb align=1 (i32.const 0) (local.get 0x0fb)) - (i64.store offset=0x0fc align=1 (i32.const 0) (local.get 0x0fc)) - (i64.store offset=0x0fd align=1 (i32.const 0) (local.get 0x0fd)) - (i64.store offset=0x0fe align=1 (i32.const 0) (local.get 0x0fe)) - (i64.store offset=0x0ff align=1 (i32.const 0) (local.get 0x0ff)) - (i64.store offset=0x100 align=1 (i32.const 0) (local.get 0x100)) - (i64.store offset=0x101 align=1 (i32.const 0) (local.get 0x101)) - (i64.store offset=0x102 align=1 (i32.const 0) (local.get 0x102)) - (i64.store offset=0x103 align=1 (i32.const 0) (local.get 0x103)) - (i64.store offset=0x104 align=1 (i32.const 0) (local.get 0x104)) - (i64.store offset=0x105 align=1 (i32.const 0) (local.get 0x105)) - (i64.store offset=0x106 align=1 (i32.const 0) (local.get 0x106)) - (i64.store offset=0x107 align=1 (i32.const 0) (local.get 0x107)) - (i64.store offset=0x108 align=1 (i32.const 0) (local.get 0x108)) - (i64.store offset=0x109 align=1 (i32.const 0) (local.get 0x109)) - (i64.store offset=0x10a align=1 (i32.const 0) (local.get 0x10a)) - (i64.store offset=0x10b align=1 (i32.const 0) (local.get 0x10b)) - (i64.store offset=0x10c align=1 (i32.const 0) (local.get 0x10c)) - (i64.store offset=0x10d align=1 (i32.const 0) (local.get 0x10d)) - (i64.store offset=0x10e align=1 (i32.const 0) (local.get 0x10e)) - (i64.store offset=0x10f align=1 (i32.const 0) (local.get 0x10f)) - (i64.store offset=0x110 align=1 (i32.const 0) (local.get 0x110)) - (i64.store offset=0x111 align=1 (i32.const 0) (local.get 0x111)) - (i64.store offset=0x112 align=1 (i32.const 0) (local.get 0x112)) - (i64.store offset=0x113 align=1 (i32.const 0) (local.get 0x113)) - (i64.store offset=0x114 align=1 (i32.const 0) (local.get 0x114)) - (i64.store offset=0x115 align=1 (i32.const 0) (local.get 0x115)) - (i64.store offset=0x116 align=1 (i32.const 0) (local.get 0x116)) - (i64.store offset=0x117 align=1 (i32.const 0) (local.get 0x117)) - (i64.store offset=0x118 align=1 (i32.const 0) (local.get 0x118)) - (i64.store offset=0x119 align=1 (i32.const 0) (local.get 0x119)) - (i64.store offset=0x11a align=1 (i32.const 0) (local.get 0x11a)) - (i64.store offset=0x11b align=1 (i32.const 0) (local.get 0x11b)) - (i64.store offset=0x11c align=1 (i32.const 0) (local.get 0x11c)) - (i64.store offset=0x11d align=1 (i32.const 0) (local.get 0x11d)) - (i64.store offset=0x11e align=1 (i32.const 0) (local.get 0x11e)) - (i64.store offset=0x11f align=1 (i32.const 0) (local.get 0x11f)) - (i64.store offset=0x120 align=1 (i32.const 0) (local.get 0x120)) - (i64.store offset=0x121 align=1 (i32.const 0) (local.get 0x121)) - (i64.store offset=0x122 align=1 (i32.const 0) (local.get 0x122)) - (i64.store offset=0x123 align=1 (i32.const 0) (local.get 0x123)) - (i64.store offset=0x124 align=1 (i32.const 0) (local.get 0x124)) - (i64.store offset=0x125 align=1 (i32.const 0) (local.get 0x125)) - (i64.store offset=0x126 align=1 (i32.const 0) (local.get 0x126)) - (i64.store offset=0x127 align=1 (i32.const 0) (local.get 0x127)) - (i64.store offset=0x128 align=1 (i32.const 0) (local.get 0x128)) - (i64.store offset=0x129 align=1 (i32.const 0) (local.get 0x129)) - (i64.store offset=0x12a align=1 (i32.const 0) (local.get 0x12a)) - (i64.store offset=0x12b align=1 (i32.const 0) (local.get 0x12b)) - (i64.store offset=0x12c align=1 (i32.const 0) (local.get 0x12c)) - (i64.store offset=0x12d align=1 (i32.const 0) (local.get 0x12d)) - (i64.store offset=0x12e align=1 (i32.const 0) (local.get 0x12e)) - (i64.store offset=0x12f align=1 (i32.const 0) (local.get 0x12f)) - (i64.store offset=0x130 align=1 (i32.const 0) (local.get 0x130)) - (i64.store offset=0x131 align=1 (i32.const 0) (local.get 0x131)) - (i64.store offset=0x132 align=1 (i32.const 0) (local.get 0x132)) - (i64.store offset=0x133 align=1 (i32.const 0) (local.get 0x133)) - (i64.store offset=0x134 align=1 (i32.const 0) (local.get 0x134)) - (i64.store offset=0x135 align=1 (i32.const 0) (local.get 0x135)) - (i64.store offset=0x136 align=1 (i32.const 0) (local.get 0x136)) - (i64.store offset=0x137 align=1 (i32.const 0) (local.get 0x137)) - (i64.store offset=0x138 align=1 (i32.const 0) (local.get 0x138)) - (i64.store offset=0x139 align=1 (i32.const 0) (local.get 0x139)) - (i64.store offset=0x13a align=1 (i32.const 0) (local.get 0x13a)) - (i64.store offset=0x13b align=1 (i32.const 0) (local.get 0x13b)) - (i64.store offset=0x13c align=1 (i32.const 0) (local.get 0x13c)) - (i64.store offset=0x13d align=1 (i32.const 0) (local.get 0x13d)) - (i64.store offset=0x13e align=1 (i32.const 0) (local.get 0x13e)) - (i64.store offset=0x13f align=1 (i32.const 0) (local.get 0x13f)) - (i64.store offset=0x140 align=1 (i32.const 0) (local.get 0x140)) - (i64.store offset=0x141 align=1 (i32.const 0) (local.get 0x141)) - (i64.store offset=0x142 align=1 (i32.const 0) (local.get 0x142)) - (i64.store offset=0x143 align=1 (i32.const 0) (local.get 0x143)) - (i64.store offset=0x144 align=1 (i32.const 0) (local.get 0x144)) - (i64.store offset=0x145 align=1 (i32.const 0) (local.get 0x145)) - (i64.store offset=0x146 align=1 (i32.const 0) (local.get 0x146)) - (i64.store offset=0x147 align=1 (i32.const 0) (local.get 0x147)) - (i64.store offset=0x148 align=1 (i32.const 0) (local.get 0x148)) - (i64.store offset=0x149 align=1 (i32.const 0) (local.get 0x149)) - (i64.store offset=0x14a align=1 (i32.const 0) (local.get 0x14a)) - (i64.store offset=0x14b align=1 (i32.const 0) (local.get 0x14b)) - (i64.store offset=0x14c align=1 (i32.const 0) (local.get 0x14c)) - (i64.store offset=0x14d align=1 (i32.const 0) (local.get 0x14d)) - (i64.store offset=0x14e align=1 (i32.const 0) (local.get 0x14e)) - (i64.store offset=0x14f align=1 (i32.const 0) (local.get 0x14f)) - (i64.store offset=0x150 align=1 (i32.const 0) (local.get 0x150)) - (i64.store offset=0x151 align=1 (i32.const 0) (local.get 0x151)) - (i64.store offset=0x152 align=1 (i32.const 0) (local.get 0x152)) - (i64.store offset=0x153 align=1 (i32.const 0) (local.get 0x153)) - (i64.store offset=0x154 align=1 (i32.const 0) (local.get 0x154)) - (i64.store offset=0x155 align=1 (i32.const 0) (local.get 0x155)) - (i64.store offset=0x156 align=1 (i32.const 0) (local.get 0x156)) - (i64.store offset=0x157 align=1 (i32.const 0) (local.get 0x157)) - (i64.store offset=0x158 align=1 (i32.const 0) (local.get 0x158)) - (i64.store offset=0x159 align=1 (i32.const 0) (local.get 0x159)) - (i64.store offset=0x15a align=1 (i32.const 0) (local.get 0x15a)) - (i64.store offset=0x15b align=1 (i32.const 0) (local.get 0x15b)) - (i64.store offset=0x15c align=1 (i32.const 0) (local.get 0x15c)) - (i64.store offset=0x15d align=1 (i32.const 0) (local.get 0x15d)) - (i64.store offset=0x15e align=1 (i32.const 0) (local.get 0x15e)) - (i64.store offset=0x15f align=1 (i32.const 0) (local.get 0x15f)) - (i64.store offset=0x160 align=1 (i32.const 0) (local.get 0x160)) - (i64.store offset=0x161 align=1 (i32.const 0) (local.get 0x161)) - (i64.store offset=0x162 align=1 (i32.const 0) (local.get 0x162)) - (i64.store offset=0x163 align=1 (i32.const 0) (local.get 0x163)) - (i64.store offset=0x164 align=1 (i32.const 0) (local.get 0x164)) - (i64.store offset=0x165 align=1 (i32.const 0) (local.get 0x165)) - (i64.store offset=0x166 align=1 (i32.const 0) (local.get 0x166)) - (i64.store offset=0x167 align=1 (i32.const 0) (local.get 0x167)) - (i64.store offset=0x168 align=1 (i32.const 0) (local.get 0x168)) - (i64.store offset=0x169 align=1 (i32.const 0) (local.get 0x169)) - (i64.store offset=0x16a align=1 (i32.const 0) (local.get 0x16a)) - (i64.store offset=0x16b align=1 (i32.const 0) (local.get 0x16b)) - (i64.store offset=0x16c align=1 (i32.const 0) (local.get 0x16c)) - (i64.store offset=0x16d align=1 (i32.const 0) (local.get 0x16d)) - (i64.store offset=0x16e align=1 (i32.const 0) (local.get 0x16e)) - (i64.store offset=0x16f align=1 (i32.const 0) (local.get 0x16f)) - (i64.store offset=0x170 align=1 (i32.const 0) (local.get 0x170)) - (i64.store offset=0x171 align=1 (i32.const 0) (local.get 0x171)) - (i64.store offset=0x172 align=1 (i32.const 0) (local.get 0x172)) - (i64.store offset=0x173 align=1 (i32.const 0) (local.get 0x173)) - (i64.store offset=0x174 align=1 (i32.const 0) (local.get 0x174)) - (i64.store offset=0x175 align=1 (i32.const 0) (local.get 0x175)) - (i64.store offset=0x176 align=1 (i32.const 0) (local.get 0x176)) - (i64.store offset=0x177 align=1 (i32.const 0) (local.get 0x177)) - (i64.store offset=0x178 align=1 (i32.const 0) (local.get 0x178)) - (i64.store offset=0x179 align=1 (i32.const 0) (local.get 0x179)) - (i64.store offset=0x17a align=1 (i32.const 0) (local.get 0x17a)) - (i64.store offset=0x17b align=1 (i32.const 0) (local.get 0x17b)) - (i64.store offset=0x17c align=1 (i32.const 0) (local.get 0x17c)) - (i64.store offset=0x17d align=1 (i32.const 0) (local.get 0x17d)) - (i64.store offset=0x17e align=1 (i32.const 0) (local.get 0x17e)) - (i64.store offset=0x17f align=1 (i32.const 0) (local.get 0x17f)) - (i64.store offset=0x180 align=1 (i32.const 0) (local.get 0x180)) - (i64.store offset=0x181 align=1 (i32.const 0) (local.get 0x181)) - (i64.store offset=0x182 align=1 (i32.const 0) (local.get 0x182)) - (i64.store offset=0x183 align=1 (i32.const 0) (local.get 0x183)) - (i64.store offset=0x184 align=1 (i32.const 0) (local.get 0x184)) - (i64.store offset=0x185 align=1 (i32.const 0) (local.get 0x185)) - (i64.store offset=0x186 align=1 (i32.const 0) (local.get 0x186)) - (i64.store offset=0x187 align=1 (i32.const 0) (local.get 0x187)) - (i64.store offset=0x188 align=1 (i32.const 0) (local.get 0x188)) - (i64.store offset=0x189 align=1 (i32.const 0) (local.get 0x189)) - (i64.store offset=0x18a align=1 (i32.const 0) (local.get 0x18a)) - (i64.store offset=0x18b align=1 (i32.const 0) (local.get 0x18b)) - (i64.store offset=0x18c align=1 (i32.const 0) (local.get 0x18c)) - (i64.store offset=0x18d align=1 (i32.const 0) (local.get 0x18d)) - (i64.store offset=0x18e align=1 (i32.const 0) (local.get 0x18e)) - (i64.store offset=0x18f align=1 (i32.const 0) (local.get 0x18f)) - (i64.store offset=0x190 align=1 (i32.const 0) (local.get 0x190)) - (i64.store offset=0x191 align=1 (i32.const 0) (local.get 0x191)) - (i64.store offset=0x192 align=1 (i32.const 0) (local.get 0x192)) - (i64.store offset=0x193 align=1 (i32.const 0) (local.get 0x193)) - (i64.store offset=0x194 align=1 (i32.const 0) (local.get 0x194)) - (i64.store offset=0x195 align=1 (i32.const 0) (local.get 0x195)) - (i64.store offset=0x196 align=1 (i32.const 0) (local.get 0x196)) - (i64.store offset=0x197 align=1 (i32.const 0) (local.get 0x197)) - (i64.store offset=0x198 align=1 (i32.const 0) (local.get 0x198)) - (i64.store offset=0x199 align=1 (i32.const 0) (local.get 0x199)) - (i64.store offset=0x19a align=1 (i32.const 0) (local.get 0x19a)) - (i64.store offset=0x19b align=1 (i32.const 0) (local.get 0x19b)) - (i64.store offset=0x19c align=1 (i32.const 0) (local.get 0x19c)) - (i64.store offset=0x19d align=1 (i32.const 0) (local.get 0x19d)) - (i64.store offset=0x19e align=1 (i32.const 0) (local.get 0x19e)) - (i64.store offset=0x19f align=1 (i32.const 0) (local.get 0x19f)) - (i64.store offset=0x1a0 align=1 (i32.const 0) (local.get 0x1a0)) - (i64.store offset=0x1a1 align=1 (i32.const 0) (local.get 0x1a1)) - (i64.store offset=0x1a2 align=1 (i32.const 0) (local.get 0x1a2)) - (i64.store offset=0x1a3 align=1 (i32.const 0) (local.get 0x1a3)) - (i64.store offset=0x1a4 align=1 (i32.const 0) (local.get 0x1a4)) - (i64.store offset=0x1a5 align=1 (i32.const 0) (local.get 0x1a5)) - (i64.store offset=0x1a6 align=1 (i32.const 0) (local.get 0x1a6)) - (i64.store offset=0x1a7 align=1 (i32.const 0) (local.get 0x1a7)) - (i64.store offset=0x1a8 align=1 (i32.const 0) (local.get 0x1a8)) - (i64.store offset=0x1a9 align=1 (i32.const 0) (local.get 0x1a9)) - (i64.store offset=0x1aa align=1 (i32.const 0) (local.get 0x1aa)) - (i64.store offset=0x1ab align=1 (i32.const 0) (local.get 0x1ab)) - (i64.store offset=0x1ac align=1 (i32.const 0) (local.get 0x1ac)) - (i64.store offset=0x1ad align=1 (i32.const 0) (local.get 0x1ad)) - (i64.store offset=0x1ae align=1 (i32.const 0) (local.get 0x1ae)) - (i64.store offset=0x1af align=1 (i32.const 0) (local.get 0x1af)) - (i64.store offset=0x1b0 align=1 (i32.const 0) (local.get 0x1b0)) - (i64.store offset=0x1b1 align=1 (i32.const 0) (local.get 0x1b1)) - (i64.store offset=0x1b2 align=1 (i32.const 0) (local.get 0x1b2)) - (i64.store offset=0x1b3 align=1 (i32.const 0) (local.get 0x1b3)) - (i64.store offset=0x1b4 align=1 (i32.const 0) (local.get 0x1b4)) - (i64.store offset=0x1b5 align=1 (i32.const 0) (local.get 0x1b5)) - (i64.store offset=0x1b6 align=1 (i32.const 0) (local.get 0x1b6)) - (i64.store offset=0x1b7 align=1 (i32.const 0) (local.get 0x1b7)) - (i64.store offset=0x1b8 align=1 (i32.const 0) (local.get 0x1b8)) - (i64.store offset=0x1b9 align=1 (i32.const 0) (local.get 0x1b9)) - (i64.store offset=0x1ba align=1 (i32.const 0) (local.get 0x1ba)) - (i64.store offset=0x1bb align=1 (i32.const 0) (local.get 0x1bb)) - (i64.store offset=0x1bc align=1 (i32.const 0) (local.get 0x1bc)) - (i64.store offset=0x1bd align=1 (i32.const 0) (local.get 0x1bd)) - (i64.store offset=0x1be align=1 (i32.const 0) (local.get 0x1be)) - (i64.store offset=0x1bf align=1 (i32.const 0) (local.get 0x1bf)) - (i64.store offset=0x1c0 align=1 (i32.const 0) (local.get 0x1c0)) - (i64.store offset=0x1c1 align=1 (i32.const 0) (local.get 0x1c1)) - (i64.store offset=0x1c2 align=1 (i32.const 0) (local.get 0x1c2)) - (i64.store offset=0x1c3 align=1 (i32.const 0) (local.get 0x1c3)) - (i64.store offset=0x1c4 align=1 (i32.const 0) (local.get 0x1c4)) - (i64.store offset=0x1c5 align=1 (i32.const 0) (local.get 0x1c5)) - (i64.store offset=0x1c6 align=1 (i32.const 0) (local.get 0x1c6)) - (i64.store offset=0x1c7 align=1 (i32.const 0) (local.get 0x1c7)) - (i64.store offset=0x1c8 align=1 (i32.const 0) (local.get 0x1c8)) - (i64.store offset=0x1c9 align=1 (i32.const 0) (local.get 0x1c9)) - (i64.store offset=0x1ca align=1 (i32.const 0) (local.get 0x1ca)) - (i64.store offset=0x1cb align=1 (i32.const 0) (local.get 0x1cb)) - (i64.store offset=0x1cc align=1 (i32.const 0) (local.get 0x1cc)) - (i64.store offset=0x1cd align=1 (i32.const 0) (local.get 0x1cd)) - (i64.store offset=0x1ce align=1 (i32.const 0) (local.get 0x1ce)) - (i64.store offset=0x1cf align=1 (i32.const 0) (local.get 0x1cf)) - (i64.store offset=0x1d0 align=1 (i32.const 0) (local.get 0x1d0)) - (i64.store offset=0x1d1 align=1 (i32.const 0) (local.get 0x1d1)) - (i64.store offset=0x1d2 align=1 (i32.const 0) (local.get 0x1d2)) - (i64.store offset=0x1d3 align=1 (i32.const 0) (local.get 0x1d3)) - (i64.store offset=0x1d4 align=1 (i32.const 0) (local.get 0x1d4)) - (i64.store offset=0x1d5 align=1 (i32.const 0) (local.get 0x1d5)) - (i64.store offset=0x1d6 align=1 (i32.const 0) (local.get 0x1d6)) - (i64.store offset=0x1d7 align=1 (i32.const 0) (local.get 0x1d7)) - (i64.store offset=0x1d8 align=1 (i32.const 0) (local.get 0x1d8)) - (i64.store offset=0x1d9 align=1 (i32.const 0) (local.get 0x1d9)) - (i64.store offset=0x1da align=1 (i32.const 0) (local.get 0x1da)) - (i64.store offset=0x1db align=1 (i32.const 0) (local.get 0x1db)) - (i64.store offset=0x1dc align=1 (i32.const 0) (local.get 0x1dc)) - (i64.store offset=0x1dd align=1 (i32.const 0) (local.get 0x1dd)) - (i64.store offset=0x1de align=1 (i32.const 0) (local.get 0x1de)) - (i64.store offset=0x1df align=1 (i32.const 0) (local.get 0x1df)) - (i64.store offset=0x1e0 align=1 (i32.const 0) (local.get 0x1e0)) - (i64.store offset=0x1e1 align=1 (i32.const 0) (local.get 0x1e1)) - (i64.store offset=0x1e2 align=1 (i32.const 0) (local.get 0x1e2)) - (i64.store offset=0x1e3 align=1 (i32.const 0) (local.get 0x1e3)) - (i64.store offset=0x1e4 align=1 (i32.const 0) (local.get 0x1e4)) - (i64.store offset=0x1e5 align=1 (i32.const 0) (local.get 0x1e5)) - (i64.store offset=0x1e6 align=1 (i32.const 0) (local.get 0x1e6)) - (i64.store offset=0x1e7 align=1 (i32.const 0) (local.get 0x1e7)) - (i64.store offset=0x1e8 align=1 (i32.const 0) (local.get 0x1e8)) - (i64.store offset=0x1e9 align=1 (i32.const 0) (local.get 0x1e9)) - (i64.store offset=0x1ea align=1 (i32.const 0) (local.get 0x1ea)) - (i64.store offset=0x1eb align=1 (i32.const 0) (local.get 0x1eb)) - (i64.store offset=0x1ec align=1 (i32.const 0) (local.get 0x1ec)) - (i64.store offset=0x1ed align=1 (i32.const 0) (local.get 0x1ed)) - (i64.store offset=0x1ee align=1 (i32.const 0) (local.get 0x1ee)) - (i64.store offset=0x1ef align=1 (i32.const 0) (local.get 0x1ef)) - (i64.store offset=0x1f0 align=1 (i32.const 0) (local.get 0x1f0)) - (i64.store offset=0x1f1 align=1 (i32.const 0) (local.get 0x1f1)) - (i64.store offset=0x1f2 align=1 (i32.const 0) (local.get 0x1f2)) - (i64.store offset=0x1f3 align=1 (i32.const 0) (local.get 0x1f3)) - (i64.store offset=0x1f4 align=1 (i32.const 0) (local.get 0x1f4)) - (i64.store offset=0x1f5 align=1 (i32.const 0) (local.get 0x1f5)) - (i64.store offset=0x1f6 align=1 (i32.const 0) (local.get 0x1f6)) - (i64.store offset=0x1f7 align=1 (i32.const 0) (local.get 0x1f7)) - (i64.store offset=0x1f8 align=1 (i32.const 0) (local.get 0x1f8)) - (i64.store offset=0x1f9 align=1 (i32.const 0) (local.get 0x1f9)) - (i64.store offset=0x1fa align=1 (i32.const 0) (local.get 0x1fa)) - (i64.store offset=0x1fb align=1 (i32.const 0) (local.get 0x1fb)) - (i64.store offset=0x1fc align=1 (i32.const 0) (local.get 0x1fc)) - (i64.store offset=0x1fd align=1 (i32.const 0) (local.get 0x1fd)) - (i64.store offset=0x1fe align=1 (i32.const 0) (local.get 0x1fe)) - (i64.store offset=0x1ff align=1 (i32.const 0) (local.get 0x1ff)) - (i64.store offset=0x200 align=1 (i32.const 0) (local.get 0x200)) - (i64.store offset=0x201 align=1 (i32.const 0) (local.get 0x201)) - (i64.store offset=0x202 align=1 (i32.const 0) (local.get 0x202)) - (i64.store offset=0x203 align=1 (i32.const 0) (local.get 0x203)) - (i64.store offset=0x204 align=1 (i32.const 0) (local.get 0x204)) - (i64.store offset=0x205 align=1 (i32.const 0) (local.get 0x205)) - (i64.store offset=0x206 align=1 (i32.const 0) (local.get 0x206)) - (i64.store offset=0x207 align=1 (i32.const 0) (local.get 0x207)) - (i64.store offset=0x208 align=1 (i32.const 0) (local.get 0x208)) - (i64.store offset=0x209 align=1 (i32.const 0) (local.get 0x209)) - (i64.store offset=0x20a align=1 (i32.const 0) (local.get 0x20a)) - (i64.store offset=0x20b align=1 (i32.const 0) (local.get 0x20b)) - (i64.store offset=0x20c align=1 (i32.const 0) (local.get 0x20c)) - (i64.store offset=0x20d align=1 (i32.const 0) (local.get 0x20d)) - (i64.store offset=0x20e align=1 (i32.const 0) (local.get 0x20e)) - (i64.store offset=0x20f align=1 (i32.const 0) (local.get 0x20f)) - (i64.store offset=0x210 align=1 (i32.const 0) (local.get 0x210)) - (i64.store offset=0x211 align=1 (i32.const 0) (local.get 0x211)) - (i64.store offset=0x212 align=1 (i32.const 0) (local.get 0x212)) - (i64.store offset=0x213 align=1 (i32.const 0) (local.get 0x213)) - (i64.store offset=0x214 align=1 (i32.const 0) (local.get 0x214)) - (i64.store offset=0x215 align=1 (i32.const 0) (local.get 0x215)) - (i64.store offset=0x216 align=1 (i32.const 0) (local.get 0x216)) - (i64.store offset=0x217 align=1 (i32.const 0) (local.get 0x217)) - (i64.store offset=0x218 align=1 (i32.const 0) (local.get 0x218)) - (i64.store offset=0x219 align=1 (i32.const 0) (local.get 0x219)) - (i64.store offset=0x21a align=1 (i32.const 0) (local.get 0x21a)) - (i64.store offset=0x21b align=1 (i32.const 0) (local.get 0x21b)) - (i64.store offset=0x21c align=1 (i32.const 0) (local.get 0x21c)) - (i64.store offset=0x21d align=1 (i32.const 0) (local.get 0x21d)) - (i64.store offset=0x21e align=1 (i32.const 0) (local.get 0x21e)) - (i64.store offset=0x21f align=1 (i32.const 0) (local.get 0x21f)) - (i64.store offset=0x220 align=1 (i32.const 0) (local.get 0x220)) - (i64.store offset=0x221 align=1 (i32.const 0) (local.get 0x221)) - (i64.store offset=0x222 align=1 (i32.const 0) (local.get 0x222)) - (i64.store offset=0x223 align=1 (i32.const 0) (local.get 0x223)) - (i64.store offset=0x224 align=1 (i32.const 0) (local.get 0x224)) - (i64.store offset=0x225 align=1 (i32.const 0) (local.get 0x225)) - (i64.store offset=0x226 align=1 (i32.const 0) (local.get 0x226)) - (i64.store offset=0x227 align=1 (i32.const 0) (local.get 0x227)) - (i64.store offset=0x228 align=1 (i32.const 0) (local.get 0x228)) - (i64.store offset=0x229 align=1 (i32.const 0) (local.get 0x229)) - (i64.store offset=0x22a align=1 (i32.const 0) (local.get 0x22a)) - (i64.store offset=0x22b align=1 (i32.const 0) (local.get 0x22b)) - (i64.store offset=0x22c align=1 (i32.const 0) (local.get 0x22c)) - (i64.store offset=0x22d align=1 (i32.const 0) (local.get 0x22d)) - (i64.store offset=0x22e align=1 (i32.const 0) (local.get 0x22e)) - (i64.store offset=0x22f align=1 (i32.const 0) (local.get 0x22f)) - (i64.store offset=0x230 align=1 (i32.const 0) (local.get 0x230)) - (i64.store offset=0x231 align=1 (i32.const 0) (local.get 0x231)) - (i64.store offset=0x232 align=1 (i32.const 0) (local.get 0x232)) - (i64.store offset=0x233 align=1 (i32.const 0) (local.get 0x233)) - (i64.store offset=0x234 align=1 (i32.const 0) (local.get 0x234)) - (i64.store offset=0x235 align=1 (i32.const 0) (local.get 0x235)) - (i64.store offset=0x236 align=1 (i32.const 0) (local.get 0x236)) - (i64.store offset=0x237 align=1 (i32.const 0) (local.get 0x237)) - (i64.store offset=0x238 align=1 (i32.const 0) (local.get 0x238)) - (i64.store offset=0x239 align=1 (i32.const 0) (local.get 0x239)) - (i64.store offset=0x23a align=1 (i32.const 0) (local.get 0x23a)) - (i64.store offset=0x23b align=1 (i32.const 0) (local.get 0x23b)) - (i64.store offset=0x23c align=1 (i32.const 0) (local.get 0x23c)) - (i64.store offset=0x23d align=1 (i32.const 0) (local.get 0x23d)) - (i64.store offset=0x23e align=1 (i32.const 0) (local.get 0x23e)) - (i64.store offset=0x23f align=1 (i32.const 0) (local.get 0x23f)) - (i64.store offset=0x240 align=1 (i32.const 0) (local.get 0x240)) - (i64.store offset=0x241 align=1 (i32.const 0) (local.get 0x241)) - (i64.store offset=0x242 align=1 (i32.const 0) (local.get 0x242)) - (i64.store offset=0x243 align=1 (i32.const 0) (local.get 0x243)) - (i64.store offset=0x244 align=1 (i32.const 0) (local.get 0x244)) - (i64.store offset=0x245 align=1 (i32.const 0) (local.get 0x245)) - (i64.store offset=0x246 align=1 (i32.const 0) (local.get 0x246)) - (i64.store offset=0x247 align=1 (i32.const 0) (local.get 0x247)) - (i64.store offset=0x248 align=1 (i32.const 0) (local.get 0x248)) - (i64.store offset=0x249 align=1 (i32.const 0) (local.get 0x249)) - (i64.store offset=0x24a align=1 (i32.const 0) (local.get 0x24a)) - (i64.store offset=0x24b align=1 (i32.const 0) (local.get 0x24b)) - (i64.store offset=0x24c align=1 (i32.const 0) (local.get 0x24c)) - (i64.store offset=0x24d align=1 (i32.const 0) (local.get 0x24d)) - (i64.store offset=0x24e align=1 (i32.const 0) (local.get 0x24e)) - (i64.store offset=0x24f align=1 (i32.const 0) (local.get 0x24f)) - (i64.store offset=0x250 align=1 (i32.const 0) (local.get 0x250)) - (i64.store offset=0x251 align=1 (i32.const 0) (local.get 0x251)) - (i64.store offset=0x252 align=1 (i32.const 0) (local.get 0x252)) - (i64.store offset=0x253 align=1 (i32.const 0) (local.get 0x253)) - (i64.store offset=0x254 align=1 (i32.const 0) (local.get 0x254)) - (i64.store offset=0x255 align=1 (i32.const 0) (local.get 0x255)) - (i64.store offset=0x256 align=1 (i32.const 0) (local.get 0x256)) - (i64.store offset=0x257 align=1 (i32.const 0) (local.get 0x257)) - (i64.store offset=0x258 align=1 (i32.const 0) (local.get 0x258)) - (i64.store offset=0x259 align=1 (i32.const 0) (local.get 0x259)) - (i64.store offset=0x25a align=1 (i32.const 0) (local.get 0x25a)) - (i64.store offset=0x25b align=1 (i32.const 0) (local.get 0x25b)) - (i64.store offset=0x25c align=1 (i32.const 0) (local.get 0x25c)) - (i64.store offset=0x25d align=1 (i32.const 0) (local.get 0x25d)) - (i64.store offset=0x25e align=1 (i32.const 0) (local.get 0x25e)) - (i64.store offset=0x25f align=1 (i32.const 0) (local.get 0x25f)) - (i64.store offset=0x260 align=1 (i32.const 0) (local.get 0x260)) - (i64.store offset=0x261 align=1 (i32.const 0) (local.get 0x261)) - (i64.store offset=0x262 align=1 (i32.const 0) (local.get 0x262)) - (i64.store offset=0x263 align=1 (i32.const 0) (local.get 0x263)) - (i64.store offset=0x264 align=1 (i32.const 0) (local.get 0x264)) - (i64.store offset=0x265 align=1 (i32.const 0) (local.get 0x265)) - (i64.store offset=0x266 align=1 (i32.const 0) (local.get 0x266)) - (i64.store offset=0x267 align=1 (i32.const 0) (local.get 0x267)) - (i64.store offset=0x268 align=1 (i32.const 0) (local.get 0x268)) - (i64.store offset=0x269 align=1 (i32.const 0) (local.get 0x269)) - (i64.store offset=0x26a align=1 (i32.const 0) (local.get 0x26a)) - (i64.store offset=0x26b align=1 (i32.const 0) (local.get 0x26b)) - (i64.store offset=0x26c align=1 (i32.const 0) (local.get 0x26c)) - (i64.store offset=0x26d align=1 (i32.const 0) (local.get 0x26d)) - (i64.store offset=0x26e align=1 (i32.const 0) (local.get 0x26e)) - (i64.store offset=0x26f align=1 (i32.const 0) (local.get 0x26f)) - (i64.store offset=0x270 align=1 (i32.const 0) (local.get 0x270)) - (i64.store offset=0x271 align=1 (i32.const 0) (local.get 0x271)) - (i64.store offset=0x272 align=1 (i32.const 0) (local.get 0x272)) - (i64.store offset=0x273 align=1 (i32.const 0) (local.get 0x273)) - (i64.store offset=0x274 align=1 (i32.const 0) (local.get 0x274)) - (i64.store offset=0x275 align=1 (i32.const 0) (local.get 0x275)) - (i64.store offset=0x276 align=1 (i32.const 0) (local.get 0x276)) - (i64.store offset=0x277 align=1 (i32.const 0) (local.get 0x277)) - (i64.store offset=0x278 align=1 (i32.const 0) (local.get 0x278)) - (i64.store offset=0x279 align=1 (i32.const 0) (local.get 0x279)) - (i64.store offset=0x27a align=1 (i32.const 0) (local.get 0x27a)) - (i64.store offset=0x27b align=1 (i32.const 0) (local.get 0x27b)) - (i64.store offset=0x27c align=1 (i32.const 0) (local.get 0x27c)) - (i64.store offset=0x27d align=1 (i32.const 0) (local.get 0x27d)) - (i64.store offset=0x27e align=1 (i32.const 0) (local.get 0x27e)) - (i64.store offset=0x27f align=1 (i32.const 0) (local.get 0x27f)) - (i64.store offset=0x280 align=1 (i32.const 0) (local.get 0x280)) - (i64.store offset=0x281 align=1 (i32.const 0) (local.get 0x281)) - (i64.store offset=0x282 align=1 (i32.const 0) (local.get 0x282)) - (i64.store offset=0x283 align=1 (i32.const 0) (local.get 0x283)) - (i64.store offset=0x284 align=1 (i32.const 0) (local.get 0x284)) - (i64.store offset=0x285 align=1 (i32.const 0) (local.get 0x285)) - (i64.store offset=0x286 align=1 (i32.const 0) (local.get 0x286)) - (i64.store offset=0x287 align=1 (i32.const 0) (local.get 0x287)) - (i64.store offset=0x288 align=1 (i32.const 0) (local.get 0x288)) - (i64.store offset=0x289 align=1 (i32.const 0) (local.get 0x289)) - (i64.store offset=0x28a align=1 (i32.const 0) (local.get 0x28a)) - (i64.store offset=0x28b align=1 (i32.const 0) (local.get 0x28b)) - (i64.store offset=0x28c align=1 (i32.const 0) (local.get 0x28c)) - (i64.store offset=0x28d align=1 (i32.const 0) (local.get 0x28d)) - (i64.store offset=0x28e align=1 (i32.const 0) (local.get 0x28e)) - (i64.store offset=0x28f align=1 (i32.const 0) (local.get 0x28f)) - (i64.store offset=0x290 align=1 (i32.const 0) (local.get 0x290)) - (i64.store offset=0x291 align=1 (i32.const 0) (local.get 0x291)) - (i64.store offset=0x292 align=1 (i32.const 0) (local.get 0x292)) - (i64.store offset=0x293 align=1 (i32.const 0) (local.get 0x293)) - (i64.store offset=0x294 align=1 (i32.const 0) (local.get 0x294)) - (i64.store offset=0x295 align=1 (i32.const 0) (local.get 0x295)) - (i64.store offset=0x296 align=1 (i32.const 0) (local.get 0x296)) - (i64.store offset=0x297 align=1 (i32.const 0) (local.get 0x297)) - (i64.store offset=0x298 align=1 (i32.const 0) (local.get 0x298)) - (i64.store offset=0x299 align=1 (i32.const 0) (local.get 0x299)) - (i64.store offset=0x29a align=1 (i32.const 0) (local.get 0x29a)) - (i64.store offset=0x29b align=1 (i32.const 0) (local.get 0x29b)) - (i64.store offset=0x29c align=1 (i32.const 0) (local.get 0x29c)) - (i64.store offset=0x29d align=1 (i32.const 0) (local.get 0x29d)) - (i64.store offset=0x29e align=1 (i32.const 0) (local.get 0x29e)) - (i64.store offset=0x29f align=1 (i32.const 0) (local.get 0x29f)) - (i64.store offset=0x2a0 align=1 (i32.const 0) (local.get 0x2a0)) - (i64.store offset=0x2a1 align=1 (i32.const 0) (local.get 0x2a1)) - (i64.store offset=0x2a2 align=1 (i32.const 0) (local.get 0x2a2)) - (i64.store offset=0x2a3 align=1 (i32.const 0) (local.get 0x2a3)) - (i64.store offset=0x2a4 align=1 (i32.const 0) (local.get 0x2a4)) - (i64.store offset=0x2a5 align=1 (i32.const 0) (local.get 0x2a5)) - (i64.store offset=0x2a6 align=1 (i32.const 0) (local.get 0x2a6)) - (i64.store offset=0x2a7 align=1 (i32.const 0) (local.get 0x2a7)) - (i64.store offset=0x2a8 align=1 (i32.const 0) (local.get 0x2a8)) - (i64.store offset=0x2a9 align=1 (i32.const 0) (local.get 0x2a9)) - (i64.store offset=0x2aa align=1 (i32.const 0) (local.get 0x2aa)) - (i64.store offset=0x2ab align=1 (i32.const 0) (local.get 0x2ab)) - (i64.store offset=0x2ac align=1 (i32.const 0) (local.get 0x2ac)) - (i64.store offset=0x2ad align=1 (i32.const 0) (local.get 0x2ad)) - (i64.store offset=0x2ae align=1 (i32.const 0) (local.get 0x2ae)) - (i64.store offset=0x2af align=1 (i32.const 0) (local.get 0x2af)) - (i64.store offset=0x2b0 align=1 (i32.const 0) (local.get 0x2b0)) - (i64.store offset=0x2b1 align=1 (i32.const 0) (local.get 0x2b1)) - (i64.store offset=0x2b2 align=1 (i32.const 0) (local.get 0x2b2)) - (i64.store offset=0x2b3 align=1 (i32.const 0) (local.get 0x2b3)) - (i64.store offset=0x2b4 align=1 (i32.const 0) (local.get 0x2b4)) - (i64.store offset=0x2b5 align=1 (i32.const 0) (local.get 0x2b5)) - (i64.store offset=0x2b6 align=1 (i32.const 0) (local.get 0x2b6)) - (i64.store offset=0x2b7 align=1 (i32.const 0) (local.get 0x2b7)) - (i64.store offset=0x2b8 align=1 (i32.const 0) (local.get 0x2b8)) - (i64.store offset=0x2b9 align=1 (i32.const 0) (local.get 0x2b9)) - (i64.store offset=0x2ba align=1 (i32.const 0) (local.get 0x2ba)) - (i64.store offset=0x2bb align=1 (i32.const 0) (local.get 0x2bb)) - (i64.store offset=0x2bc align=1 (i32.const 0) (local.get 0x2bc)) - (i64.store offset=0x2bd align=1 (i32.const 0) (local.get 0x2bd)) - (i64.store offset=0x2be align=1 (i32.const 0) (local.get 0x2be)) - (i64.store offset=0x2bf align=1 (i32.const 0) (local.get 0x2bf)) - (i64.store offset=0x2c0 align=1 (i32.const 0) (local.get 0x2c0)) - (i64.store offset=0x2c1 align=1 (i32.const 0) (local.get 0x2c1)) - (i64.store offset=0x2c2 align=1 (i32.const 0) (local.get 0x2c2)) - (i64.store offset=0x2c3 align=1 (i32.const 0) (local.get 0x2c3)) - (i64.store offset=0x2c4 align=1 (i32.const 0) (local.get 0x2c4)) - (i64.store offset=0x2c5 align=1 (i32.const 0) (local.get 0x2c5)) - (i64.store offset=0x2c6 align=1 (i32.const 0) (local.get 0x2c6)) - (i64.store offset=0x2c7 align=1 (i32.const 0) (local.get 0x2c7)) - (i64.store offset=0x2c8 align=1 (i32.const 0) (local.get 0x2c8)) - (i64.store offset=0x2c9 align=1 (i32.const 0) (local.get 0x2c9)) - (i64.store offset=0x2ca align=1 (i32.const 0) (local.get 0x2ca)) - (i64.store offset=0x2cb align=1 (i32.const 0) (local.get 0x2cb)) - (i64.store offset=0x2cc align=1 (i32.const 0) (local.get 0x2cc)) - (i64.store offset=0x2cd align=1 (i32.const 0) (local.get 0x2cd)) - (i64.store offset=0x2ce align=1 (i32.const 0) (local.get 0x2ce)) - (i64.store offset=0x2cf align=1 (i32.const 0) (local.get 0x2cf)) - (i64.store offset=0x2d0 align=1 (i32.const 0) (local.get 0x2d0)) - (i64.store offset=0x2d1 align=1 (i32.const 0) (local.get 0x2d1)) - (i64.store offset=0x2d2 align=1 (i32.const 0) (local.get 0x2d2)) - (i64.store offset=0x2d3 align=1 (i32.const 0) (local.get 0x2d3)) - (i64.store offset=0x2d4 align=1 (i32.const 0) (local.get 0x2d4)) - (i64.store offset=0x2d5 align=1 (i32.const 0) (local.get 0x2d5)) - (i64.store offset=0x2d6 align=1 (i32.const 0) (local.get 0x2d6)) - (i64.store offset=0x2d7 align=1 (i32.const 0) (local.get 0x2d7)) - (i64.store offset=0x2d8 align=1 (i32.const 0) (local.get 0x2d8)) - (i64.store offset=0x2d9 align=1 (i32.const 0) (local.get 0x2d9)) - (i64.store offset=0x2da align=1 (i32.const 0) (local.get 0x2da)) - (i64.store offset=0x2db align=1 (i32.const 0) (local.get 0x2db)) - (i64.store offset=0x2dc align=1 (i32.const 0) (local.get 0x2dc)) - (i64.store offset=0x2dd align=1 (i32.const 0) (local.get 0x2dd)) - (i64.store offset=0x2de align=1 (i32.const 0) (local.get 0x2de)) - (i64.store offset=0x2df align=1 (i32.const 0) (local.get 0x2df)) - (i64.store offset=0x2e0 align=1 (i32.const 0) (local.get 0x2e0)) - (i64.store offset=0x2e1 align=1 (i32.const 0) (local.get 0x2e1)) - (i64.store offset=0x2e2 align=1 (i32.const 0) (local.get 0x2e2)) - (i64.store offset=0x2e3 align=1 (i32.const 0) (local.get 0x2e3)) - (i64.store offset=0x2e4 align=1 (i32.const 0) (local.get 0x2e4)) - (i64.store offset=0x2e5 align=1 (i32.const 0) (local.get 0x2e5)) - (i64.store offset=0x2e6 align=1 (i32.const 0) (local.get 0x2e6)) - (i64.store offset=0x2e7 align=1 (i32.const 0) (local.get 0x2e7)) - (i64.store offset=0x2e8 align=1 (i32.const 0) (local.get 0x2e8)) - (i64.store offset=0x2e9 align=1 (i32.const 0) (local.get 0x2e9)) - (i64.store offset=0x2ea align=1 (i32.const 0) (local.get 0x2ea)) - (i64.store offset=0x2eb align=1 (i32.const 0) (local.get 0x2eb)) - (i64.store offset=0x2ec align=1 (i32.const 0) (local.get 0x2ec)) - (i64.store offset=0x2ed align=1 (i32.const 0) (local.get 0x2ed)) - (i64.store offset=0x2ee align=1 (i32.const 0) (local.get 0x2ee)) - (i64.store offset=0x2ef align=1 (i32.const 0) (local.get 0x2ef)) - (i64.store offset=0x2f0 align=1 (i32.const 0) (local.get 0x2f0)) - (i64.store offset=0x2f1 align=1 (i32.const 0) (local.get 0x2f1)) - (i64.store offset=0x2f2 align=1 (i32.const 0) (local.get 0x2f2)) - (i64.store offset=0x2f3 align=1 (i32.const 0) (local.get 0x2f3)) - (i64.store offset=0x2f4 align=1 (i32.const 0) (local.get 0x2f4)) - (i64.store offset=0x2f5 align=1 (i32.const 0) (local.get 0x2f5)) - (i64.store offset=0x2f6 align=1 (i32.const 0) (local.get 0x2f6)) - (i64.store offset=0x2f7 align=1 (i32.const 0) (local.get 0x2f7)) - (i64.store offset=0x2f8 align=1 (i32.const 0) (local.get 0x2f8)) - (i64.store offset=0x2f9 align=1 (i32.const 0) (local.get 0x2f9)) - (i64.store offset=0x2fa align=1 (i32.const 0) (local.get 0x2fa)) - (i64.store offset=0x2fb align=1 (i32.const 0) (local.get 0x2fb)) - (i64.store offset=0x2fc align=1 (i32.const 0) (local.get 0x2fc)) - (i64.store offset=0x2fd align=1 (i32.const 0) (local.get 0x2fd)) - (i64.store offset=0x2fe align=1 (i32.const 0) (local.get 0x2fe)) - (i64.store offset=0x2ff align=1 (i32.const 0) (local.get 0x2ff)) - (i64.store offset=0x300 align=1 (i32.const 0) (local.get 0x300)) - (i64.store offset=0x301 align=1 (i32.const 0) (local.get 0x301)) - (i64.store offset=0x302 align=1 (i32.const 0) (local.get 0x302)) - (i64.store offset=0x303 align=1 (i32.const 0) (local.get 0x303)) - (i64.store offset=0x304 align=1 (i32.const 0) (local.get 0x304)) - (i64.store offset=0x305 align=1 (i32.const 0) (local.get 0x305)) - (i64.store offset=0x306 align=1 (i32.const 0) (local.get 0x306)) - (i64.store offset=0x307 align=1 (i32.const 0) (local.get 0x307)) - (i64.store offset=0x308 align=1 (i32.const 0) (local.get 0x308)) - (i64.store offset=0x309 align=1 (i32.const 0) (local.get 0x309)) - (i64.store offset=0x30a align=1 (i32.const 0) (local.get 0x30a)) - (i64.store offset=0x30b align=1 (i32.const 0) (local.get 0x30b)) - (i64.store offset=0x30c align=1 (i32.const 0) (local.get 0x30c)) - (i64.store offset=0x30d align=1 (i32.const 0) (local.get 0x30d)) - (i64.store offset=0x30e align=1 (i32.const 0) (local.get 0x30e)) - (i64.store offset=0x30f align=1 (i32.const 0) (local.get 0x30f)) - (i64.store offset=0x310 align=1 (i32.const 0) (local.get 0x310)) - (i64.store offset=0x311 align=1 (i32.const 0) (local.get 0x311)) - (i64.store offset=0x312 align=1 (i32.const 0) (local.get 0x312)) - (i64.store offset=0x313 align=1 (i32.const 0) (local.get 0x313)) - (i64.store offset=0x314 align=1 (i32.const 0) (local.get 0x314)) - (i64.store offset=0x315 align=1 (i32.const 0) (local.get 0x315)) - (i64.store offset=0x316 align=1 (i32.const 0) (local.get 0x316)) - (i64.store offset=0x317 align=1 (i32.const 0) (local.get 0x317)) - (i64.store offset=0x318 align=1 (i32.const 0) (local.get 0x318)) - (i64.store offset=0x319 align=1 (i32.const 0) (local.get 0x319)) - (i64.store offset=0x31a align=1 (i32.const 0) (local.get 0x31a)) - (i64.store offset=0x31b align=1 (i32.const 0) (local.get 0x31b)) - (i64.store offset=0x31c align=1 (i32.const 0) (local.get 0x31c)) - (i64.store offset=0x31d align=1 (i32.const 0) (local.get 0x31d)) - (i64.store offset=0x31e align=1 (i32.const 0) (local.get 0x31e)) - (i64.store offset=0x31f align=1 (i32.const 0) (local.get 0x31f)) - (i64.store offset=0x320 align=1 (i32.const 0) (local.get 0x320)) - (i64.store offset=0x321 align=1 (i32.const 0) (local.get 0x321)) - (i64.store offset=0x322 align=1 (i32.const 0) (local.get 0x322)) - (i64.store offset=0x323 align=1 (i32.const 0) (local.get 0x323)) - (i64.store offset=0x324 align=1 (i32.const 0) (local.get 0x324)) - (i64.store offset=0x325 align=1 (i32.const 0) (local.get 0x325)) - (i64.store offset=0x326 align=1 (i32.const 0) (local.get 0x326)) - (i64.store offset=0x327 align=1 (i32.const 0) (local.get 0x327)) - (i64.store offset=0x328 align=1 (i32.const 0) (local.get 0x328)) - (i64.store offset=0x329 align=1 (i32.const 0) (local.get 0x329)) - (i64.store offset=0x32a align=1 (i32.const 0) (local.get 0x32a)) - (i64.store offset=0x32b align=1 (i32.const 0) (local.get 0x32b)) - (i64.store offset=0x32c align=1 (i32.const 0) (local.get 0x32c)) - (i64.store offset=0x32d align=1 (i32.const 0) (local.get 0x32d)) - (i64.store offset=0x32e align=1 (i32.const 0) (local.get 0x32e)) - (i64.store offset=0x32f align=1 (i32.const 0) (local.get 0x32f)) - (i64.store offset=0x330 align=1 (i32.const 0) (local.get 0x330)) - (i64.store offset=0x331 align=1 (i32.const 0) (local.get 0x331)) - (i64.store offset=0x332 align=1 (i32.const 0) (local.get 0x332)) - (i64.store offset=0x333 align=1 (i32.const 0) (local.get 0x333)) - (i64.store offset=0x334 align=1 (i32.const 0) (local.get 0x334)) - (i64.store offset=0x335 align=1 (i32.const 0) (local.get 0x335)) - (i64.store offset=0x336 align=1 (i32.const 0) (local.get 0x336)) - (i64.store offset=0x337 align=1 (i32.const 0) (local.get 0x337)) - (i64.store offset=0x338 align=1 (i32.const 0) (local.get 0x338)) - (i64.store offset=0x339 align=1 (i32.const 0) (local.get 0x339)) - (i64.store offset=0x33a align=1 (i32.const 0) (local.get 0x33a)) - (i64.store offset=0x33b align=1 (i32.const 0) (local.get 0x33b)) - (i64.store offset=0x33c align=1 (i32.const 0) (local.get 0x33c)) - (i64.store offset=0x33d align=1 (i32.const 0) (local.get 0x33d)) - (i64.store offset=0x33e align=1 (i32.const 0) (local.get 0x33e)) - (i64.store offset=0x33f align=1 (i32.const 0) (local.get 0x33f)) - (i64.store offset=0x340 align=1 (i32.const 0) (local.get 0x340)) - (i64.store offset=0x341 align=1 (i32.const 0) (local.get 0x341)) - (i64.store offset=0x342 align=1 (i32.const 0) (local.get 0x342)) - (i64.store offset=0x343 align=1 (i32.const 0) (local.get 0x343)) - (i64.store offset=0x344 align=1 (i32.const 0) (local.get 0x344)) - (i64.store offset=0x345 align=1 (i32.const 0) (local.get 0x345)) - (i64.store offset=0x346 align=1 (i32.const 0) (local.get 0x346)) - (i64.store offset=0x347 align=1 (i32.const 0) (local.get 0x347)) - (i64.store offset=0x348 align=1 (i32.const 0) (local.get 0x348)) - (i64.store offset=0x349 align=1 (i32.const 0) (local.get 0x349)) - (i64.store offset=0x34a align=1 (i32.const 0) (local.get 0x34a)) - (i64.store offset=0x34b align=1 (i32.const 0) (local.get 0x34b)) - (i64.store offset=0x34c align=1 (i32.const 0) (local.get 0x34c)) - (i64.store offset=0x34d align=1 (i32.const 0) (local.get 0x34d)) - (i64.store offset=0x34e align=1 (i32.const 0) (local.get 0x34e)) - (i64.store offset=0x34f align=1 (i32.const 0) (local.get 0x34f)) - (i64.store offset=0x350 align=1 (i32.const 0) (local.get 0x350)) - (i64.store offset=0x351 align=1 (i32.const 0) (local.get 0x351)) - (i64.store offset=0x352 align=1 (i32.const 0) (local.get 0x352)) - (i64.store offset=0x353 align=1 (i32.const 0) (local.get 0x353)) - (i64.store offset=0x354 align=1 (i32.const 0) (local.get 0x354)) - (i64.store offset=0x355 align=1 (i32.const 0) (local.get 0x355)) - (i64.store offset=0x356 align=1 (i32.const 0) (local.get 0x356)) - (i64.store offset=0x357 align=1 (i32.const 0) (local.get 0x357)) - (i64.store offset=0x358 align=1 (i32.const 0) (local.get 0x358)) - (i64.store offset=0x359 align=1 (i32.const 0) (local.get 0x359)) - (i64.store offset=0x35a align=1 (i32.const 0) (local.get 0x35a)) - (i64.store offset=0x35b align=1 (i32.const 0) (local.get 0x35b)) - (i64.store offset=0x35c align=1 (i32.const 0) (local.get 0x35c)) - (i64.store offset=0x35d align=1 (i32.const 0) (local.get 0x35d)) - (i64.store offset=0x35e align=1 (i32.const 0) (local.get 0x35e)) - (i64.store offset=0x35f align=1 (i32.const 0) (local.get 0x35f)) - (i64.store offset=0x360 align=1 (i32.const 0) (local.get 0x360)) - (i64.store offset=0x361 align=1 (i32.const 0) (local.get 0x361)) - (i64.store offset=0x362 align=1 (i32.const 0) (local.get 0x362)) - (i64.store offset=0x363 align=1 (i32.const 0) (local.get 0x363)) - (i64.store offset=0x364 align=1 (i32.const 0) (local.get 0x364)) - (i64.store offset=0x365 align=1 (i32.const 0) (local.get 0x365)) - (i64.store offset=0x366 align=1 (i32.const 0) (local.get 0x366)) - (i64.store offset=0x367 align=1 (i32.const 0) (local.get 0x367)) - (i64.store offset=0x368 align=1 (i32.const 0) (local.get 0x368)) - (i64.store offset=0x369 align=1 (i32.const 0) (local.get 0x369)) - (i64.store offset=0x36a align=1 (i32.const 0) (local.get 0x36a)) - (i64.store offset=0x36b align=1 (i32.const 0) (local.get 0x36b)) - (i64.store offset=0x36c align=1 (i32.const 0) (local.get 0x36c)) - (i64.store offset=0x36d align=1 (i32.const 0) (local.get 0x36d)) - (i64.store offset=0x36e align=1 (i32.const 0) (local.get 0x36e)) - (i64.store offset=0x36f align=1 (i32.const 0) (local.get 0x36f)) - (i64.store offset=0x370 align=1 (i32.const 0) (local.get 0x370)) - (i64.store offset=0x371 align=1 (i32.const 0) (local.get 0x371)) - (i64.store offset=0x372 align=1 (i32.const 0) (local.get 0x372)) - (i64.store offset=0x373 align=1 (i32.const 0) (local.get 0x373)) - (i64.store offset=0x374 align=1 (i32.const 0) (local.get 0x374)) - (i64.store offset=0x375 align=1 (i32.const 0) (local.get 0x375)) - (i64.store offset=0x376 align=1 (i32.const 0) (local.get 0x376)) - (i64.store offset=0x377 align=1 (i32.const 0) (local.get 0x377)) - (i64.store offset=0x378 align=1 (i32.const 0) (local.get 0x378)) - (i64.store offset=0x379 align=1 (i32.const 0) (local.get 0x379)) - (i64.store offset=0x37a align=1 (i32.const 0) (local.get 0x37a)) - (i64.store offset=0x37b align=1 (i32.const 0) (local.get 0x37b)) - (i64.store offset=0x37c align=1 (i32.const 0) (local.get 0x37c)) - (i64.store offset=0x37d align=1 (i32.const 0) (local.get 0x37d)) - (i64.store offset=0x37e align=1 (i32.const 0) (local.get 0x37e)) - (i64.store offset=0x37f align=1 (i32.const 0) (local.get 0x37f)) - (i64.store offset=0x380 align=1 (i32.const 0) (local.get 0x380)) - (i64.store offset=0x381 align=1 (i32.const 0) (local.get 0x381)) - (i64.store offset=0x382 align=1 (i32.const 0) (local.get 0x382)) - (i64.store offset=0x383 align=1 (i32.const 0) (local.get 0x383)) - (i64.store offset=0x384 align=1 (i32.const 0) (local.get 0x384)) - (i64.store offset=0x385 align=1 (i32.const 0) (local.get 0x385)) - (i64.store offset=0x386 align=1 (i32.const 0) (local.get 0x386)) - (i64.store offset=0x387 align=1 (i32.const 0) (local.get 0x387)) - (i64.store offset=0x388 align=1 (i32.const 0) (local.get 0x388)) - (i64.store offset=0x389 align=1 (i32.const 0) (local.get 0x389)) - (i64.store offset=0x38a align=1 (i32.const 0) (local.get 0x38a)) - (i64.store offset=0x38b align=1 (i32.const 0) (local.get 0x38b)) - (i64.store offset=0x38c align=1 (i32.const 0) (local.get 0x38c)) - (i64.store offset=0x38d align=1 (i32.const 0) (local.get 0x38d)) - (i64.store offset=0x38e align=1 (i32.const 0) (local.get 0x38e)) - (i64.store offset=0x38f align=1 (i32.const 0) (local.get 0x38f)) - (i64.store offset=0x390 align=1 (i32.const 0) (local.get 0x390)) - (i64.store offset=0x391 align=1 (i32.const 0) (local.get 0x391)) - (i64.store offset=0x392 align=1 (i32.const 0) (local.get 0x392)) - (i64.store offset=0x393 align=1 (i32.const 0) (local.get 0x393)) - (i64.store offset=0x394 align=1 (i32.const 0) (local.get 0x394)) - (i64.store offset=0x395 align=1 (i32.const 0) (local.get 0x395)) - (i64.store offset=0x396 align=1 (i32.const 0) (local.get 0x396)) - (i64.store offset=0x397 align=1 (i32.const 0) (local.get 0x397)) - (i64.store offset=0x398 align=1 (i32.const 0) (local.get 0x398)) - (i64.store offset=0x399 align=1 (i32.const 0) (local.get 0x399)) - (i64.store offset=0x39a align=1 (i32.const 0) (local.get 0x39a)) - (i64.store offset=0x39b align=1 (i32.const 0) (local.get 0x39b)) - (i64.store offset=0x39c align=1 (i32.const 0) (local.get 0x39c)) - (i64.store offset=0x39d align=1 (i32.const 0) (local.get 0x39d)) - (i64.store offset=0x39e align=1 (i32.const 0) (local.get 0x39e)) - (i64.store offset=0x39f align=1 (i32.const 0) (local.get 0x39f)) - (i64.store offset=0x3a0 align=1 (i32.const 0) (local.get 0x3a0)) - (i64.store offset=0x3a1 align=1 (i32.const 0) (local.get 0x3a1)) - (i64.store offset=0x3a2 align=1 (i32.const 0) (local.get 0x3a2)) - (i64.store offset=0x3a3 align=1 (i32.const 0) (local.get 0x3a3)) - (i64.store offset=0x3a4 align=1 (i32.const 0) (local.get 0x3a4)) - (i64.store offset=0x3a5 align=1 (i32.const 0) (local.get 0x3a5)) - (i64.store offset=0x3a6 align=1 (i32.const 0) (local.get 0x3a6)) - (i64.store offset=0x3a7 align=1 (i32.const 0) (local.get 0x3a7)) - (i64.store offset=0x3a8 align=1 (i32.const 0) (local.get 0x3a8)) - (i64.store offset=0x3a9 align=1 (i32.const 0) (local.get 0x3a9)) - (i64.store offset=0x3aa align=1 (i32.const 0) (local.get 0x3aa)) - (i64.store offset=0x3ab align=1 (i32.const 0) (local.get 0x3ab)) - (i64.store offset=0x3ac align=1 (i32.const 0) (local.get 0x3ac)) - (i64.store offset=0x3ad align=1 (i32.const 0) (local.get 0x3ad)) - (i64.store offset=0x3ae align=1 (i32.const 0) (local.get 0x3ae)) - (i64.store offset=0x3af align=1 (i32.const 0) (local.get 0x3af)) - (i64.store offset=0x3b0 align=1 (i32.const 0) (local.get 0x3b0)) - (i64.store offset=0x3b1 align=1 (i32.const 0) (local.get 0x3b1)) - (i64.store offset=0x3b2 align=1 (i32.const 0) (local.get 0x3b2)) - (i64.store offset=0x3b3 align=1 (i32.const 0) (local.get 0x3b3)) - (i64.store offset=0x3b4 align=1 (i32.const 0) (local.get 0x3b4)) - (i64.store offset=0x3b5 align=1 (i32.const 0) (local.get 0x3b5)) - (i64.store offset=0x3b6 align=1 (i32.const 0) (local.get 0x3b6)) - (i64.store offset=0x3b7 align=1 (i32.const 0) (local.get 0x3b7)) - (i64.store offset=0x3b8 align=1 (i32.const 0) (local.get 0x3b8)) - (i64.store offset=0x3b9 align=1 (i32.const 0) (local.get 0x3b9)) - (i64.store offset=0x3ba align=1 (i32.const 0) (local.get 0x3ba)) - (i64.store offset=0x3bb align=1 (i32.const 0) (local.get 0x3bb)) - (i64.store offset=0x3bc align=1 (i32.const 0) (local.get 0x3bc)) - (i64.store offset=0x3bd align=1 (i32.const 0) (local.get 0x3bd)) - (i64.store offset=0x3be align=1 (i32.const 0) (local.get 0x3be)) - (i64.store offset=0x3bf align=1 (i32.const 0) (local.get 0x3bf)) - (i64.store offset=0x3c0 align=1 (i32.const 0) (local.get 0x3c0)) - (i64.store offset=0x3c1 align=1 (i32.const 0) (local.get 0x3c1)) - (i64.store offset=0x3c2 align=1 (i32.const 0) (local.get 0x3c2)) - (i64.store offset=0x3c3 align=1 (i32.const 0) (local.get 0x3c3)) - (i64.store offset=0x3c4 align=1 (i32.const 0) (local.get 0x3c4)) - (i64.store offset=0x3c5 align=1 (i32.const 0) (local.get 0x3c5)) - (i64.store offset=0x3c6 align=1 (i32.const 0) (local.get 0x3c6)) - (i64.store offset=0x3c7 align=1 (i32.const 0) (local.get 0x3c7)) - (i64.store offset=0x3c8 align=1 (i32.const 0) (local.get 0x3c8)) - (i64.store offset=0x3c9 align=1 (i32.const 0) (local.get 0x3c9)) - (i64.store offset=0x3ca align=1 (i32.const 0) (local.get 0x3ca)) - (i64.store offset=0x3cb align=1 (i32.const 0) (local.get 0x3cb)) - (i64.store offset=0x3cc align=1 (i32.const 0) (local.get 0x3cc)) - (i64.store offset=0x3cd align=1 (i32.const 0) (local.get 0x3cd)) - (i64.store offset=0x3ce align=1 (i32.const 0) (local.get 0x3ce)) - (i64.store offset=0x3cf align=1 (i32.const 0) (local.get 0x3cf)) - (i64.store offset=0x3d0 align=1 (i32.const 0) (local.get 0x3d0)) - (i64.store offset=0x3d1 align=1 (i32.const 0) (local.get 0x3d1)) - (i64.store offset=0x3d2 align=1 (i32.const 0) (local.get 0x3d2)) - (i64.store offset=0x3d3 align=1 (i32.const 0) (local.get 0x3d3)) - (i64.store offset=0x3d4 align=1 (i32.const 0) (local.get 0x3d4)) - (i64.store offset=0x3d5 align=1 (i32.const 0) (local.get 0x3d5)) - (i64.store offset=0x3d6 align=1 (i32.const 0) (local.get 0x3d6)) - (i64.store offset=0x3d7 align=1 (i32.const 0) (local.get 0x3d7)) - (i64.store offset=0x3d8 align=1 (i32.const 0) (local.get 0x3d8)) - (i64.store offset=0x3d9 align=1 (i32.const 0) (local.get 0x3d9)) - (i64.store offset=0x3da align=1 (i32.const 0) (local.get 0x3da)) - (i64.store offset=0x3db align=1 (i32.const 0) (local.get 0x3db)) - (i64.store offset=0x3dc align=1 (i32.const 0) (local.get 0x3dc)) - (i64.store offset=0x3dd align=1 (i32.const 0) (local.get 0x3dd)) - (i64.store offset=0x3de align=1 (i32.const 0) (local.get 0x3de)) - (i64.store offset=0x3df align=1 (i32.const 0) (local.get 0x3df)) - (i64.store offset=0x3e0 align=1 (i32.const 0) (local.get 0x3e0)) - (i64.store offset=0x3e1 align=1 (i32.const 0) (local.get 0x3e1)) - (i64.store offset=0x3e2 align=1 (i32.const 0) (local.get 0x3e2)) - (i64.store offset=0x3e3 align=1 (i32.const 0) (local.get 0x3e3)) - (i64.store offset=0x3e4 align=1 (i32.const 0) (local.get 0x3e4)) - (i64.store offset=0x3e5 align=1 (i32.const 0) (local.get 0x3e5)) - (i64.store offset=0x3e6 align=1 (i32.const 0) (local.get 0x3e6)) - (i64.store offset=0x3e7 align=1 (i32.const 0) (local.get 0x3e7)) - (i64.store offset=0x3e8 align=1 (i32.const 0) (local.get 0x3e8)) - (i64.store offset=0x3e9 align=1 (i32.const 0) (local.get 0x3e9)) - (i64.store offset=0x3ea align=1 (i32.const 0) (local.get 0x3ea)) - (i64.store offset=0x3eb align=1 (i32.const 0) (local.get 0x3eb)) - (i64.store offset=0x3ec align=1 (i32.const 0) (local.get 0x3ec)) - (i64.store offset=0x3ed align=1 (i32.const 0) (local.get 0x3ed)) - (i64.store offset=0x3ee align=1 (i32.const 0) (local.get 0x3ee)) - (i64.store offset=0x3ef align=1 (i32.const 0) (local.get 0x3ef)) - (i64.store offset=0x3f0 align=1 (i32.const 0) (local.get 0x3f0)) - (i64.store offset=0x3f1 align=1 (i32.const 0) (local.get 0x3f1)) - (i64.store offset=0x3f2 align=1 (i32.const 0) (local.get 0x3f2)) - (i64.store offset=0x3f3 align=1 (i32.const 0) (local.get 0x3f3)) - (i64.store offset=0x3f4 align=1 (i32.const 0) (local.get 0x3f4)) - (i64.store offset=0x3f5 align=1 (i32.const 0) (local.get 0x3f5)) - (i64.store offset=0x3f6 align=1 (i32.const 0) (local.get 0x3f6)) - (i64.store offset=0x3f7 align=1 (i32.const 0) (local.get 0x3f7)) - (i64.store offset=0x3f8 align=1 (i32.const 0) (local.get 0x3f8)) - (i64.store offset=0x3f9 align=1 (i32.const 0) (local.get 0x3f9)) - (i64.store offset=0x3fa align=1 (i32.const 0) (local.get 0x3fa)) - (i64.store offset=0x3fb align=1 (i32.const 0) (local.get 0x3fb)) - (i64.store offset=0x3fc align=1 (i32.const 0) (local.get 0x3fc)) - (i64.store offset=0x3fd align=1 (i32.const 0) (local.get 0x3fd)) - (i64.store offset=0x3fe align=1 (i32.const 0) (local.get 0x3fe)) - (i64.store offset=0x3ff align=1 (i32.const 0) (local.get 0x3ff)) - (i64.store offset=0x400 align=1 (i32.const 0) (local.get 0x400)) - (i64.store offset=0x401 align=1 (i32.const 0) (local.get 0x401)) - (i64.store offset=0x402 align=1 (i32.const 0) (local.get 0x402)) - (i64.store offset=0x403 align=1 (i32.const 0) (local.get 0x403)) - (i64.store offset=0x404 align=1 (i32.const 0) (local.get 0x404)) - (i64.store offset=0x405 align=1 (i32.const 0) (local.get 0x405)) - (i64.store offset=0x406 align=1 (i32.const 0) (local.get 0x406)) - (i64.store offset=0x407 align=1 (i32.const 0) (local.get 0x407)) - (i64.store offset=0x408 align=1 (i32.const 0) (local.get 0x408)) - (i64.store offset=0x409 align=1 (i32.const 0) (local.get 0x409)) - (i64.store offset=0x40a align=1 (i32.const 0) (local.get 0x40a)) - (i64.store offset=0x40b align=1 (i32.const 0) (local.get 0x40b)) - (i64.store offset=0x40c align=1 (i32.const 0) (local.get 0x40c)) - (i64.store offset=0x40d align=1 (i32.const 0) (local.get 0x40d)) - (i64.store offset=0x40e align=1 (i32.const 0) (local.get 0x40e)) - (i64.store offset=0x40f align=1 (i32.const 0) (local.get 0x40f)) - (i64.store offset=0x410 align=1 (i32.const 0) (local.get 0x410)) - (i64.store offset=0x411 align=1 (i32.const 0) (local.get 0x411)) - (i64.store offset=0x412 align=1 (i32.const 0) (local.get 0x412)) - (i64.store offset=0x413 align=1 (i32.const 0) (local.get 0x413)) - (i64.store offset=0x414 align=1 (i32.const 0) (local.get 0x414)) - (i64.store offset=0x415 align=1 (i32.const 0) (local.get 0x415)) - (i64.store offset=0x416 align=1 (i32.const 0) (local.get 0x416)) - (i64.store offset=0x417 align=1 (i32.const 0) (local.get 0x417)) - (i64.store offset=0x418 align=1 (i32.const 0) (local.get 0x418)) - (i64.store offset=0x419 align=1 (i32.const 0) (local.get 0x419)) - (i64.store offset=0x41a align=1 (i32.const 0) (local.get 0x41a)) - (i64.store offset=0x41b align=1 (i32.const 0) (local.get 0x41b)) - (i64.store offset=0x41c align=1 (i32.const 0) (local.get 0x41c)) - (i64.store offset=0x41d align=1 (i32.const 0) (local.get 0x41d)) - (i64.store offset=0x41e align=1 (i32.const 0) (local.get 0x41e)) - (i64.store offset=0x41f align=1 (i32.const 0) (local.get 0x41f)) - ) -) - -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 0)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 100)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 200)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 300)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 400)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 500)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 600)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 700)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 800)) "call stack exhausted") -(assert_exhaustion (invoke "test-guard-page-skip" (i32.const 900)) "call stack exhausted") diff --git a/test/spec/stack.wast b/test/spec/stack.wast deleted file mode 100644 index 5da5043c8e9..00000000000 --- a/test/spec/stack.wast +++ /dev/null @@ -1,239 +0,0 @@ -(module - (func (export "fac-expr") (param $n i64) (result i64) - (local $i i64) - (local $res i64) - (local.set $i (local.get $n)) - (local.set $res (i64.const 1)) - (block $done - (loop $loop - (if - (i64.eq (local.get $i) (i64.const 0)) - (then (br $done)) - (else - (local.set $res (i64.mul (local.get $i) (local.get $res))) - (local.set $i (i64.sub (local.get $i) (i64.const 1))) - ) - ) - (br $loop) - ) - ) - (local.get $res) - ) - - (func (export "fac-stack") (param $n i64) (result i64) - (local $i i64) - (local $res i64) - (local.get $n) - (local.set $i) - (i64.const 1) - (local.set $res) - (block $done - (loop $loop - (local.get $i) - (i64.const 0) - (i64.eq) - (if - (then (br $done)) - (else - (local.get $i) - (local.get $res) - (i64.mul) - (local.set $res) - (local.get $i) - (i64.const 1) - (i64.sub) - (local.set $i) - ) - ) - (br $loop) - ) - ) - (local.get $res) - ) - - (func (export "fac-stack-raw") (param $n i64) (result i64) - (local $i i64) - (local $res i64) - local.get $n - local.set $i - i64.const 1 - local.set $res - block $done - loop $loop - local.get $i - i64.const 0 - i64.eq - if $body - br $done - else $body - local.get $i - local.get $res - i64.mul - local.set $res - local.get $i - i64.const 1 - i64.sub - local.set $i - end $body - br $loop - end $loop - end $done - local.get $res - ) - - (func (export "fac-mixed") (param $n i64) (result i64) - (local $i i64) - (local $res i64) - (local.set $i (local.get $n)) - (local.set $res (i64.const 1)) - (block $done - (loop $loop - (i64.eq (local.get $i) (i64.const 0)) - (if - (then (br $done)) - (else - (i64.mul (local.get $i) (local.get $res)) - (local.set $res) - (i64.sub (local.get $i) (i64.const 1)) - (local.set $i) - ) - ) - (br $loop) - ) - ) - (local.get $res) - ) - - (func (export "fac-mixed-raw") (param $n i64) (result i64) - (local $i i64) - (local $res i64) - (local.set $i (local.get $n)) - (local.set $res (i64.const 1)) - block $done - loop $loop - (i64.eq (local.get $i) (i64.const 0)) - if - br $done - else - (i64.mul (local.get $i) (local.get $res)) - local.set $res - (i64.sub (local.get $i) (i64.const 1)) - local.set $i - end - br $loop - end - end - local.get $res - ) - - (global $temp (mut i32) (i32.const 0)) - (func $add_one_to_global (result i32) - (local i32) - (global.set $temp (i32.add (i32.const 1) (global.get $temp))) - (global.get $temp) - ) - (func $add_one_to_global_and_drop - (drop (call $add_one_to_global)) - ) - (func (export "not-quite-a-tree") (result i32) - call $add_one_to_global - call $add_one_to_global - call $add_one_to_global_and_drop - i32.add - ) -) - -(assert_return (invoke "fac-expr" (i64.const 25)) (i64.const 7034535277573963776)) -(assert_return (invoke "fac-stack" (i64.const 25)) (i64.const 7034535277573963776)) -(assert_return (invoke "fac-mixed" (i64.const 25)) (i64.const 7034535277573963776)) - -(assert_return (invoke "not-quite-a-tree") (i32.const 3)) -(assert_return (invoke "not-quite-a-tree") (i32.const 9)) - - -;; Syntax of flat call_indirect - -(module - (type $proc (func)) - (table 1 funcref) - - (func - (block i32.const 0 call_indirect) - (loop i32.const 0 call_indirect) - (if (i32.const 0) (then i32.const 0 call_indirect)) - (if (i32.const 0) - (then i32.const 0 call_indirect) - (else i32.const 0 call_indirect) - ) - (block i32.const 0 call_indirect (type $proc)) - (loop i32.const 0 call_indirect (type $proc)) - (if (i32.const 0) (then i32.const 0 call_indirect (type $proc))) - (if (i32.const 0) - (then i32.const 0 call_indirect (type $proc)) - (else i32.const 0 call_indirect (type $proc)) - ) - (block i32.const 0 i32.const 0 call_indirect (param i32)) - (loop i32.const 0 i32.const 0 call_indirect (param i32)) - (if (i32.const 0) (then i32.const 0 i32.const 0 call_indirect (param i32))) - (if (i32.const 0) - (then i32.const 0 i32.const 0 call_indirect (param i32)) - (else i32.const 0 i32.const 0 call_indirect (param i32)) - ) - (block (result i32) i32.const 0 call_indirect (result i32)) (drop) - (loop (result i32) i32.const 0 call_indirect (result i32)) (drop) - (if (result i32) (i32.const 0) - (then i32.const 0 call_indirect (result i32)) - (else i32.const 0 call_indirect (result i32)) - ) (drop) - (block i32.const 0 call_indirect (type $proc) (param) (result)) - (loop i32.const 0 call_indirect (type $proc) (param) (result)) - (if (i32.const 0) - (then i32.const 0 call_indirect (type $proc) (param) (result)) - ) - (if (i32.const 0) - (then i32.const 0 call_indirect (type $proc) (param) (param) (result)) - (else i32.const 0 call_indirect (type $proc) (param) (result) (result)) - ) - - block i32.const 0 call_indirect end - loop i32.const 0 call_indirect end - i32.const 0 if i32.const 0 call_indirect end - i32.const 0 if i32.const 0 call_indirect else i32.const 0 call_indirect end - block i32.const 0 call_indirect (type $proc) end - loop i32.const 0 call_indirect (type $proc) end - i32.const 0 if i32.const 0 call_indirect (type $proc) end - i32.const 0 - if - i32.const 0 call_indirect (type $proc) - else - i32.const 0 call_indirect (type $proc) - end - block i32.const 0 i32.const 0 call_indirect (param i32) end - loop i32.const 0 i32.const 0 call_indirect (param i32) end - i32.const 0 if i32.const 0 i32.const 0 call_indirect (param i32) end - i32.const 0 - if - i32.const 0 i32.const 0 call_indirect (param i32) - else - i32.const 0 i32.const 0 call_indirect (param i32) - end - block (result i32) i32.const 0 call_indirect (result i32) end drop - loop (result i32) i32.const 0 call_indirect (result i32) end drop - i32.const 0 - if (result i32) - i32.const 0 call_indirect (result i32) - else - i32.const 0 call_indirect (result i32) - end drop - block i32.const 0 call_indirect (type $proc) (param) (result) end - loop i32.const 0 call_indirect (type $proc) (param) (result) end - i32.const 0 if i32.const 0 call_indirect (type $proc) (param) (result) end - i32.const 0 - if - i32.const 0 call_indirect (type $proc) (param) (result) - else - i32.const 0 call_indirect (type $proc) (param) (param) (result) (result) - end - i32.const 0 call_indirect - ) -) diff --git a/test/spec/start.wast b/test/spec/start.wast deleted file mode 100644 index bf88a6a4a48..00000000000 --- a/test/spec/start.wast +++ /dev/null @@ -1,105 +0,0 @@ -(assert_invalid - (module (func) (start 1)) - "unknown function" -) - -(assert_invalid - (module - (func $main (result i32) (return (i32.const 0))) - (start $main) - ) - "start function" -) -(assert_invalid - (module - (func $main (param $a i32)) - (start $main) - ) - "start function" -) - -(module - (memory (data "A")) - (func $inc - (i32.store8 - (i32.const 0) - (i32.add - (i32.load8_u (i32.const 0)) - (i32.const 1) - ) - ) - ) - (func $get (result i32) - (return (i32.load8_u (i32.const 0))) - ) - (func $main - (call $inc) - (call $inc) - (call $inc) - ) - - (start $main) - (export "inc" (func $inc)) - (export "get" (func $get)) -) -(assert_return (invoke "get") (i32.const 68)) -(invoke "inc") -(assert_return (invoke "get") (i32.const 69)) -(invoke "inc") -(assert_return (invoke "get") (i32.const 70)) - -(module - (memory (data "A")) - (func $inc - (i32.store8 - (i32.const 0) - (i32.add - (i32.load8_u (i32.const 0)) - (i32.const 1) - ) - ) - ) - (func $get (result i32) - (return (i32.load8_u (i32.const 0))) - ) - (func $main - (call $inc) - (call $inc) - (call $inc) - ) - (start 2) - (export "inc" (func $inc)) - (export "get" (func $get)) -) -(assert_return (invoke "get") (i32.const 68)) -(invoke "inc") -(assert_return (invoke "get") (i32.const 69)) -(invoke "inc") -(assert_return (invoke "get") (i32.const 70)) - -(module - (func $print_i32 (import "spectest" "print_i32") (param i32)) - (func $main (call $print_i32 (i32.const 1))) - (start 1) -) - -(module - (func $print_i32 (import "spectest" "print_i32") (param i32)) - (func $main (call $print_i32 (i32.const 2))) - (start $main) -) - -(module - (func $print (import "spectest" "print")) - (start $print) -) - -(assert_trap - (module (func $main (unreachable)) (start $main)) - "unreachable" -) - -(assert_malformed - (module quote "(module (func $a (unreachable)) (func $b (unreachable)) (start $a) (start $b))") - "multiple start sections" -) diff --git a/test/spec/store.wast b/test/spec/store.wast deleted file mode 100644 index 01c3a2dd648..00000000000 --- a/test/spec/store.wast +++ /dev/null @@ -1,417 +0,0 @@ -;; Store operator as the argument of control constructs and instructions - -(module - (memory 1) - - (func (export "as-block-value") - (block (i32.store (i32.const 0) (i32.const 1))) - ) - (func (export "as-loop-value") - (loop (i32.store (i32.const 0) (i32.const 1))) - ) - - (func (export "as-br-value") - (block (br 0 (i32.store (i32.const 0) (i32.const 1)))) - ) - (func (export "as-br_if-value") - (block - (br_if 0 (i32.store (i32.const 0) (i32.const 1)) (i32.const 1)) - ) - ) - (func (export "as-br_if-value-cond") - (block - (br_if 0 (i32.const 6) (i32.store (i32.const 0) (i32.const 1))) - ) - ) - (func (export "as-br_table-value") - (block - (br_table 0 (i32.store (i32.const 0) (i32.const 1)) (i32.const 1)) - ) - ) - - (func (export "as-return-value") - (return (i32.store (i32.const 0) (i32.const 1))) - ) - - (func (export "as-if-then") - (if (i32.const 1) (then (i32.store (i32.const 0) (i32.const 1)))) - ) - (func (export "as-if-else") - (if (i32.const 0) (then) (else (i32.store (i32.const 0) (i32.const 1)))) - ) -) - -(assert_return (invoke "as-block-value")) -(assert_return (invoke "as-loop-value")) - -(assert_return (invoke "as-br-value")) -(assert_return (invoke "as-br_if-value")) -(assert_return (invoke "as-br_if-value-cond")) -(assert_return (invoke "as-br_table-value")) - -(assert_return (invoke "as-return-value")) - -(assert_return (invoke "as-if-then")) -(assert_return (invoke "as-if-else")) - -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (i32.store32 (local.get 0) (i32.const 0)))" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (i32.store64 (local.get 0) (i64.const 0)))" - ) - "unknown operator" -) - -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (i64.store64 (local.get 0) (i64.const 0)))" - ) - "unknown operator" -) - -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (f32.store32 (local.get 0) (f32.const 0)))" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (f32.store64 (local.get 0) (f64.const 0)))" - ) - "unknown operator" -) - -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (f64.store32 (local.get 0) (f32.const 0)))" - ) - "unknown operator" -) -(assert_malformed - (module quote - "(memory 1)" - "(func (param i32) (f64.store64 (local.get 0) (f64.const 0)))" - ) - "unknown operator" -) -;; store should have no retval - -(assert_invalid - (module (memory 1) (func (param i32) (result i32) (i32.store (i32.const 0) (i32.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i64) (result i64) (i64.store (i32.const 0) (i64.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param f32) (result f32) (f32.store (i32.const 0) (f32.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param f64) (result f64) (f64.store (i32.const 0) (f64.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i32) (result i32) (i32.store8 (i32.const 0) (i32.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i32) (result i32) (i32.store16 (i32.const 0) (i32.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i64) (result i64) (i64.store8 (i32.const 0) (i64.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i64) (result i64) (i64.store16 (i32.const 0) (i64.const 1)))) - "type mismatch" -) -(assert_invalid - (module (memory 1) (func (param i64) (result i64) (i64.store32 (i32.const 0) (i64.const 1)))) - "type mismatch" -) - - -(assert_invalid - (module - (memory 1) - (func $type-address-empty - (i32.store) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty - (i32.const 0) (i32.store) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-block - (i32.const 0) (i32.const 0) - (block (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-block - (i32.const 0) - (block (i32.const 0) (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-loop - (i32.const 0) (i32.const 0) - (loop (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-loop - (i32.const 0) - (loop (i32.const 0) (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-then - (i32.const 0) (i32.const 0) - (if (then (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-then - (i32.const 0) - (if (then (i32.const 0) (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-else - (i32.const 0) (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-else - (i32.const 0) - (if (result i32) (then (i32.const 0)) (else (i32.const 0) (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-br - (i32.const 0) (i32.const 0) - (block (br 0 (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-br - (i32.const 0) - (block (br 0 (i32.const 0) (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-br_if - (i32.const 0) (i32.const 0) - (block (br_if 0 (i32.store) (i32.const 1)) ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-br_if - (i32.const 0) - (block (br_if 0 (i32.const 0) (i32.store) (i32.const 1)) ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-br_table - (i32.const 0) (i32.const 0) - (block (br_table 0 (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-br_table - (i32.const 0) - (block (br_table 0 (i32.const 0) (i32.store))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-return - (return (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-return - (return (i32.const 0) (i32.store)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-select - (select (i32.store) (i32.const 1) (i32.const 2)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-select - (select (i32.const 0) (i32.store) (i32.const 1) (i32.const 2)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-address-empty-in-call - (call 1 (i32.store)) - ) - (func (param i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $type-value-empty-in-call - (call 1 (i32.const 0) (i32.store)) - ) - (func (param i32) (result i32) (local.get 0)) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-address-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (i32.store) (i32.const 0) - ) - ) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (memory 1) - (func $f (param i32) (result i32) (local.get 0)) - (type $sig (func (param i32) (result i32))) - (table funcref (elem $f)) - (func $type-value-empty-in-call_indirect - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.store) (i32.const 0) - ) - ) - ) - ) - "type mismatch" -) - - -;; Type check - -(assert_invalid (module (memory 1) (func (i32.store (f32.const 0) (i32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i32.store8 (f32.const 0) (i32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i32.store16 (f32.const 0) (i32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store (f32.const 0) (i32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store8 (f32.const 0) (i64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store16 (f32.const 0) (i64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store32 (f32.const 0) (i64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (f32.store (f32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (f64.store (f32.const 0) (f64.const 0)))) "type mismatch") - -(assert_invalid (module (memory 1) (func (i32.store (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i32.store8 (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i32.store16 (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store (i32.const 0) (f32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store8 (i32.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store16 (i32.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (i64.store32 (i32.const 0) (f64.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (f32.store (i32.const 0) (i32.const 0)))) "type mismatch") -(assert_invalid (module (memory 1) (func (f64.store (i32.const 0) (i64.const 0)))) "type mismatch") diff --git a/test/spec/switch.wast b/test/spec/switch.wast deleted file mode 100644 index e9ae24dc151..00000000000 --- a/test/spec/switch.wast +++ /dev/null @@ -1,150 +0,0 @@ -(module - ;; Statement switch - (func (export "stmt") (param $i i32) (result i32) - (local $j i32) - (local.set $j (i32.const 100)) - (block $switch - (block $7 - (block $default - (block $6 - (block $5 - (block $4 - (block $3 - (block $2 - (block $1 - (block $0 - (br_table $0 $1 $2 $3 $4 $5 $6 $7 $default - (local.get $i) - ) - ) ;; 0 - (return (local.get $i)) - ) ;; 1 - (nop) - ;; fallthrough - ) ;; 2 - ;; fallthrough - ) ;; 3 - (local.set $j (i32.sub (i32.const 0) (local.get $i))) - (br $switch) - ) ;; 4 - (br $switch) - ) ;; 5 - (local.set $j (i32.const 101)) - (br $switch) - ) ;; 6 - (local.set $j (i32.const 101)) - ;; fallthrough - ) ;; default - (local.set $j (i32.const 102)) - ) ;; 7 - ;; fallthrough - ) - (return (local.get $j)) - ) - - ;; Expression switch - (func (export "expr") (param $i i64) (result i64) - (local $j i64) - (local.set $j (i64.const 100)) - (return - (block $switch (result i64) - (block $7 - (block $default - (block $4 - (block $5 - (block $6 - (block $3 - (block $2 - (block $1 - (block $0 - (br_table $0 $1 $2 $3 $4 $5 $6 $7 $default - (i32.wrap_i64 (local.get $i)) - ) - ) ;; 0 - (return (local.get $i)) - ) ;; 1 - (nop) - ;; fallthrough - ) ;; 2 - ;; fallthrough - ) ;; 3 - (br $switch (i64.sub (i64.const 0) (local.get $i))) - ) ;; 6 - (local.set $j (i64.const 101)) - ;; fallthrough - ) ;; 4 - ;; fallthrough - ) ;; 5 - ;; fallthrough - ) ;; default - (br $switch (local.get $j)) - ) ;; 7 - (i64.const -5) - ) - ) - ) - - ;; Argument switch - (func (export "arg") (param $i i32) (result i32) - (return - (block $2 (result i32) - (i32.add (i32.const 10) - (block $1 (result i32) - (i32.add (i32.const 100) - (block $0 (result i32) - (i32.add (i32.const 1000) - (block $default (result i32) - (br_table $0 $1 $2 $default - (i32.mul (i32.const 2) (local.get $i)) - (i32.and (i32.const 3) (local.get $i)) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - - ;; Corner cases - (func (export "corner") (result i32) - (block - (br_table 0 (i32.const 0)) - ) - (i32.const 1) - ) -) - -(assert_return (invoke "stmt" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "stmt" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "stmt" (i32.const 2)) (i32.const -2)) -(assert_return (invoke "stmt" (i32.const 3)) (i32.const -3)) -(assert_return (invoke "stmt" (i32.const 4)) (i32.const 100)) -(assert_return (invoke "stmt" (i32.const 5)) (i32.const 101)) -(assert_return (invoke "stmt" (i32.const 6)) (i32.const 102)) -(assert_return (invoke "stmt" (i32.const 7)) (i32.const 100)) -(assert_return (invoke "stmt" (i32.const -10)) (i32.const 102)) - -(assert_return (invoke "expr" (i64.const 0)) (i64.const 0)) -(assert_return (invoke "expr" (i64.const 1)) (i64.const -1)) -(assert_return (invoke "expr" (i64.const 2)) (i64.const -2)) -(assert_return (invoke "expr" (i64.const 3)) (i64.const -3)) -(assert_return (invoke "expr" (i64.const 6)) (i64.const 101)) -(assert_return (invoke "expr" (i64.const 7)) (i64.const -5)) -(assert_return (invoke "expr" (i64.const -10)) (i64.const 100)) - -(assert_return (invoke "arg" (i32.const 0)) (i32.const 110)) -(assert_return (invoke "arg" (i32.const 1)) (i32.const 12)) -(assert_return (invoke "arg" (i32.const 2)) (i32.const 4)) -(assert_return (invoke "arg" (i32.const 3)) (i32.const 1116)) -(assert_return (invoke "arg" (i32.const 4)) (i32.const 118)) -(assert_return (invoke "arg" (i32.const 5)) (i32.const 20)) -(assert_return (invoke "arg" (i32.const 6)) (i32.const 12)) -(assert_return (invoke "arg" (i32.const 7)) (i32.const 1124)) -(assert_return (invoke "arg" (i32.const 8)) (i32.const 126)) - -(assert_return (invoke "corner") (i32.const 1)) - -(assert_invalid (module (func (br_table 3 (i32.const 0)))) "unknown label") diff --git a/test/spec/table_copy.wast b/test/spec/table_copy.wast deleted file mode 100644 index a23dbcba587..00000000000 --- a/test/spec/table_copy.wast +++ /dev/null @@ -1,2216 +0,0 @@ -(module - (func (export "ef0") (result i32) (i32.const 0)) - (func (export "ef1") (result i32) (i32.const 1)) - (func (export "ef2") (result i32) (i32.const 2)) - (func (export "ef3") (result i32) (i32.const 3)) - (func (export "ef4") (result i32) (i32.const 4)) -) -(register "a") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (nop)) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 13) (i32.const 2) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 25) (i32.const 15) (i32.const 2))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 25)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 26)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 13) (i32.const 25) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_trap (invoke "check_t0" (i32.const 13)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 14)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 15)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 20) (i32.const 22) (i32.const 4))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 25) (i32.const 1) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 26)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 27)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 10) (i32.const 12) (i32.const 7))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 10)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 11)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 15)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t0 (i32.const 12) (i32.const 10) (i32.const 7))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 12)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 13)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 17)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 18)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t1) (i32.const 3) func 1 3 1 4) - (elem (table $t1) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t0 (i32.const 10) (i32.const 0) (i32.const 20))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 4)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 1)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 22)) (i32.const 7)) -(assert_return (invoke "check_t1" (i32.const 23)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 24)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 25)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 26)) (i32.const 6)) -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (nop)) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 13) (i32.const 2) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 25) (i32.const 15) (i32.const 2))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 25)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 26)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 13) (i32.const 25) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_trap (invoke "check_t0" (i32.const 13)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 14)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 15)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 20) (i32.const 22) (i32.const 4))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 25) (i32.const 1) (i32.const 3))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 26)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 27)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 10) (i32.const 12) (i32.const 7))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 10)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 11)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 15)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t1 $t1 (i32.const 12) (i32.const 10) (i32.const 7))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 12)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 13)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 17)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 18)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 11)) (i32.const 6)) -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 7)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (type (func (result i32))) ;; type #0 - (import "a" "ef0" (func (result i32))) ;; index 0 - (import "a" "ef1" (func (result i32))) - (import "a" "ef2" (func (result i32))) - (import "a" "ef3" (func (result i32))) - (import "a" "ef4" (func (result i32))) ;; index 4 - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t1) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t1) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (elem (table $t0) (i32.const 3) func 1 3 1 4) - (elem (table $t0) (i32.const 11) func 6 3 2 5 7) - (func (result i32) (i32.const 5)) ;; index 5 - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) ;; index 9 - (func (export "test") - (table.copy $t0 $t1 (i32.const 10) (i32.const 0) (i32.const 20))) - (func (export "check_t0") (param i32) (result i32) - (call_indirect $t1 (type 0) (local.get 0))) - (func (export "check_t1") (param i32) (result i32) - (call_indirect $t0 (type 0) (local.get 0))) -) - -(invoke "test") -(assert_trap (invoke "check_t0" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 1)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 2)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t0" (i32.const 4)) (i32.const 4)) -(assert_return (invoke "check_t0" (i32.const 5)) (i32.const 1)) -(assert_trap (invoke "check_t0" (i32.const 6)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t0" (i32.const 12)) (i32.const 7)) -(assert_return (invoke "check_t0" (i32.const 13)) (i32.const 5)) -(assert_return (invoke "check_t0" (i32.const 14)) (i32.const 2)) -(assert_return (invoke "check_t0" (i32.const 15)) (i32.const 3)) -(assert_return (invoke "check_t0" (i32.const 16)) (i32.const 6)) -(assert_trap (invoke "check_t0" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 21)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 22)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 23)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 24)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 25)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 26)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t0" (i32.const 29)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 0)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 1)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 2)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 4)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 5)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 6)) (i32.const 4)) -(assert_trap (invoke "check_t1" (i32.const 7)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 8)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 9)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 10)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 11)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 12)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 13)) (i32.const 1)) -(assert_return (invoke "check_t1" (i32.const 14)) (i32.const 4)) -(assert_return (invoke "check_t1" (i32.const 15)) (i32.const 1)) -(assert_trap (invoke "check_t1" (i32.const 16)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 17)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 18)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 19)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 20)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 21)) "uninitialized element") -(assert_return (invoke "check_t1" (i32.const 22)) (i32.const 7)) -(assert_return (invoke "check_t1" (i32.const 23)) (i32.const 5)) -(assert_return (invoke "check_t1" (i32.const 24)) (i32.const 2)) -(assert_return (invoke "check_t1" (i32.const 25)) (i32.const 3)) -(assert_return (invoke "check_t1" (i32.const 26)) (i32.const 6)) -(assert_trap (invoke "check_t1" (i32.const 27)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 28)) "uninitialized element") -(assert_trap (invoke "check_t1" (i32.const 29)) "uninitialized element") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 28) (i32.const 1) (i32.const 3)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 15) (i32.const 25) (i32.const 6)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 15) (i32.const 25) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 30) (i32.const 15) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 31) (i32.const 15) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 15) (i32.const 30) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 15) (i32.const 31) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 30) (i32.const 30) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t0 $t0 (i32.const 31) (i32.const 31) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 28) (i32.const 1) (i32.const 3)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 15) (i32.const 25) (i32.const 6)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 15) (i32.const 25) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 30) (i32.const 15) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 31) (i32.const 15) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 15) (i32.const 30) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 15) (i32.const 31) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 30) (i32.const 30) (i32.const 0)) - )) - -(invoke "test") - -(module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) - (elem funcref - (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) - (elem funcref - (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) - (func (result i32) (i32.const 0)) - (func (result i32) (i32.const 1)) - (func (result i32) (i32.const 2)) - (func (result i32) (i32.const 3)) - (func (result i32) (i32.const 4)) - (func (result i32) (i32.const 5)) - (func (result i32) (i32.const 6)) - (func (result i32) (i32.const 7)) - (func (result i32) (i32.const 8)) - (func (result i32) (i32.const 9)) - (func (export "test") - (table.copy $t1 $t0 (i32.const 31) (i32.const 31) (i32.const 0)) - )) - -(assert_trap (invoke "test") "out of bounds table access") - -;; TODO: add remaining parts that do not pass yet diff --git a/test/spec/table_size.wast b/test/spec/table_size.wast deleted file mode 100644 index 71081d7e6bd..00000000000 --- a/test/spec/table_size.wast +++ /dev/null @@ -1,89 +0,0 @@ -(module - (table $t0 0 externref) - (table $t1 1 externref) - (table $t2 0 2 externref) - (table $t3 3 8 externref) - (table $t64 i64 42 42 externref) - - (func (export "size-t0") (result i32) table.size) - (func (export "size-t1") (result i32) (table.size $t1)) - (func (export "size-t2") (result i32) (table.size $t2)) - (func (export "size-t3") (result i32) (table.size $t3)) - (func (export "size-t64") (result i64) (table.size $t64)) - - (func (export "grow-t0") (param $sz i32) - (drop (table.grow $t0 (ref.null extern) (local.get $sz))) - ) - (func (export "grow-t1") (param $sz i32) - (drop (table.grow $t1 (ref.null extern) (local.get $sz))) - ) - (func (export "grow-t2") (param $sz i32) - (drop (table.grow $t2 (ref.null extern) (local.get $sz))) - ) - (func (export "grow-t3") (param $sz i32) - (drop (table.grow $t3 (ref.null extern) (local.get $sz))) - ) -) - -(assert_return (invoke "size-t0") (i32.const 0)) -(assert_return (invoke "grow-t0" (i32.const 1))) -(assert_return (invoke "size-t0") (i32.const 1)) -(assert_return (invoke "grow-t0" (i32.const 4))) -(assert_return (invoke "size-t0") (i32.const 5)) -(assert_return (invoke "grow-t0" (i32.const 0))) -(assert_return (invoke "size-t0") (i32.const 5)) - -(assert_return (invoke "size-t1") (i32.const 1)) -(assert_return (invoke "grow-t1" (i32.const 1))) -(assert_return (invoke "size-t1") (i32.const 2)) -(assert_return (invoke "grow-t1" (i32.const 4))) -(assert_return (invoke "size-t1") (i32.const 6)) -(assert_return (invoke "grow-t1" (i32.const 0))) -(assert_return (invoke "size-t1") (i32.const 6)) - -(assert_return (invoke "size-t2") (i32.const 0)) -(assert_return (invoke "grow-t2" (i32.const 3))) -(assert_return (invoke "size-t2") (i32.const 0)) -(assert_return (invoke "grow-t2" (i32.const 1))) -(assert_return (invoke "size-t2") (i32.const 1)) -(assert_return (invoke "grow-t2" (i32.const 0))) -(assert_return (invoke "size-t2") (i32.const 1)) -(assert_return (invoke "grow-t2" (i32.const 4))) -(assert_return (invoke "size-t2") (i32.const 1)) -(assert_return (invoke "grow-t2" (i32.const 1))) -(assert_return (invoke "size-t2") (i32.const 2)) - -(assert_return (invoke "size-t3") (i32.const 3)) -(assert_return (invoke "grow-t3" (i32.const 1))) -(assert_return (invoke "size-t3") (i32.const 4)) -(assert_return (invoke "grow-t3" (i32.const 3))) -(assert_return (invoke "size-t3") (i32.const 7)) -(assert_return (invoke "grow-t3" (i32.const 0))) -(assert_return (invoke "size-t3") (i32.const 7)) -(assert_return (invoke "grow-t3" (i32.const 2))) -(assert_return (invoke "size-t3") (i32.const 7)) -(assert_return (invoke "grow-t3" (i32.const 1))) -(assert_return (invoke "size-t3") (i32.const 8)) - -(assert_return (invoke "size-t64") (i64.const 42)) - -;; Type errors - -(assert_invalid - (module - (table $t 1 externref) - (func $type-result-i32-vs-empty - (table.size $t) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 1 externref) - (func $type-result-i32-vs-f32 (result f32) - (table.size $t) - ) - ) - "type mismatch" -) diff --git a/test/spec/testsuite b/test/spec/testsuite new file mode 160000 index 00000000000..e05365077e1 --- /dev/null +++ b/test/spec/testsuite @@ -0,0 +1 @@ +Subproject commit e05365077e13a1d86ffe77acfb1a835b7aa78422 diff --git a/test/spec/traps.wast b/test/spec/traps.wast deleted file mode 100644 index 142fa22b2b9..00000000000 --- a/test/spec/traps.wast +++ /dev/null @@ -1,91 +0,0 @@ -;; Test that traps are preserved even in instructions which might otherwise -;; be dead-code-eliminated. These functions all perform an operation and -;; discard its return value. - -(module - (func (export "no_dce.i32.div_s") (param $x i32) (param $y i32) - (drop (i32.div_s (local.get $x) (local.get $y)))) - (func (export "no_dce.i32.div_u") (param $x i32) (param $y i32) - (drop (i32.div_u (local.get $x) (local.get $y)))) - (func (export "no_dce.i64.div_s") (param $x i64) (param $y i64) - (drop (i64.div_s (local.get $x) (local.get $y)))) - (func (export "no_dce.i64.div_u") (param $x i64) (param $y i64) - (drop (i64.div_u (local.get $x) (local.get $y)))) -) - -(assert_trap (invoke "no_dce.i32.div_s" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i32.div_u" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i64.div_s" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i64.div_u" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i32.div_s" (i32.const 0x80000000) (i32.const -1)) "integer overflow") -(assert_trap (invoke "no_dce.i64.div_s" (i64.const 0x8000000000000000) (i64.const -1)) "integer overflow") - -(module - (func (export "no_dce.i32.rem_s") (param $x i32) (param $y i32) - (drop (i32.rem_s (local.get $x) (local.get $y)))) - (func (export "no_dce.i32.rem_u") (param $x i32) (param $y i32) - (drop (i32.rem_u (local.get $x) (local.get $y)))) - (func (export "no_dce.i64.rem_s") (param $x i64) (param $y i64) - (drop (i64.rem_s (local.get $x) (local.get $y)))) - (func (export "no_dce.i64.rem_u") (param $x i64) (param $y i64) - (drop (i64.rem_u (local.get $x) (local.get $y)))) -) - -(assert_trap (invoke "no_dce.i32.rem_s" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i32.rem_u" (i32.const 1) (i32.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i64.rem_s" (i64.const 1) (i64.const 0)) "integer divide by zero") -(assert_trap (invoke "no_dce.i64.rem_u" (i64.const 1) (i64.const 0)) "integer divide by zero") - -(module - (func (export "no_dce.i32.trunc_f32_s") (param $x f32) (drop (i32.trunc_f32_s (local.get $x)))) - (func (export "no_dce.i32.trunc_f32_u") (param $x f32) (drop (i32.trunc_f32_u (local.get $x)))) - (func (export "no_dce.i32.trunc_f64_s") (param $x f64) (drop (i32.trunc_f64_s (local.get $x)))) - (func (export "no_dce.i32.trunc_f64_u") (param $x f64) (drop (i32.trunc_f64_u (local.get $x)))) - (func (export "no_dce.i64.trunc_f32_s") (param $x f32) (drop (i64.trunc_f32_s (local.get $x)))) - (func (export "no_dce.i64.trunc_f32_u") (param $x f32) (drop (i64.trunc_f32_u (local.get $x)))) - (func (export "no_dce.i64.trunc_f64_s") (param $x f64) (drop (i64.trunc_f64_s (local.get $x)))) - (func (export "no_dce.i64.trunc_f64_u") (param $x f64) (drop (i64.trunc_f64_u (local.get $x)))) -) - -(assert_trap (invoke "no_dce.i32.trunc_f32_s" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i32.trunc_f32_u" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i32.trunc_f64_s" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i32.trunc_f64_u" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i64.trunc_f32_s" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i64.trunc_f32_u" (f32.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i64.trunc_f64_s" (f64.const nan)) "invalid conversion to integer") -(assert_trap (invoke "no_dce.i64.trunc_f64_u" (f64.const nan)) "invalid conversion to integer") - -(module - (memory 1) - - (func (export "no_dce.i32.load") (param $i i32) (drop (i32.load (local.get $i)))) - (func (export "no_dce.i32.load16_s") (param $i i32) (drop (i32.load16_s (local.get $i)))) - (func (export "no_dce.i32.load16_u") (param $i i32) (drop (i32.load16_u (local.get $i)))) - (func (export "no_dce.i32.load8_s") (param $i i32) (drop (i32.load8_s (local.get $i)))) - (func (export "no_dce.i32.load8_u") (param $i i32) (drop (i32.load8_u (local.get $i)))) - (func (export "no_dce.i64.load") (param $i i32) (drop (i64.load (local.get $i)))) - (func (export "no_dce.i64.load32_s") (param $i i32) (drop (i64.load32_s (local.get $i)))) - (func (export "no_dce.i64.load32_u") (param $i i32) (drop (i64.load32_u (local.get $i)))) - (func (export "no_dce.i64.load16_s") (param $i i32) (drop (i64.load16_s (local.get $i)))) - (func (export "no_dce.i64.load16_u") (param $i i32) (drop (i64.load16_u (local.get $i)))) - (func (export "no_dce.i64.load8_s") (param $i i32) (drop (i64.load8_s (local.get $i)))) - (func (export "no_dce.i64.load8_u") (param $i i32) (drop (i64.load8_u (local.get $i)))) - (func (export "no_dce.f32.load") (param $i i32) (drop (f32.load (local.get $i)))) - (func (export "no_dce.f64.load") (param $i i32) (drop (f64.load (local.get $i)))) -) - -(assert_trap (invoke "no_dce.i32.load" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i32.load16_s" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i32.load16_u" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i32.load8_s" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i32.load8_u" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load32_s" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load32_u" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load16_s" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load16_u" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load8_s" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.i64.load8_u" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.f32.load" (i32.const 65536)) "out of bounds memory access") -(assert_trap (invoke "no_dce.f64.load" (i32.const 65536)) "out of bounds memory access") diff --git a/test/spec/type.wast b/test/spec/type.wast deleted file mode 100644 index b94063e6a04..00000000000 --- a/test/spec/type.wast +++ /dev/null @@ -1,50 +0,0 @@ -;; Test type definitions - -(module - (type (func)) - (type $t (func)) - - (type (func (param i32))) - (type (func (param $x i32))) - (type (func (result i32))) - (type (func (param i32) (result i32))) - (type (func (param $x i32) (result i32))) - - (type (func (param f32 f64))) - (type (func (result i64 f32))) - (type (func (param i32 i64) (result f32 f64))) - - (type (func (param f32) (param f64))) - (type (func (param $x f32) (param f64))) - (type (func (param f32) (param $y f64))) - (type (func (param $x f32) (param $y f64))) - (type (func (result i64) (result f32))) - (type (func (param i32) (param i64) (result f32) (result f64))) - (type (func (param $x i32) (param $y i64) (result f32) (result f64))) - - (type (func (param f32 f64) (param $x i32) (param f64 i32 i32))) - (type (func (result i64 i64 f32) (result f32 i32))) - (type - (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32)) - ) - - (type (func (param) (param $x f32) (param) (param) (param f64 i32) (param))) - (type - (func (result) (result) (result i64 i64) (result) (result f32) (result)) - ) - (type - (func - (param i32 i32) (param i64 i32) (param) (param $x i32) (param) - (result) (result f32 f64) (result f64 i32) (result) - ) - ) -) - -(assert_malformed - (module quote "(type (func (result i32) (param i32)))") - "result before parameter" -) -(assert_malformed - (module quote "(type (func (result $x i32)))") - "unexpected token" -) diff --git a/test/spec/unreachable.wast b/test/spec/unreachable.wast deleted file mode 100644 index 3074847a3e1..00000000000 --- a/test/spec/unreachable.wast +++ /dev/null @@ -1,304 +0,0 @@ -;; Test `unreachable` operator - -(module - ;; Auxiliary definitions - (func $dummy) - (func $dummy3 (param i32 i32 i32)) - - (func (export "type-i32") (result i32) (unreachable)) - (func (export "type-i64") (result i32) (unreachable)) - (func (export "type-f32") (result f64) (unreachable)) - (func (export "type-f64") (result f64) (unreachable)) - - (func (export "as-func-first") (result i32) - (unreachable) (i32.const -1) - ) - (func (export "as-func-mid") (result i32) - (call $dummy) (unreachable) (i32.const -1) - ) - (func (export "as-func-last") - (call $dummy) (unreachable) - ) - (func (export "as-func-value") (result i32) - (call $dummy) (unreachable) - ) - - (func (export "as-block-first") (result i32) - (block (result i32) (unreachable) (i32.const 2)) - ) - (func (export "as-block-mid") (result i32) - (block (result i32) (call $dummy) (unreachable) (i32.const 2)) - ) - (func (export "as-block-last") - (block (nop) (call $dummy) (unreachable)) - ) - (func (export "as-block-value") (result i32) - (block (result i32) (nop) (call $dummy) (unreachable)) - ) - (func (export "as-block-broke") (result i32) - (block (result i32) (call $dummy) (br 0 (i32.const 1)) (unreachable)) - ) - - (func (export "as-loop-first") (result i32) - (loop (result i32) (unreachable) (i32.const 2)) - ) - (func (export "as-loop-mid") (result i32) - (loop (result i32) (call $dummy) (unreachable) (i32.const 2)) - ) - (func (export "as-loop-last") - (loop (nop) (call $dummy) (unreachable)) - ) - (func (export "as-loop-broke") (result i32) - (block (result i32) - (loop (result i32) (call $dummy) (br 1 (i32.const 1)) (unreachable)) - ) - ) - - (func (export "as-br-value") (result i32) - (block (result i32) (br 0 (unreachable))) - ) - - (func (export "as-br_if-cond") - (block (br_if 0 (unreachable))) - ) - (func (export "as-br_if-value") (result i32) - (block (result i32) - (drop (br_if 0 (unreachable) (i32.const 1))) (i32.const 7) - ) - ) - (func (export "as-br_if-value-cond") (result i32) - (block (result i32) - (drop (br_if 0 (i32.const 6) (unreachable))) (i32.const 7) - ) - ) - - (func (export "as-br_table-index") - (block (br_table 0 0 0 (unreachable))) - ) - (func (export "as-br_table-value") (result i32) - (block (result i32) - (br_table 0 0 0 (unreachable) (i32.const 1)) (i32.const 7) - ) - ) - (func (export "as-br_table-value-2") (result i32) - (block (result i32) - (block (result i32) (br_table 0 1 (unreachable) (i32.const 1))) - ) - ) - (func (export "as-br_table-value-index") (result i32) - (block (result i32) - (br_table 0 0 (i32.const 6) (unreachable)) (i32.const 7) - ) - ) - (func (export "as-br_table-value-and-index") (result i32) - (block (result i32) (br_table 0 0 (unreachable)) (i32.const 8)) - ) - - (func (export "as-return-value") (result i64) - (return (unreachable)) - ) - - (func (export "as-if-cond") (result i32) - (if (result i32) (unreachable) (then (i32.const 0)) (else (i32.const 1))) - ) - (func (export "as-if-then") (param i32 i32) (result i32) - (if (result i32) (local.get 0) (then (unreachable)) (else (local.get 1))) - ) - (func (export "as-if-else") (param i32 i32) (result i32) - (if (result i32) (local.get 0) (then (local.get 1)) (else (unreachable))) - ) - (func (export "as-if-then-no-else") (param i32 i32) (result i32) - (if (local.get 0) (then (unreachable))) (local.get 1) - ) - - (func (export "as-select-first") (param i32 i32) (result i32) - (select (unreachable) (local.get 0) (local.get 1)) - ) - (func (export "as-select-second") (param i32 i32) (result i32) - (select (local.get 0) (unreachable) (local.get 1)) - ) - (func (export "as-select-cond") (result i32) - (select (i32.const 0) (i32.const 1) (unreachable)) - ) - - (func (export "as-call-first") - (call $dummy3 (unreachable) (i32.const 2) (i32.const 3)) - ) - (func (export "as-call-mid") - (call $dummy3 (i32.const 1) (unreachable) (i32.const 3)) - ) - (func (export "as-call-last") - (call $dummy3 (i32.const 1) (i32.const 2) (unreachable)) - ) - - (type $sig (func (param i32 i32 i32))) - (table funcref (elem $dummy3)) - (func (export "as-call_indirect-func") - (call_indirect (type $sig) - (unreachable) (i32.const 1) (i32.const 2) (i32.const 3) - ) - ) - (func (export "as-call_indirect-first") - (call_indirect (type $sig) - (i32.const 0) (unreachable) (i32.const 2) (i32.const 3) - ) - ) - (func (export "as-call_indirect-mid") - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (unreachable) (i32.const 3) - ) - ) - (func (export "as-call_indirect-last") - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (i32.const 2) (unreachable) - ) - ) - - (func (export "as-local.set-value") (local f32) - (local.set 0 (unreachable)) - ) - (func (export "as-local.tee-value") (result f32) (local f32) - (local.tee 0 (unreachable)) - ) - (global $a (mut f32) (f32.const 0)) - (func (export "as-global.set-value") (result f32) - (global.set $a (unreachable)) - ) - - (memory 1) - (func (export "as-load-address") (result f32) - (f32.load (unreachable)) - ) - (func (export "as-loadN-address") (result i64) - (i64.load8_s (unreachable)) - ) - - (func (export "as-store-address") - (f64.store (unreachable) (f64.const 7)) - ) - (func (export "as-store-value") - (i64.store (i32.const 2) (unreachable)) - ) - - (func (export "as-storeN-address") - (i32.store8 (unreachable) (i32.const 7)) - ) - (func (export "as-storeN-value") - (i64.store16 (i32.const 2) (unreachable)) - ) - - (func (export "as-unary-operand") (result f32) - (f32.neg (unreachable)) - ) - - (func (export "as-binary-left") (result i32) - (i32.add (unreachable) (i32.const 10)) - ) - (func (export "as-binary-right") (result i64) - (i64.sub (i64.const 10) (unreachable)) - ) - - (func (export "as-test-operand") (result i32) - (i32.eqz (unreachable)) - ) - - (func (export "as-compare-left") (result i32) - (f64.le (unreachable) (f64.const 10)) - ) - (func (export "as-compare-right") (result i32) - (f32.ne (f32.const 10) (unreachable)) - ) - - (func (export "as-convert-operand") (result i32) - (i32.wrap_i64 (unreachable)) - ) - - (func (export "as-memory.grow-size") (result i32) - (memory.grow (unreachable)) - ) -) - -(assert_trap (invoke "type-i32") "unreachable") -(assert_trap (invoke "type-i64") "unreachable") -(assert_trap (invoke "type-f32") "unreachable") -(assert_trap (invoke "type-f64") "unreachable") - -(assert_trap (invoke "as-func-first") "unreachable") -(assert_trap (invoke "as-func-mid") "unreachable") -(assert_trap (invoke "as-func-last") "unreachable") -(assert_trap (invoke "as-func-value") "unreachable") - -(assert_trap (invoke "as-block-first") "unreachable") -(assert_trap (invoke "as-block-mid") "unreachable") -(assert_trap (invoke "as-block-last") "unreachable") -(assert_trap (invoke "as-block-value") "unreachable") -(assert_return (invoke "as-block-broke") (i32.const 1)) - -(assert_trap (invoke "as-loop-first") "unreachable") -(assert_trap (invoke "as-loop-mid") "unreachable") -(assert_trap (invoke "as-loop-last") "unreachable") -(assert_return (invoke "as-loop-broke") (i32.const 1)) - -(assert_trap (invoke "as-br-value") "unreachable") - -(assert_trap (invoke "as-br_if-cond") "unreachable") -(assert_trap (invoke "as-br_if-value") "unreachable") -(assert_trap (invoke "as-br_if-value-cond") "unreachable") - -(assert_trap (invoke "as-br_table-index") "unreachable") -(assert_trap (invoke "as-br_table-value") "unreachable") -(assert_trap (invoke "as-br_table-value-2") "unreachable") -(assert_trap (invoke "as-br_table-value-index") "unreachable") -(assert_trap (invoke "as-br_table-value-and-index") "unreachable") - -(assert_trap (invoke "as-return-value") "unreachable") - -(assert_trap (invoke "as-if-cond") "unreachable") -(assert_trap (invoke "as-if-then" (i32.const 1) (i32.const 6)) "unreachable") -(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_trap (invoke "as-if-else" (i32.const 0) (i32.const 6)) "unreachable") -(assert_return (invoke "as-if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) -(assert_trap (invoke "as-if-then-no-else" (i32.const 1) (i32.const 6)) "unreachable") -(assert_return (invoke "as-if-then-no-else" (i32.const 0) (i32.const 6)) (i32.const 6)) - -(assert_trap (invoke "as-select-first" (i32.const 0) (i32.const 6)) "unreachable") -(assert_trap (invoke "as-select-first" (i32.const 1) (i32.const 6)) "unreachable") -(assert_trap (invoke "as-select-second" (i32.const 0) (i32.const 6)) "unreachable") -(assert_trap (invoke "as-select-second" (i32.const 1) (i32.const 6)) "unreachable") -(assert_trap (invoke "as-select-cond") "unreachable") - -(assert_trap (invoke "as-call-first") "unreachable") -(assert_trap (invoke "as-call-mid") "unreachable") -(assert_trap (invoke "as-call-last") "unreachable") - -(assert_trap (invoke "as-call_indirect-func") "unreachable") -(assert_trap (invoke "as-call_indirect-first") "unreachable") -(assert_trap (invoke "as-call_indirect-mid") "unreachable") -(assert_trap (invoke "as-call_indirect-last") "unreachable") - -(assert_trap (invoke "as-local.set-value") "unreachable") -(assert_trap (invoke "as-local.tee-value") "unreachable") -(assert_trap (invoke "as-global.set-value") "unreachable") - -(assert_trap (invoke "as-load-address") "unreachable") -(assert_trap (invoke "as-loadN-address") "unreachable") - -(assert_trap (invoke "as-store-address") "unreachable") -(assert_trap (invoke "as-store-value") "unreachable") -(assert_trap (invoke "as-storeN-address") "unreachable") -(assert_trap (invoke "as-storeN-value") "unreachable") - -(assert_trap (invoke "as-unary-operand") "unreachable") - -(assert_trap (invoke "as-binary-left") "unreachable") -(assert_trap (invoke "as-binary-right") "unreachable") - -(assert_trap (invoke "as-test-operand") "unreachable") - -(assert_trap (invoke "as-compare-left") "unreachable") -(assert_trap (invoke "as-compare-right") "unreachable") - -(assert_trap (invoke "as-convert-operand") "unreachable") - -(assert_trap (invoke "as-memory.grow-size") "unreachable") - diff --git a/test/spec/unwind.wast b/test/spec/unwind.wast deleted file mode 100644 index 85db60b595e..00000000000 --- a/test/spec/unwind.wast +++ /dev/null @@ -1,267 +0,0 @@ -;; Test that control-flow transfer unwinds stack and it can be anything after. - -(module - (func (export "func-unwind-by-unreachable") - (i32.const 3) (i64.const 1) (unreachable) - ) - (func (export "func-unwind-by-br") - (i32.const 3) (i64.const 1) (br 0) - ) - (func (export "func-unwind-by-br-value") (result i32) - (i32.const 3) (i64.const 1) (br 0 (i32.const 9)) - ) - (func (export "func-unwind-by-br_if") - (i32.const 3) (i64.const 1) (drop (drop (br_if 0 (i32.const 1)))) - ) - (func (export "func-unwind-by-br_if-value") (result i32) - (i32.const 3) (i64.const 1) (drop (drop (br_if 0 (i32.const 9) (i32.const 1)))) - ) - (func (export "func-unwind-by-br_table") - (i32.const 3) (i64.const 1) (br_table 0 (i32.const 0)) - ) - (func (export "func-unwind-by-br_table-value") (result i32) - (i32.const 3) (i64.const 1) (br_table 0 (i32.const 9) (i32.const 0)) - ) - (func (export "func-unwind-by-return") (result i32) - (i32.const 3) (i64.const 1) (return (i32.const 9)) - ) - - (func (export "block-unwind-by-unreachable") - (block (i32.const 3) (i64.const 1) (unreachable)) - ) - (func (export "block-unwind-by-br") (result i32) - (block (i32.const 3) (i64.const 1) (br 0)) (i32.const 9) - ) - (func (export "block-unwind-by-br-value") (result i32) - (block (result i32) (i32.const 3) (i64.const 1) (br 0 (i32.const 9))) - ) - (func (export "block-unwind-by-br_if") (result i32) - (block (i32.const 3) (i64.const 1) (drop (drop (br_if 0 (i32.const 1))))) (i32.const 9) - ) - (func (export "block-unwind-by-br_if-value") (result i32) - (block (result i32) - (i32.const 3) (i64.const 1) (drop (drop (br_if 0 (i32.const 9) (i32.const 1)))) - ) - ) - (func (export "block-unwind-by-br_table") (result i32) - (block (i32.const 3) (i64.const 1) (br_table 0 (i32.const 0))) (i32.const 9) - ) - (func (export "block-unwind-by-br_table-value") (result i32) - (block (result i32) - (i32.const 3) (i64.const 1) (br_table 0 (i32.const 9) (i32.const 0)) - ) - ) - (func (export "block-unwind-by-return") (result i32) - (block (result i32) (i32.const 3) (i64.const 1) (return (i32.const 9))) - ) - - (func (export "block-nested-unwind-by-unreachable") (result i32) - (block (result i32) (i32.const 3) (block (i64.const 1) (unreachable))) - ) - (func (export "block-nested-unwind-by-br") (result i32) - (block (i32.const 3) (block (i64.const 1) (br 1)) (drop)) (i32.const 9) - ) - (func (export "block-nested-unwind-by-br-value") (result i32) - (block (result i32) - (i32.const 3) (block (i64.const 1) (br 1 (i32.const 9))) - ) - ) - (func (export "block-nested-unwind-by-br_if") (result i32) - (block (i32.const 3) (block (i64.const 1) (drop (br_if 1 (i32.const 1)))) (drop)) (i32.const 9) - ) - (func (export "block-nested-unwind-by-br_if-value") (result i32) - (block (result i32) - (i32.const 3) (block (i64.const 1) (drop (drop (br_if 1 (i32.const 9) (i32.const 1))))) - ) - ) - (func (export "block-nested-unwind-by-br_table") (result i32) - (block - (i32.const 3) (block (i64.const 1) (br_table 1 (i32.const 1))) - (drop) - ) - (i32.const 9) - ) - (func (export "block-nested-unwind-by-br_table-value") (result i32) - (block (result i32) - (i32.const 3) - (block (i64.const 1) (br_table 1 (i32.const 9) (i32.const 1))) - ) - ) - (func (export "block-nested-unwind-by-return") (result i32) - (block (result i32) - (i32.const 3) (block (i64.const 1) (return (i32.const 9))) - ) - ) - - (func (export "unary-after-unreachable") (result i32) - (f32.const 0) (unreachable) (i64.eqz) - ) - (func (export "unary-after-br") (result i32) - (block (result i32) (f32.const 0) (br 0 (i32.const 9)) (i64.eqz)) - ) - (func (export "unary-after-br_if") (result i32) - (block (result i32) - (i64.const 0) (drop (br_if 0 (i32.const 9) (i32.const 1))) (i64.eqz) - ) - ) - (func (export "unary-after-br_table") (result i32) - (block (result i32) - (f32.const 0) (br_table 0 0 (i32.const 9) (i32.const 0)) (i64.eqz) - ) - ) - (func (export "unary-after-return") (result i32) - (f32.const 0) (return (i32.const 9)) (i64.eqz) - ) - - (func (export "binary-after-unreachable") (result i32) - (f32.const 0) (f64.const 1) (unreachable) (i64.eq) - ) - (func (export "binary-after-br") (result i32) - (block (result i32) - (f32.const 0) (f64.const 1) (br 0 (i32.const 9)) (i64.eq) - ) - ) - (func (export "binary-after-br_if") (result i32) - (block (result i32) - (i64.const 0) (i64.const 1) (drop (br_if 0 (i32.const 9) (i32.const 1))) - (i64.eq) - ) - ) - (func (export "binary-after-br_table") (result i32) - (block (result i32) - (f32.const 0) (f64.const 1) (br_table 0 (i32.const 9) (i32.const 0)) - (i64.eq) - ) - ) - (func (export "binary-after-return") (result i32) - (f32.const 0) (f64.const 1) (return (i32.const 9)) (i64.eq) - ) - - (func (export "select-after-unreachable") (result i32) - (f32.const 0) (f64.const 1) (i64.const 0) (unreachable) (select) - ) - (func (export "select-after-br") (result i32) - (block (result i32) - (f32.const 0) (f64.const 1) (i64.const 0) (br 0 (i32.const 9)) (select) - ) - ) - (func (export "select-after-br_if") (result i32) - (block (result i32) - (i32.const 0) (i32.const 1) (i32.const 0) - (drop (br_if 0 (i32.const 9) (i32.const 1))) - (select) - ) - ) - (func (export "select-after-br_table") (result i32) - (block (result i32) - (f32.const 0) (f64.const 1) (i64.const 0) - (br_table 0 (i32.const 9) (i32.const 0)) - (select) - ) - ) - (func (export "select-after-return") (result i32) - (f32.const 0) (f64.const 1) (i64.const 1) (return (i32.const 9)) (select) - ) - - (func (export "block-value-after-unreachable") (result i32) - (block (result i32) (f32.const 0) (unreachable)) - ) - (func (export "block-value-after-br") (result i32) - (block (result i32) (f32.const 0) (br 0 (i32.const 9))) - ) - (func (export "block-value-after-br_if") (result i32) - (block (result i32) - (i32.const 0) (drop (br_if 0 (i32.const 9) (i32.const 1))) - ) - ) - (func (export "block-value-after-br_table") (result i32) - (block (result i32) - (f32.const 0) (br_table 0 0 (i32.const 9) (i32.const 0)) - ) - ) - (func (export "block-value-after-return") (result i32) - (block (result i32) (f32.const 0) (return (i32.const 9))) - ) - - (func (export "loop-value-after-unreachable") (result i32) - (loop (result i32) (f32.const 0) (unreachable)) - ) - (func (export "loop-value-after-br") (result i32) - (block (result i32) (loop (result i32) (f32.const 0) (br 1 (i32.const 9)))) - ) - (func (export "loop-value-after-br_if") (result i32) - (block (result i32) - (loop (result i32) - (i32.const 0) (drop (br_if 1 (i32.const 9) (i32.const 1))) - ) - ) - ) - - (func (export "loop-value-after-br_table") (result i32) - (block (result i32) - (loop (result i32) - (f32.const 0) (br_table 1 1 (i32.const 9) (i32.const 0)) - ) - ) - ) - (func (export "loop-value-after-return") (result i32) - (loop (result i32) (f32.const 0) (return (i32.const 9))) - ) -) - -(assert_trap (invoke "func-unwind-by-unreachable") "unreachable") -(assert_return (invoke "func-unwind-by-br")) -(assert_return (invoke "func-unwind-by-br-value") (i32.const 9)) -(assert_return (invoke "func-unwind-by-br_if")) -(assert_return (invoke "func-unwind-by-br_if-value") (i32.const 9)) -(assert_return (invoke "func-unwind-by-br_table")) -(assert_return (invoke "func-unwind-by-br_table-value") (i32.const 9)) -(assert_return (invoke "func-unwind-by-return") (i32.const 9)) - -(assert_trap (invoke "block-unwind-by-unreachable") "unreachable") -(assert_return (invoke "block-unwind-by-br") (i32.const 9)) -(assert_return (invoke "block-unwind-by-br-value") (i32.const 9)) -(assert_return (invoke "block-unwind-by-br_if") (i32.const 9)) -(assert_return (invoke "block-unwind-by-br_if-value") (i32.const 9)) -(assert_return (invoke "block-unwind-by-br_table") (i32.const 9)) -(assert_return (invoke "block-unwind-by-br_table-value") (i32.const 9)) -(assert_return (invoke "block-unwind-by-return") (i32.const 9)) - -(assert_trap (invoke "block-nested-unwind-by-unreachable") "unreachable") -(assert_return (invoke "block-nested-unwind-by-br") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-br-value") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-br_if") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-br_if-value") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-br_table") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-br_table-value") (i32.const 9)) -(assert_return (invoke "block-nested-unwind-by-return") (i32.const 9)) - -(assert_trap (invoke "unary-after-unreachable") "unreachable") -(assert_return (invoke "unary-after-br") (i32.const 9)) -(assert_return (invoke "unary-after-br_if") (i32.const 9)) -(assert_return (invoke "unary-after-br_table") (i32.const 9)) -(assert_return (invoke "unary-after-return") (i32.const 9)) - -(assert_trap (invoke "binary-after-unreachable") "unreachable") -(assert_return (invoke "binary-after-br") (i32.const 9)) -(assert_return (invoke "binary-after-br_if") (i32.const 9)) -(assert_return (invoke "binary-after-br_table") (i32.const 9)) -(assert_return (invoke "binary-after-return") (i32.const 9)) - -(assert_trap (invoke "select-after-unreachable") "unreachable") -(assert_return (invoke "select-after-br") (i32.const 9)) -(assert_return (invoke "select-after-br_if") (i32.const 9)) -(assert_return (invoke "select-after-br_table") (i32.const 9)) -(assert_return (invoke "select-after-return") (i32.const 9)) - -(assert_trap (invoke "block-value-after-unreachable") "unreachable") -(assert_return (invoke "block-value-after-br") (i32.const 9)) -(assert_return (invoke "block-value-after-br_if") (i32.const 9)) -(assert_return (invoke "block-value-after-br_table") (i32.const 9)) -(assert_return (invoke "block-value-after-return") (i32.const 9)) - -(assert_trap (invoke "loop-value-after-unreachable") "unreachable") -(assert_return (invoke "loop-value-after-br") (i32.const 9)) -(assert_return (invoke "loop-value-after-br_if") (i32.const 9)) -(assert_return (invoke "loop-value-after-br_table") (i32.const 9)) -(assert_return (invoke "loop-value-after-return") (i32.const 9)) diff --git a/test/spec/utf8-custom-section-id.wast b/test/spec/utf8-custom-section-id.wast deleted file mode 100644 index 129d2b91393..00000000000 --- a/test/spec/utf8-custom-section-id.wast +++ /dev/null @@ -1,1792 +0,0 @@ -;;;;;; Invalid UTF-8 custom section names - -;;;; Continuation bytes not preceded by prefixes - -;; encoding starts with (first) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\80" ;; "\80" - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x8f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\8f" ;; "\8f" - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x90) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\90" ;; "\90" - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x9f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\9f" ;; "\9f" - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0xa0) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\a0" ;; "\a0" - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (last) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\bf" ;; "\bf" - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequences - -;; 2-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\c2\80\80" ;; "\c2\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\c2" ;; "\c2" - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c2\2e" ;; "\c2." - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequence contents - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c0\80" ;; "\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c0\bf" ;; "\c0\bf" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c1\80" ;; "\c1\80" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c1\bf" ;; "\c1\bf" - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a contination byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c2\00" ;; "\c2\00" - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c2\7f" ;; "\c2\7f" - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c2\c0" ;; "\c2\c0" - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\c2\fd" ;; "\c2\fd" - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\df\00" ;; "\df\00" - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\df\7f" ;; "\df\7f" - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\df\c0" ;; "\df\c0" - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\df\fd" ;; "\df\fd" - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequences - -;; 3-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\e1\80\80\80" ;; "\e1\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\e1\80" ;; "\e1\80" - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\80\2e" ;; "\e1\80." - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\e1" ;; "\e1" - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\e1\2e" ;; "\e1." - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\00\a0" ;; "\e0\00\a0" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\7f\a0" ;; "\e0\7f\a0" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\80\80" ;; "\e0\80\80" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\80\a0" ;; "\e0\80\a0" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\9f\a0" ;; "\e0\9f\a0" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\9f\bf" ;; "\e0\9f\bf" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\c0\a0" ;; "\e0\c0\a0" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\fd\a0" ;; "\e0\fd\a0" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\00\80" ;; "\e1\00\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\7f\80" ;; "\e1\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\c0\80" ;; "\e1\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\fd\80" ;; "\e1\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\00\80" ;; "\ec\00\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\7f\80" ;; "\ec\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\c0\80" ;; "\ec\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\fd\80" ;; "\ec\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\00\80" ;; "\ed\00\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\7f\80" ;; "\ed\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\a0\80" ;; "\ed\a0\80" - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\a0\bf" ;; "\ed\a0\bf" - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\bf\80" ;; "\ed\bf\80" - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\bf\bf" ;; "\ed\bf\bf" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\c0\80" ;; "\ed\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\fd\80" ;; "\ed\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\00\80" ;; "\ee\00\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\7f\80" ;; "\ee\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\c0\80" ;; "\ee\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\fd\80" ;; "\ee\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\00\80" ;; "\ef\00\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\7f\80" ;; "\ef\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\c0\80" ;; "\ef\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\fd\80" ;; "\ef\fd\80" - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents (third byte) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\a0\00" ;; "\e0\a0\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\a0\7f" ;; "\e0\a0\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\a0\c0" ;; "\e0\a0\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e0\a0\fd" ;; "\e0\a0\fd" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\80\00" ;; "\e1\80\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\80\7f" ;; "\e1\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\80\c0" ;; "\e1\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\e1\80\fd" ;; "\e1\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\80\00" ;; "\ec\80\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\80\7f" ;; "\ec\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\80\c0" ;; "\ec\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ec\80\fd" ;; "\ec\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\80\00" ;; "\ed\80\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\80\7f" ;; "\ed\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\80\c0" ;; "\ed\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ed\80\fd" ;; "\ed\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\80\00" ;; "\ee\80\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\80\7f" ;; "\ee\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\80\c0" ;; "\ee\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ee\80\fd" ;; "\ee\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\80\00" ;; "\ef\80\00" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\80\7f" ;; "\ef\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\80\c0" ;; "\ef\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\ef\80\fd" ;; "\ef\80\fd" - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequences - -;; 4-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\f1\80\80" ;; "\f1\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\80\23" ;; "\f1\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\f1\80" ;; "\f1\80" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\f1\80\23" ;; "\f1\80#" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\f1" ;; "\f1" - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\f1\23" ;; "\f1#" - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\00\90\90" ;; "\f0\00\90\90" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\7f\90\90" ;; "\f0\7f\90\90" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\80\80\80" ;; "\f0\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\80\90\90" ;; "\f0\80\90\90" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\8f\90\90" ;; "\f0\8f\90\90" - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\c0\90\90" ;; "\f0\c0\90\90" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\fd\90\90" ;; "\f0\fd\90\90" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\00\80\80" ;; "\f1\00\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\7f\80\80" ;; "\f1\7f\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\c0\80\80" ;; "\f1\c0\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\fd\80\80" ;; "\f1\fd\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\00\80\80" ;; "\f3\00\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\7f\80\80" ;; "\f3\7f\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\c0\80\80" ;; "\f3\c0\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\fd\80\80" ;; "\f3\fd\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\00\80\80" ;; "\f4\00\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\7f\80\80" ;; "\f4\7f\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\90\80\80" ;; "\f4\90\80\80" - ) - "invalid UTF-8 encoding" -) - -;; invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\bf\80\80" ;; "\f4\bf\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\c0\80\80" ;; "\f4\c0\80\80" - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\fd\80\80" ;; "\f4\fd\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f5\80\80\80" ;; "\f5\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f7\80\80\80" ;; "\f7\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (third byte) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\00\90" ;; "\f0\90\00\90" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\7f\90" ;; "\f0\90\7f\90" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\c0\90" ;; "\f0\90\c0\90" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\fd\90" ;; "\f0\90\fd\90" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\00\80" ;; "\f1\80\00\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\7f\80" ;; "\f1\80\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\c0\80" ;; "\f1\80\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\fd\80" ;; "\f1\80\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\00\80" ;; "\f3\80\00\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\7f\80" ;; "\f3\80\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\c0\80" ;; "\f3\80\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\fd\80" ;; "\f3\80\fd\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\00\80" ;; "\f4\80\00\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\7f\80" ;; "\f4\80\7f\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\c0\80" ;; "\f4\80\c0\80" - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\fd\80" ;; "\f4\80\fd\80" - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (fourth byte) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\90\00" ;; "\f0\90\90\00" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\90\7f" ;; "\f0\90\90\7f" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\90\c0" ;; "\f0\90\90\c0" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f0\90\90\fd" ;; "\f0\90\90\fd" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\80\00" ;; "\f1\80\80\00" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\80\7f" ;; "\f1\80\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\80\c0" ;; "\f1\80\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f1\80\80\fd" ;; "\f1\80\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\80\00" ;; "\f3\80\80\00" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\80\7f" ;; "\f3\80\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\80\c0" ;; "\f3\80\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f3\80\80\fd" ;; "\f3\80\80\fd" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\80\00" ;; "\f4\80\80\00" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\80\7f" ;; "\f4\80\80\7f" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\80\c0" ;; "\f4\80\80\c0" - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f4\80\80\fd" ;; "\f4\80\80\fd" - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequences - -;; 5-byte sequence contains 6 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\07" ;; custom section - "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f8\80\80\80" ;; "\f8\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\f8\80\80" ;; "\f8\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\f8\80\80\23" ;; "\f8\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\f8\80" ;; "\f8\80" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\f8\80\23" ;; "\f8\80#" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\f8" ;; "\f8" - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\f8\23" ;; "\f8#" - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequence contents - -;; (first) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequences - -;; 6-byte sequence contains 7 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\08" ;; custom section - "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\07" ;; custom section - "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\fc\80\80\80" ;; "\fc\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\06" ;; custom section - "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\fc\80\80" ;; "\fc\80\80" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\fc\80\80\23" ;; "\fc\80\80#" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\fc\80" ;; "\fc\80" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\04" ;; custom section - "\03\fc\80\23" ;; "\fc\80#" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\fc" ;; "\fc" - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\fc\23" ;; "\fc#" - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequence contents - -;; (first) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\07" ;; custom section - "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\07" ;; custom section - "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" - ) - "invalid UTF-8 encoding" -) - -;;;; Miscellaneous invalid bytes - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\fe" ;; "\fe" - ) - "invalid UTF-8 encoding" -) - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\02" ;; custom section - "\01\ff" ;; "\ff" - ) - "invalid UTF-8 encoding" -) - -;; UTF-16BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\fe\ff" ;; "\fe\ff" - ) - "invalid UTF-8 encoding" -) - -;; UTF-32BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\00\00\fe\ff" ;; "\00\00\fe\ff" - ) - "invalid UTF-8 encoding" -) - -;; UTF-16LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\03" ;; custom section - "\02\ff\fe" ;; "\ff\fe" - ) - "invalid UTF-8 encoding" -) - -;; UTF-32LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00\05" ;; custom section - "\04\ff\fe\00\00" ;; "\ff\fe\00\00" - ) - "invalid UTF-8 encoding" -) - diff --git a/test/spec/utf8-import-field.wast b/test/spec/utf8-import-field.wast deleted file mode 100644 index 1ff2aa03068..00000000000 --- a/test/spec/utf8-import-field.wast +++ /dev/null @@ -1,2672 +0,0 @@ -;;;;;; Invalid UTF-8 import field names - -;;;; Continuation bytes not preceded by prefixes - -;; encoding starts with (first) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\80" ;; "\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x8f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\8f" ;; "\8f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x90) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\90" ;; "\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x9f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\9f" ;; "\9f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0xa0) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\a0" ;; "\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (last) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\bf" ;; "\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequences - -;; 2-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\c2\80\80" ;; "\c2\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\c2" ;; "\c2" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c2\2e" ;; "\c2." - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequence contents - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c0\80" ;; "\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c0\bf" ;; "\c0\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c1\80" ;; "\c1\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c1\bf" ;; "\c1\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a contination byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c2\00" ;; "\c2\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c2\7f" ;; "\c2\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c2\c0" ;; "\c2\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\c2\fd" ;; "\c2\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\df\00" ;; "\df\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\df\7f" ;; "\df\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\df\c0" ;; "\df\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\df\fd" ;; "\df\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequences - -;; 3-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\e1\80\80\80" ;; "\e1\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\e1\80" ;; "\e1\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\80\2e" ;; "\e1\80." - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\e1" ;; "\e1" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\e1\2e" ;; "\e1." - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\00\a0" ;; "\e0\00\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\7f\a0" ;; "\e0\7f\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\80\80" ;; "\e0\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\80\a0" ;; "\e0\80\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\9f\a0" ;; "\e0\9f\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\9f\bf" ;; "\e0\9f\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\c0\a0" ;; "\e0\c0\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\fd\a0" ;; "\e0\fd\a0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\00\80" ;; "\e1\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\7f\80" ;; "\e1\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\c0\80" ;; "\e1\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\fd\80" ;; "\e1\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\00\80" ;; "\ec\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\7f\80" ;; "\ec\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\c0\80" ;; "\ec\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\fd\80" ;; "\ec\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\00\80" ;; "\ed\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\7f\80" ;; "\ed\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\a0\80" ;; "\ed\a0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\a0\bf" ;; "\ed\a0\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\bf\80" ;; "\ed\bf\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\bf\bf" ;; "\ed\bf\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\c0\80" ;; "\ed\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\fd\80" ;; "\ed\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\00\80" ;; "\ee\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\7f\80" ;; "\ee\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\c0\80" ;; "\ee\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\fd\80" ;; "\ee\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\00\80" ;; "\ef\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\7f\80" ;; "\ef\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\c0\80" ;; "\ef\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\fd\80" ;; "\ef\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents (third byte) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\a0\00" ;; "\e0\a0\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\a0\7f" ;; "\e0\a0\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\a0\c0" ;; "\e0\a0\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e0\a0\fd" ;; "\e0\a0\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\80\00" ;; "\e1\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\80\7f" ;; "\e1\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\80\c0" ;; "\e1\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\e1\80\fd" ;; "\e1\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\80\00" ;; "\ec\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\80\7f" ;; "\ec\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\80\c0" ;; "\ec\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ec\80\fd" ;; "\ec\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\80\00" ;; "\ed\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\80\7f" ;; "\ed\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\80\c0" ;; "\ed\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ed\80\fd" ;; "\ed\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\80\00" ;; "\ee\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\80\7f" ;; "\ee\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\80\c0" ;; "\ee\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ee\80\fd" ;; "\ee\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\80\00" ;; "\ef\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\80\7f" ;; "\ef\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\80\c0" ;; "\ef\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\ef\80\fd" ;; "\ef\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequences - -;; 4-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\f1\80\80" ;; "\f1\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\80\23" ;; "\f1\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\f1\80" ;; "\f1\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\f1\80\23" ;; "\f1\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\f1" ;; "\f1" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\f1\23" ;; "\f1#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\00\90\90" ;; "\f0\00\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\7f\90\90" ;; "\f0\7f\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\80\80\80" ;; "\f0\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\80\90\90" ;; "\f0\80\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\8f\90\90" ;; "\f0\8f\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\c0\90\90" ;; "\f0\c0\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\fd\90\90" ;; "\f0\fd\90\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\00\80\80" ;; "\f1\00\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\7f\80\80" ;; "\f1\7f\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\c0\80\80" ;; "\f1\c0\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\fd\80\80" ;; "\f1\fd\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\00\80\80" ;; "\f3\00\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\7f\80\80" ;; "\f3\7f\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\c0\80\80" ;; "\f3\c0\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\fd\80\80" ;; "\f3\fd\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\00\80\80" ;; "\f4\00\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\7f\80\80" ;; "\f4\7f\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\90\80\80" ;; "\f4\90\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\bf\80\80" ;; "\f4\bf\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\c0\80\80" ;; "\f4\c0\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\fd\80\80" ;; "\f4\fd\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f5\80\80\80" ;; "\f5\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f7\80\80\80" ;; "\f7\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (third byte) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\00\90" ;; "\f0\90\00\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\7f\90" ;; "\f0\90\7f\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\c0\90" ;; "\f0\90\c0\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\fd\90" ;; "\f0\90\fd\90" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\00\80" ;; "\f1\80\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\7f\80" ;; "\f1\80\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\c0\80" ;; "\f1\80\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\fd\80" ;; "\f1\80\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\00\80" ;; "\f3\80\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\7f\80" ;; "\f3\80\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\c0\80" ;; "\f3\80\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\fd\80" ;; "\f3\80\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\00\80" ;; "\f4\80\00\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\7f\80" ;; "\f4\80\7f\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\c0\80" ;; "\f4\80\c0\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\fd\80" ;; "\f4\80\fd\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (fourth byte) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\90\00" ;; "\f0\90\90\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\90\7f" ;; "\f0\90\90\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\90\c0" ;; "\f0\90\90\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f0\90\90\fd" ;; "\f0\90\90\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\80\00" ;; "\f1\80\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\80\7f" ;; "\f1\80\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\80\c0" ;; "\f1\80\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f1\80\80\fd" ;; "\f1\80\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\80\00" ;; "\f3\80\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\80\7f" ;; "\f3\80\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\80\c0" ;; "\f3\80\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f3\80\80\fd" ;; "\f3\80\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\80\00" ;; "\f4\80\80\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\80\7f" ;; "\f4\80\80\7f" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\80\c0" ;; "\f4\80\80\c0" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f4\80\80\fd" ;; "\f4\80\80\fd" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequences - -;; 5-byte sequence contains 6 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f8\80\80\80" ;; "\f8\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\f8\80\80" ;; "\f8\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\f8\80\80\23" ;; "\f8\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\f8\80" ;; "\f8\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\f8\80\23" ;; "\f8\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\f8" ;; "\f8" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\f8\23" ;; "\f8#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequence contents - -;; (first) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequences - -;; 6-byte sequence contains 7 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\11" ;; import section - "\01" ;; length 1 - "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\fc\80\80\80" ;; "\fc\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\fc\80\80" ;; "\fc\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\fc\80\80\23" ;; "\fc\80\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\fc\80" ;; "\fc\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\03\fc\80\23" ;; "\fc\80#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\fc" ;; "\fc" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\fc\23" ;; "\fc#" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequence contents - -;; (first) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; Miscellaneous invalid bytes - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\fe" ;; "\fe" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\01\ff" ;; "\ff" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-16BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\fe\ff" ;; "\fe\ff" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-32BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\00\00\fe\ff" ;; "\00\00\fe\ff" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-16LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\02\ff\fe" ;; "\ff\fe" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-32LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\ff\fe\00\00" ;; "\ff\fe\00\00" - "\04\74\65\73\74" ;; "test" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - diff --git a/test/spec/utf8-import-module.wast b/test/spec/utf8-import-module.wast deleted file mode 100644 index ceabbeb7ce9..00000000000 --- a/test/spec/utf8-import-module.wast +++ /dev/null @@ -1,2672 +0,0 @@ -;;;;;; Invalid UTF-8 import module names - -;;;; Continuation bytes not preceded by prefixes - -;; encoding starts with (first) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\80" ;; "\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x8f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\8f" ;; "\8f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x90) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\90" ;; "\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0x9f) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\9f" ;; "\9f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (0xa0) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\a0" ;; "\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; encoding starts with (last) continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\bf" ;; "\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequences - -;; 2-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\c2\80\80" ;; "\c2\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\c2" ;; "\c2" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 2-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c2\2e" ;; "\c2." - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 2-byte sequence contents - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c0\80" ;; "\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c0\bf" ;; "\c0\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c1\80" ;; "\c1\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xc1 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c1\bf" ;; "\c1\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a contination byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c2\00" ;; "\c2\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c2\7f" ;; "\c2\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c2\c0" ;; "\c2\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (first) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\c2\fd" ;; "\c2\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\df\00" ;; "\df\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\df\7f" ;; "\df\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\df\c0" ;; "\df\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte after (last) 2-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\df\fd" ;; "\df\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequences - -;; 3-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\e1\80\80\80" ;; "\e1\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\e1\80" ;; "\e1\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\80\2e" ;; "\e1\80." - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\e1" ;; "\e1" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 3-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\e1\2e" ;; "\e1." - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\00\a0" ;; "\e0\00\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\7f\a0" ;; "\e0\7f\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\80\80" ;; "\e0\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\80\a0" ;; "\e0\80\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\9f\a0" ;; "\e0\9f\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xe0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\9f\bf" ;; "\e0\9f\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\c0\a0" ;; "\e0\c0\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\fd\a0" ;; "\e0\fd\a0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\00\80" ;; "\e1\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\7f\80" ;; "\e1\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\c0\80" ;; "\e1\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\fd\80" ;; "\e1\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\00\80" ;; "\ec\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\7f\80" ;; "\ec\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\c0\80" ;; "\ec\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\fd\80" ;; "\ec\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\00\80" ;; "\ed\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\7f\80" ;; "\ed\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\a0\80" ;; "\ed\a0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\a0\bf" ;; "\ed\a0\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\bf\80" ;; "\ed\bf\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; byte sequence reserved for UTF-16 surrogate half -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\bf\bf" ;; "\ed\bf\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\c0\80" ;; "\ed\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\fd\80" ;; "\ed\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\00\80" ;; "\ee\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\7f\80" ;; "\ee\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\c0\80" ;; "\ee\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\fd\80" ;; "\ee\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\00\80" ;; "\ef\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\7f\80" ;; "\ef\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\c0\80" ;; "\ef\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\fd\80" ;; "\ef\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 3-byte sequence contents (third byte) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\a0\00" ;; "\e0\a0\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\a0\7f" ;; "\e0\a0\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\a0\c0" ;; "\e0\a0\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xe0) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e0\a0\fd" ;; "\e0\a0\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\80\00" ;; "\e1\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\80\7f" ;; "\e1\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\80\c0" ;; "\e1\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\e1\80\fd" ;; "\e1\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\80\00" ;; "\ec\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\80\7f" ;; "\ec\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\80\c0" ;; "\ec\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ec\80\fd" ;; "\ec\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\80\00" ;; "\ed\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\80\7f" ;; "\ed\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\80\c0" ;; "\ed\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xed) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ed\80\fd" ;; "\ed\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\80\00" ;; "\ee\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\80\7f" ;; "\ee\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\80\c0" ;; "\ee\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ee\80\fd" ;; "\ee\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\80\00" ;; "\ef\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\80\7f" ;; "\ef\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\80\c0" ;; "\ef\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 3-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\ef\80\fd" ;; "\ef\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequences - -;; 4-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\f1\80\80" ;; "\f1\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\80\23" ;; "\f1\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\f1\80" ;; "\f1\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\f1\80\23" ;; "\f1\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\f1" ;; "\f1" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 4-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\f1\23" ;; "\f1#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\00\90\90" ;; "\f0\00\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\7f\90\90" ;; "\f0\7f\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\80\80\80" ;; "\f0\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\80\90\90" ;; "\f0\80\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\8f\90\90" ;; "\f0\8f\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; overlong encoding after 0xf0 prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\c0\90\90" ;; "\f0\c0\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\fd\90\90" ;; "\f0\fd\90\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\00\80\80" ;; "\f1\00\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\7f\80\80" ;; "\f1\7f\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\c0\80\80" ;; "\f1\c0\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\fd\80\80" ;; "\f1\fd\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\00\80\80" ;; "\f3\00\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\7f\80\80" ;; "\f3\7f\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\c0\80\80" ;; "\f3\c0\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\fd\80\80" ;; "\f3\fd\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\00\80\80" ;; "\f4\00\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\7f\80\80" ;; "\f4\7f\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\90\80\80" ;; "\f4\90\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; invalid code point -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\bf\80\80" ;; "\f4\bf\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\c0\80\80" ;; "\f4\c0\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; first byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\fd\80\80" ;; "\f4\fd\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (first) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f5\80\80\80" ;; "\f5\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f7\80\80\80" ;; "\f7\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 4-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (third byte) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\00\90" ;; "\f0\90\00\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\7f\90" ;; "\f0\90\7f\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\c0\90" ;; "\f0\90\c0\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\fd\90" ;; "\f0\90\fd\90" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\00\80" ;; "\f1\80\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\7f\80" ;; "\f1\80\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\c0\80" ;; "\f1\80\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\fd\80" ;; "\f1\80\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\00\80" ;; "\f3\80\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\7f\80" ;; "\f3\80\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\c0\80" ;; "\f3\80\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\fd\80" ;; "\f3\80\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\00\80" ;; "\f4\80\00\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\7f\80" ;; "\f4\80\7f\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\c0\80" ;; "\f4\80\c0\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; second byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\fd\80" ;; "\f4\80\fd\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 4-byte sequence contents (fourth byte) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\90\00" ;; "\f0\90\90\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\90\7f" ;; "\f0\90\90\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\90\c0" ;; "\f0\90\90\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf0) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f0\90\90\fd" ;; "\f0\90\90\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\80\00" ;; "\f1\80\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\80\7f" ;; "\f1\80\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\80\c0" ;; "\f1\80\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (first normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f1\80\80\fd" ;; "\f1\80\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\80\00" ;; "\f3\80\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\80\7f" ;; "\f3\80\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\80\c0" ;; "\f3\80\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (last normal) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f3\80\80\fd" ;; "\f3\80\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\80\00" ;; "\f4\80\80\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\80\7f" ;; "\f4\80\80\7f" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\80\c0" ;; "\f4\80\80\c0" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; third byte after (0xf4) 4-byte prefix not a continuation byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f4\80\80\fd" ;; "\f4\80\80\fd" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequences - -;; 5-byte sequence contains 6 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f8\80\80\80" ;; "\f8\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\f8\80\80" ;; "\f8\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\f8\80\80\23" ;; "\f8\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\f8\80" ;; "\f8\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\f8\80\23" ;; "\f8\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\f8" ;; "\f8" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 5-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\f8\23" ;; "\f8#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 5-byte sequence contents - -;; (first) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 5-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequences - -;; 6-byte sequence contains 7 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\11" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 5 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\fc\80\80\80" ;; "\fc\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 4 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0f" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\fc\80\80" ;; "\fc\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 3 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\fc\80\80\23" ;; "\fc\80\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\fc\80" ;; "\fc\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 2 bytes -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0d" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\03\fc\80\23" ;; "\fc\80#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte at end of string -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\fc" ;; "\fc" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; 6-byte sequence contains 1 byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\fc\23" ;; "\fc#" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; 6-byte sequence contents - -;; (first) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; (last) invalid 6-byte prefix -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\10" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;;;; Miscellaneous invalid bytes - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\fe" ;; "\fe" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; invalid byte -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0b" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\01\ff" ;; "\ff" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-16BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\fe\ff" ;; "\fe\ff" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-32BE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\00\00\fe\ff" ;; "\00\00\fe\ff" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-16LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0c" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\02\ff\fe" ;; "\ff\fe" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - -;; UTF-32LE BOM -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\02\0e" ;; import section - "\01" ;; length 1 - "\04\74\65\73\74" ;; "test" - "\04\ff\fe\00\00" ;; "\ff\fe\00\00" - "\03" ;; GlobalImport - "\7f" ;; i32 - "\00" ;; immutable - ) - "invalid UTF-8 encoding" -) - diff --git a/test/spec/utf8-invalid-encoding.wast b/test/spec/utf8-invalid-encoding.wast deleted file mode 100644 index 3b35730989c..00000000000 --- a/test/spec/utf8-invalid-encoding.wast +++ /dev/null @@ -1,176 +0,0 @@ -(assert_malformed (module quote "(func (export \"\\00\\00\\fe\\ff\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\8f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\9f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c0\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c1\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c1\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\2e\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\c2\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\df\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\df\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\df\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\df\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\00\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\7f\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\80\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\9f\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\9f\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\a0\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\a0\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\a0\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\a0\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\c0\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e0\\fd\\a0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\2e\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\2e\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\e1\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ec\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\a0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\a0\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\bf\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\bf\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ed\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ee\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ef\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\00\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\7f\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\80\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\8f\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\8f\\bf\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\00\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\7f\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\90\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\90\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\90\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\90\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\c0\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\90\\fd\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\c0\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f0\\fd\\90\\90\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\00\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\7f\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\80\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\c0\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f1\\fd\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\00\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\7f\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\80\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\c0\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f3\\fd\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\00\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\7f\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\00\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\7f\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\80\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\80\\7f\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\80\\c0\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\80\\fd\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\c0\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\80\\fd\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\90\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\bf\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\c0\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f4\\fd\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f5\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f7\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f7\\bf\\bf\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\f8\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fb\\bf\\bf\\bf\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\\80\\23\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\\80\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fc\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fd\\bf\\bf\\bf\\bf\\bf\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fe\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\fe\\ff\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ff\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ff\\fe\\00\\00\"))") "invalid UTF-8 encoding") -(assert_malformed (module quote "(func (export \"\\ff\\fe\"))") "invalid UTF-8 encoding") diff --git a/test/wasm2js/i32.2asm.js b/test/wasm2js/i32.2asm.js index 691ff7bb25c..62a4387a969 100644 --- a/test/wasm2js/i32.2asm.js +++ b/test/wasm2js/i32.2asm.js @@ -116,65 +116,75 @@ function asmFunc(imports) { } function $18(x) { + x = x | 0; + return x << 24 >> 24 | 0; + } + + function $19(x) { + x = x | 0; + return x << 16 >> 16 | 0; + } + + function $20(x) { x = x | 0; return !x | 0; } - function $19(x, y) { + function $21(x, y) { x = x | 0; y = y | 0; return (x | 0) == (y | 0) | 0; } - function $20(x, y) { + function $22(x, y) { x = x | 0; y = y | 0; return (x | 0) != (y | 0) | 0; } - function $21(x, y) { + function $23(x, y) { x = x | 0; y = y | 0; return (x | 0) < (y | 0) | 0; } - function $22(x, y) { + function $24(x, y) { x = x | 0; y = y | 0; return x >>> 0 < y >>> 0 | 0; } - function $23(x, y) { + function $25(x, y) { x = x | 0; y = y | 0; return (x | 0) <= (y | 0) | 0; } - function $24(x, y) { + function $26(x, y) { x = x | 0; y = y | 0; return x >>> 0 <= y >>> 0 | 0; } - function $25(x, y) { + function $27(x, y) { x = x | 0; y = y | 0; return (x | 0) > (y | 0) | 0; } - function $26(x, y) { + function $28(x, y) { x = x | 0; y = y | 0; return x >>> 0 > y >>> 0 | 0; } - function $27(x, y) { + function $29(x, y) { x = x | 0; y = y | 0; return (x | 0) >= (y | 0) | 0; } - function $28(x, y) { + function $30(x, y) { x = x | 0; y = y | 0; return x >>> 0 >= y >>> 0 | 0; @@ -242,17 +252,19 @@ function asmFunc(imports) { "clz": $15, "ctz": $16, "popcnt": $17, - "eqz": $18, - "eq": $19, - "ne": $20, - "lt_s": $21, - "lt_u": $22, - "le_s": $23, - "le_u": $24, - "gt_s": $25, - "gt_u": $26, - "ge_s": $27, - "ge_u": $28 + "extend8_s": $18, + "extend16_s": $19, + "eqz": $20, + "eq": $21, + "ne": $22, + "lt_s": $23, + "lt_u": $24, + "le_s": $25, + "le_u": $26, + "gt_s": $27, + "gt_u": $28, + "ge_s": $29, + "ge_u": $30 }; } @@ -276,6 +288,8 @@ export var rotr = retasmFunc.rotr; export var clz = retasmFunc.clz; export var ctz = retasmFunc.ctz; export var popcnt = retasmFunc.popcnt; +export var extend8_s = retasmFunc.extend8_s; +export var extend16_s = retasmFunc.extend16_s; export var eqz = retasmFunc.eqz; export var eq = retasmFunc.eq; export var ne = retasmFunc.ne; From 9772dc6cf3ce153b1eb2a570901161194e06e6a6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 20 Aug 2024 18:20:39 -0700 Subject: [PATCH 532/553] Fix encoding of heap type definitions (#6856) The leading bytes that indicate what kind of heap type is being defined are bytes, but we were previously treating them as SLEB128-encoded values. Since we emit the smallest LEB encodings possible, we were writing the correct bytes in output files, but we were also improperly accepting binaries that used more than one byte to encode these values. This was caught by an upstream spec test. --- scripts/test/shared.py | 5 +- src/wasm-binary.h | 18 +- src/wasm/wasm-binary.cpp | 26 +- test/spec/binary-leb128.wast | 963 ----------------------------------- 4 files changed, 24 insertions(+), 988 deletions(-) delete mode 100644 test/spec/binary-leb128.wast diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 08aebcdd3a8..c3878fa82cb 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -412,9 +412,8 @@ def get_tests(test_dir, extensions=[], recursive=False): 'elem.wast', ] SPEC_TESTSUITE_TESTS_TO_SKIP = [ - 'address.wast', - 'align.wast', - 'binary-leb128.wast', + 'address.wast', # 64-bit offset allowed by memory64 + 'align.wast', # Alignment bit 6 used by multi-memory 'binary.wast', 'block.wast', 'br_table.wast', diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 32eb7657c59..8c199022487 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -376,15 +376,15 @@ enum EncodedType { // string reference types stringref = -0x19, // 0x67 // type forms - Func = -0x20, // 0x60 - Cont = -0x23, // 0x5d - Struct = -0x21, // 0x5f - Array = -0x22, // 0x5e - Sub = -0x30, // 0x50 - SubFinal = -0x31, // 0x4f - Shared = -0x1b, // 0x65 - // isorecursive recursion groups - Rec = -0x32, // 0x4e + Func = 0x60, + Cont = 0x5d, + Struct = 0x5f, + Array = 0x5e, + Sub = 0x50, + SubFinal = 0x4f, + SharedDef = 0x65, + Shared = -0x1b, // Also 0x65 as an SLEB128 + Rec = 0x4e, // block_type Empty = -0x40, // 0x40 }; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 8565ddaadb1..865ca39cac2 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -269,7 +269,7 @@ void WasmBinaryWriter::writeTypes() { // size 1 are implicit, so only emit a group header for larger groups. auto currGroup = type.getRecGroup(); if (lastGroup != currGroup && currGroup.size() > 1) { - o << S32LEB(BinaryConsts::EncodedType::Rec) << U32LEB(currGroup.size()); + o << uint8_t(BinaryConsts::EncodedType::Rec) << U32LEB(currGroup.size()); } lastGroup = currGroup; // Emit the type definition. @@ -277,9 +277,9 @@ void WasmBinaryWriter::writeTypes() { auto super = type.getDeclaredSuperType(); if (super || type.isOpen()) { if (type.isOpen()) { - o << S32LEB(BinaryConsts::EncodedType::Sub); + o << uint8_t(BinaryConsts::EncodedType::Sub); } else { - o << S32LEB(BinaryConsts::EncodedType::SubFinal); + o << uint8_t(BinaryConsts::EncodedType::SubFinal); } if (super) { o << U32LEB(1); @@ -289,11 +289,11 @@ void WasmBinaryWriter::writeTypes() { } } if (type.isShared()) { - o << S32LEB(BinaryConsts::EncodedType::Shared); + o << uint8_t(BinaryConsts::EncodedType::SharedDef); } switch (type.getKind()) { case HeapTypeKind::Func: { - o << S32LEB(BinaryConsts::EncodedType::Func); + o << uint8_t(BinaryConsts::EncodedType::Func); auto sig = type.getSignature(); for (auto& sigType : {sig.params, sig.results}) { o << U32LEB(sigType.size()); @@ -304,7 +304,7 @@ void WasmBinaryWriter::writeTypes() { break; } case HeapTypeKind::Struct: { - o << S32LEB(BinaryConsts::EncodedType::Struct); + o << uint8_t(BinaryConsts::EncodedType::Struct); auto fields = type.getStruct().fields; o << U32LEB(fields.size()); for (const auto& field : fields) { @@ -313,11 +313,11 @@ void WasmBinaryWriter::writeTypes() { break; } case HeapTypeKind::Array: - o << S32LEB(BinaryConsts::EncodedType::Array); + o << uint8_t(BinaryConsts::EncodedType::Array); writeField(type.getArray().element); break; case HeapTypeKind::Cont: - o << S32LEB(BinaryConsts::EncodedType::Cont); + o << uint8_t(BinaryConsts::EncodedType::Cont); writeHeapType(type.getContinuation().type); break; case HeapTypeKind::Basic: @@ -2405,7 +2405,7 @@ void WasmBinaryReader::readTypes() { for (size_t i = 0; i < builder.size(); i++) { BYN_TRACE("read one\n"); - auto form = getS32LEB(); + auto form = getInt8(); if (form == BinaryConsts::EncodedType::Rec) { uint32_t groupSize = getU32LEB(); if (groupSize == 0u) { @@ -2416,7 +2416,7 @@ void WasmBinaryReader::readTypes() { // allocate space for the extra types. builder.grow(groupSize - 1); builder.createRecGroup(i, groupSize); - form = getS32LEB(); + form = getInt8(); } std::optional superIndex; if (form == BinaryConsts::EncodedType::Sub || @@ -2432,11 +2432,11 @@ void WasmBinaryReader::readTypes() { } superIndex = getU32LEB(); } - form = getS32LEB(); + form = getInt8(); } - if (form == BinaryConsts::Shared) { + if (form == BinaryConsts::SharedDef) { builder[i].setShared(); - form = getS32LEB(); + form = getInt8(); } if (form == BinaryConsts::EncodedType::Func) { builder[i] = readSignatureDef(); diff --git a/test/spec/binary-leb128.wast b/test/spec/binary-leb128.wast deleted file mode 100644 index 9afcb540ced..00000000000 --- a/test/spec/binary-leb128.wast +++ /dev/null @@ -1,963 +0,0 @@ -;; Unsigned LEB128 can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\05\04\01" ;; Memory section with 1 entry - "\00\82\00" ;; no max, minimum 2 -) -(module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\00" ;; no max, minimum 2 -) -(module binary - "\00asm" "\01\00\00\00" - "\05\06\01" ;; Memory section with 1 entry - "\01\82\00" ;; minimum 2 - "\82\00" ;; max 2 -) -(module binary - "\00asm" "\01\00\00\00" - "\05\09\01" ;; Memory section with 1 entry - "\01\82\00" ;; minimum 2 - "\82\80\80\80\00" ;; max 2 -) -(module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\07\01" ;; Data section with 1 entry - "\80\00" ;; Memory index 0, encoded with 2 bytes - "\41\00\0b\00" ;; (i32.const 0) with contents "" -) -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\07\01" ;; Element section with 1 entry - "\80\00" ;; Table index 0, encoded with 2 bytes - "\41\00\0b\00" ;; (i32.const 0) with no elements -) -(module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\8a\00" ;; section size 10, encoded with 2 bytes - "\01" ;; name byte count - "1" ;; name - "23456789" ;; sequence of bytes -) -(module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\0b" ;; section size - "\88\00" ;; name byte count 8, encoded with 2 bytes - "12345678" ;; name - "9" ;; sequence of bytes -) -(module binary - "\00asm" "\01\00\00\00" - "\01\08\01" ;; type section - "\60" ;; func type - "\82\00" ;; num params 2, encoded with 2 bytes - "\7f\7e" ;; param type - "\01" ;; num results - "\7f" ;; result type -) -(module binary - "\00asm" "\01\00\00\00" - "\01\08\01" ;; type section - "\60" ;; func type - "\02" ;; num params - "\7f\7e" ;; param type - "\81\00" ;; num results 1, encoded with 2 bytes - "\7f" ;; result type -) -(module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\17\01" ;; import section - "\88\00" ;; module name length 8, encoded with 2 bytes - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index -) -(module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\17\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\89\00" ;; entity name length 9, encoded with 2 bytes - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index -) -(module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\17\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length 9 - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\80\00" ;; import signature index, encoded with 2 bytes -) -(module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; function type - "\03\03\01" ;; function section - "\80\00" ;; function 0 signature index, encoded with 2 bytes - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body -) -(module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\07\01" ;; export section - "\82\00" ;; string length 2, encoded with 2 bytes - "\66\31" ;; export name f1 - "\00" ;; export kind - "\00" ;; export func index - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body -) -(module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\07\01" ;; export section - "\02" ;; string length 2 - "\66\31" ;; export name f1 - "\00" ;; export kind - "\80\00" ;; export func index, encoded with 2 bytes - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body -) -(module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\0a" ;; code section - "\05" ;; section size - "\81\00" ;; num functions, encoded with 2 bytes - "\02\00\0b" ;; function body -) - -;; Signed LEB128 can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\00" ;; i32.const 0 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\7f" ;; i32.const -1 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\00" ;; i32.const 0 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\7f" ;; i32.const -1 - "\0b" ;; end -) - -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\00" ;; i64.const 0 with unused bits set - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\7f" ;; i64.const -1 with unused bits unset - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with unused bits set - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with unused bits unset - "\0b" ;; end -) - -;; Unsigned LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\08\01" ;; Memory section with 1 entry - "\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\0a\01" ;; Memory section with 1 entry - "\01\82\00" ;; minimum 2 - "\82\80\80\80\80\00" ;; max 2 with one byte too many - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\0b\01" ;; Data section with 1 entry - "\80\80\80\80\80\00" ;; Memory index 0 with one byte too many - "\41\00\0b\00" ;; (i32.const 0) with contents "" - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\0b\01" ;; Element section with 1 entry - "\80\80\80\80\80\00" ;; Table index 0 with one byte too many - "\41\00\0b\00" ;; (i32.const 0) with no elements - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\83\80\80\80\80\00" ;; section size 3 with one byte too many - "\01" ;; name byte count - "1" ;; name - "2" ;; sequence of bytes - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\0A" ;; section size - "\83\80\80\80\80\00" ;; name byte count 3 with one byte too many - "123" ;; name - "4" ;; sequence of bytes - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\0c\01" ;; type section - "\60" ;; func type - "\82\80\80\80\80\00" ;; num params 2 with one byte too many - "\7f\7e" ;; param type - "\01" ;; num result - "\7f" ;; result type - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\08\01" ;; type section - "\60" ;; func type - "\02" ;; num params - "\7f\7e" ;; param type - "\81\80\80\80\80\00" ;; num result 1 with one byte too many - "\7f" ;; result type - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1b\01" ;; import section - "\88\80\80\80\80\00" ;; module name length 8 with one byte too many - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1b\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\89\80\80\80\80\00" ;; entity name length 9 with one byte too many - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1b\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length 9 - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\80\80\80\80\80\00" ;; import signature index 0 with one byte too many - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; function type - "\03\03\01" ;; function section - "\80\80\80\80\80\00" ;; function 0 signature index with one byte too many - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\0b\01" ;; export section - "\82\80\80\80\80\00" ;; string length 2 with one byte too many - "\66\31" ;; export name f1 - "\00" ;; export kind - "\00" ;; export func index - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\0b\01" ;; export section - "\02" ;; string length 2 - "\66\31" ;; export name f1 - "\00" ;; export kind - "\80\80\80\80\80\00" ;; export func index 0 with one byte too many - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\0a" ;; code section - "\05" ;; section size - "\81\80\80\80\80\00" ;; num functions 1 with one byte too many - "\02\00\0b" ;; function body - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\1a" ;; drop - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\80\00" ;; alignment 2 with one byte too many - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\12\01" ;; Code section - ;; function 0 - "\10\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\80\00" ;; alignment 2 with one byte too many - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\12\01" ;; Code section - ;; function 0 - "\10\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -;; Signed LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\80\00" ;; i32.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\ff\7f" ;; i32.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -;; Unsigned LEB128s zero-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\09\01" ;; Memory section with 1 entry - "\01\82\00" ;; minimum 2 - "\82\80\80\80\10" ;; max 2 with unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\09\01" ;; Memory section with 1 entry - "\01\82\00" ;; minimum 2 - "\82\80\80\80\40" ;; max 2 with some unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\0a\01" ;; Data section with 1 entry - "\80\80\80\80\10" ;; Memory index 0 with unused bits set - "\41\00\0b\00" ;; (i32.const 0) with contents "" - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\0a\01" ;; Element section with 1 entry - "\80\80\80\80\10" ;; Table index 0 with unused bits set - "\41\00\0b\00" ;; (i32.const 0) with no elements - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\83\80\80\80\10" ;; section size 3 with unused bits set - "\01" ;; name byte count - "1" ;; name - "2" ;; sequence of bytes - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\00" ;; custom section - "\09" ;; section size - "\83\80\80\80\40" ;; name byte count 3 with unused bits set - "123" ;; name - "4" ;; sequence of bytes - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\0b\01" ;; type section - "\60" ;; func type - "\82\80\80\80\10" ;; num params 2 with unused bits set - "\7f\7e" ;; param type - "\01" ;; num result - "\7f" ;; result type - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\0b\01" ;; type section - "\60" ;; func type - "\02" ;; num params - "\7f\7e" ;; param type - "\81\80\80\80\40" ;; num result 1 with unused bits set - "\7f" ;; result type - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1a\01" ;; import section - "\88\80\80\80\10" ;; module name length 8 with unused bits set - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1a\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\89\80\80\80\40" ;; entity name length 9 with unused bits set - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\00" ;; import signature index - ) - "integer too large" -) -(assert_malformed -(module binary - "\00asm" "\01\00\00\00" - "\01\05\01" ;; type section - "\60\01\7f\00" ;; function type - "\02\1a\01" ;; import section - "\08" ;; module name length - "\73\70\65\63\74\65\73\74" ;; module name - "\09" ;; entity name length 9 - "\70\72\69\6e\74\5f\69\33\32" ;; entity name - "\00" ;; import kind - "\80\80\80\80\10" ;; import signature index 0 with unused bits set -) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; function type - "\03\06\01" ;; function section - "\80\80\80\80\10" ;; function 0 signature index with unused bits set - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer too large" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\0a\01" ;; export section - "\82\80\80\80\10" ;; string length 2 with unused bits set - "\66\31" ;; export name f1 - "\00" ;; export kind - "\00" ;; export func index - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\07\0a\01" ;; export section - "\02" ;; string length 2 - "\66\31" ;; export name f1 - "\00" ;; export kind - "\80\80\80\80\10" ;; export func index with unused bits set - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01" ;; type section - "\60\00\00" ;; fun type - "\03\02\01\00" ;; function section - "\0a" ;; code section - "\08" ;; section size - "\81\80\80\80\10" ;; num functions 1 with unused bits set - "\02\00\0b" ;; function body - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\10" ;; alignment 2 with unused bits set - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\40" ;; alignment 2 with some unused bits set - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\10" ;; alignment 2 with unused bits set - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\40" ;; alignment 2 with some unused bits set - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\03" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) - -;; Signed LEB128s sign-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\70" ;; i32.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\0f" ;; i32.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\1f" ;; i32.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\4f" ;; i32.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) From adf53b3b7606a16988b548fe5423b0272913a05a Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 21 Aug 2024 09:07:55 -0700 Subject: [PATCH 533/553] [NFC] Triage spec test problems (#6857) Add comments to the spec test skip list briefly explaining why each skipped spec test must be skipped. --- scripts/test/shared.py | 161 ++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 81 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index c3878fa82cb..6be7530c259 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -414,90 +414,89 @@ def get_tests(test_dir, extensions=[], recursive=False): SPEC_TESTSUITE_TESTS_TO_SKIP = [ 'address.wast', # 64-bit offset allowed by memory64 'align.wast', # Alignment bit 6 used by multi-memory - 'binary.wast', - 'block.wast', - 'br_table.wast', - 'bulk.wast', - 'comments.wast', - 'const.wast', - 'conversions.wast', - 'data.wast', - 'elem.wast', - 'f32.wast', - 'f64.wast', - 'fac.wast', - 'float_exprs.wast', - 'float_misc.wast', - 'func.wast', - 'global.wast', - 'if.wast', - 'imports.wast', - 'linking.wast', - 'loop.wast', - 'memory.wast', - 'annotations.wast', - 'id.wast', - 'throw.wast', - 'try_catch.wast', - 'tag.wast', - 'throw_ref.wast', - 'try_table.wast', - 'br_on_non_null.wast', - 'br_on_null.wast', - 'local_init.wast', - 'ref_func.wast', - 'ref_is_null.wast', - 'ref_null.wast', - 'return_call_indirect.wast', - 'select.wast', - 'table.wast', - 'type-equivalence.wast', - 'unreached-invalid.wast', - 'array.wast', - 'array_init_elem.wast', - 'br_if.wast', - 'br_on_cast.wast', - 'br_on_cast_fail.wast', - 'extern.wast', - 'i31.wast', - 'ref_cast.wast', - 'ref_test.wast', - 'struct.wast', - 'type-rec.wast', - 'type-subtyping.wast', - 'call_indirect.wast', - 'memory64.wast', - 'table_fill.wast', - 'table_get.wast', - 'table_grow.wast', - 'table_init.wast', - 'table_set.wast', - 'imports0.wast', - 'imports2.wast', - 'imports3.wast', - 'linking0.wast', - 'linking3.wast', - 'i16x8_relaxed_q15mulr_s.wast', - 'i32x4_relaxed_trunc.wast', - 'i8x16_relaxed_swizzle.wast', - 'relaxed_dot_product.wast', - 'relaxed_laneselect.wast', - 'relaxed_madd_nmadd.wast', - 'relaxed_min_max.wast', - 'simd_address.wast', - 'simd_boolean.wast', - 'simd_const.wast', - 'simd_conversions.wast', - 'simd_f32x4.wast', - 'simd_f32x4_arith.wast', - 'simd_f32x4_rounding.wast', - 'simd_f64x2.wast', - 'simd_f64x2_arith.wast', - 'simd_f64x2_rounding.wast', + 'binary.wast', # memory.grow reserved byte a LEB in multi-memory + 'block.wast', # Requires block parameters + 'br_table.wast', # Requires ref.extern wast constants + 'bulk.wast', # Requires table.init abbreviation with implicit table + 'comments.wast', # Issue with carriage returns being treated as newlines + 'const.wast', # Hex float constant not recognized as out of range + 'conversions.wast', # Promoted NaN should be canonical + 'data.wast', # Constant global references allowed by GC + 'elem.wast', # Requires table.init abbreviation with implicit table + 'f32.wast', # Adding -0 and -nan should give a canonical NaN + 'f64.wast', # Adding -0 and -nan should give a canonical NaN + 'fac.wast', # Requires block parameters (on a loop) + 'float_exprs.wast', # Adding 0 and NaN should give canonical NaN + 'float_misc.wast', # Rounding wrong on f64.sqrt + 'func.wast', # Duplicate parameter names not properly rejected + 'global.wast', # Requires ref.extern wast constants + 'if.wast', # Requires block parameters (on an if) + 'imports.wast', # Requires wast `register` support + 'linking.wast', # Requires wast `register` support + 'loop.wast', # Requires block parameters (on a loop) + 'memory.wast', # Multiple memories now allowed + 'annotations.wast', # String annotations IDs should be allowed + 'id.wast', # Empty IDs should be disallowed + 'throw.wast', # Requires try_table interpretation + 'try_catch.wast', # Requires wast `register` support + 'tag.wast', # Non-empty tag results allowed by stack switching + 'throw_ref.wast', # Requires block parameters (on an if) + 'try_table.wast', # Requires try_table interpretation + 'br_on_non_null.wast', # Requires sending values on br_on_non_null + 'br_on_null.wast', # Requires sending values on br_on_null + 'local_init.wast', # Requires ref.extern wast constants + 'ref_func.wast', # Requires rejecting undeclared functions references + 'ref_is_null.wast', # Requires ref.extern wast constants + 'ref_null.wast', # Requires ref.null wast constants + 'return_call_indirect.wast', # Requires more precise unreachable validation + 'select.wast', # Requires ref.extern wast constants + 'table.wast', # Requires support for table default elements + 'type-equivalence.wast', # Recursive types allowed by GC + 'unreached-invalid.wast', # Requires more precise unreachable validation + 'array.wast', # Requires ref.array wast constants + 'array_init_elem.wast', # Requires support for elem.drop + 'br_if.wast', # Requires more precise branch validation + 'br_on_cast.wast', # Requires sending values on br_on_cast + 'br_on_cast_fail.wast', # Requires sending values on br_on_cast_fail + 'extern.wast', # Requires ref.extern wast constants + 'i31.wast', # Requires ref.i31 wast constants + 'ref_cast.wast', # Requires ref.extern wast constants + 'ref_test.wast', # Requires ref.extern wast constants + 'struct.wast', # Requires ref.struct wast constants + 'type-rec.wast', # Requires wast `register` support + 'type-subtyping.wast', # ShellExternalInterface::callTable does not handle subtyping + 'call_indirect.wast', # Bug with 64-bit inline element segment parsing + 'memory64.wast', # Multiple memories now allowed + 'table_fill.wast', # Requires ref.extern wast constants + 'table_get.wast', # Requires ref.extern wast constants + 'table_grow.wast', # Requires ref.extern wast constants + 'table_init.wast', # Requires support for elem.drop + 'table_set.wast', # Requires ref.extern wast constants + 'imports0.wast', # Requires wast `register` support + 'imports2.wast', # Requires wast `register` support + 'imports3.wast', # Requires wast `register` support + 'linking0.wast', # Requires wast `register` support + 'linking3.wast', # Requires wast `register` support + 'i16x8_relaxed_q15mulr_s.wast', # Requires wast `either` support + 'i32x4_relaxed_trunc.wast', # Requires wast `either` support + 'i8x16_relaxed_swizzle.wast', # Requires wast `either` support + 'relaxed_dot_product.wast', # Requires wast `either` support + 'relaxed_laneselect.wast', # Requires wast `either` support + 'relaxed_madd_nmadd.wast', # Requires wast `either` support + 'relaxed_min_max.wast', # Requires wast `either` support + 'simd_address.wast', # 64-bit offset allowed by memory64 + 'simd_const.wast', # Hex float constant not recognized as out of range + 'simd_conversions.wast', # Promoted NaN should be canonical + 'simd_f32x4.wast', # Min of 0 and NaN should give a canonical NaN + 'simd_f32x4_arith.wast', # Adding inf and -inf should give a canonical NaN + 'simd_f32x4_rounding.wast', # Ceil of NaN should give a canonical NaN + 'simd_f64x2.wast', # Min of 0 and NaN should give a canonical NaN + 'simd_f64x2_arith.wast', # Adding inf and -inf should give a canonical NaN + 'simd_f64x2_rounding.wast', # Ceil of NaN should give a canonical NaN 'simd_i32x4_cmp.wast', # UBSan error on integer overflow 'simd_i32x4_arith2.wast', # UBSan error on integer overflow 'simd_i32x4_dot_i16x8.wast', # UBSan error on integer overflow - 'token.wast', + 'token.wast', # Lexer should require spaces between strings and non-paren tokens ] options.spec_tests = [t for t in options.spec_tests if os.path.basename(t) not in (SPEC_TESTSUITE_TESTS_TO_SKIP if 'testsuite' in t From 7889abf8137291cc591cac8f38570789ebaf354d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 21 Aug 2024 10:39:09 -0700 Subject: [PATCH 534/553] Support `ref.extern n` in spec tests (#6858) Spec tests pass the value `ref.extern n`, where `n` is some integer, into exported functions that expect to receive externrefs and receive such values back out as return values. The payload serves to distinguish externrefs so the test can assert that the correct one was returned. Parse these values in wast scripts and represent them as externalized i31refs carrying the payload. We will need a different representation eventually, since some tests explicitly expect these externrefs to not be i31refs, but this suffices to get several new tests passing. To get the memory64 version of table_grow.wast passing, additionally fix the interpreter to handle growing 64-bit tables correctly. Delete the local versions of the upstream tests that can now be run successfully. --- scripts/test/shared.py | 19 +- scripts/test/wasm2js.py | 1 + src/parser/wast-parser.cpp | 12 +- src/tools/wasm-shell.cpp | 3 +- src/wasm-interpreter.h | 13 +- src/wasm/literal.cpp | 3 + test/spec/br_table.wast | 1593 ------------------------------------ test/spec/table_fill.wast | 222 ----- test/spec/table_get.wast | 94 --- test/spec/table_grow.wast | 174 ---- test/spec/table_set.wast | 129 --- 11 files changed, 29 insertions(+), 2234 deletions(-) delete mode 100644 test/spec/br_table.wast delete mode 100644 test/spec/table_fill.wast delete mode 100644 test/spec/table_get.wast delete mode 100644 test/spec/table_grow.wast delete mode 100644 test/spec/table_set.wast diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 6be7530c259..019d2b25188 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -416,7 +416,6 @@ def get_tests(test_dir, extensions=[], recursive=False): 'align.wast', # Alignment bit 6 used by multi-memory 'binary.wast', # memory.grow reserved byte a LEB in multi-memory 'block.wast', # Requires block parameters - 'br_table.wast', # Requires ref.extern wast constants 'bulk.wast', # Requires table.init abbreviation with implicit table 'comments.wast', # Issue with carriage returns being treated as newlines 'const.wast', # Hex float constant not recognized as out of range @@ -429,7 +428,7 @@ def get_tests(test_dir, extensions=[], recursive=False): 'float_exprs.wast', # Adding 0 and NaN should give canonical NaN 'float_misc.wast', # Rounding wrong on f64.sqrt 'func.wast', # Duplicate parameter names not properly rejected - 'global.wast', # Requires ref.extern wast constants + 'global.wast', # Globals allowed to refer to previous globals by GC 'if.wast', # Requires block parameters (on an if) 'imports.wast', # Requires wast `register` support 'linking.wast', # Requires wast `register` support @@ -444,12 +443,12 @@ def get_tests(test_dir, extensions=[], recursive=False): 'try_table.wast', # Requires try_table interpretation 'br_on_non_null.wast', # Requires sending values on br_on_non_null 'br_on_null.wast', # Requires sending values on br_on_null - 'local_init.wast', # Requires ref.extern wast constants + 'local_init.wast', # Requires local validation to respect unnamed blocks 'ref_func.wast', # Requires rejecting undeclared functions references - 'ref_is_null.wast', # Requires ref.extern wast constants + 'ref_is_null.wast', # Requires ref.null wast constants 'ref_null.wast', # Requires ref.null wast constants 'return_call_indirect.wast', # Requires more precise unreachable validation - 'select.wast', # Requires ref.extern wast constants + 'select.wast', # Requires ref.null wast constants 'table.wast', # Requires support for table default elements 'type-equivalence.wast', # Recursive types allowed by GC 'unreached-invalid.wast', # Requires more precise unreachable validation @@ -458,20 +457,16 @@ def get_tests(test_dir, extensions=[], recursive=False): 'br_if.wast', # Requires more precise branch validation 'br_on_cast.wast', # Requires sending values on br_on_cast 'br_on_cast_fail.wast', # Requires sending values on br_on_cast_fail - 'extern.wast', # Requires ref.extern wast constants + 'extern.wast', # Requires ref.host wast constants 'i31.wast', # Requires ref.i31 wast constants - 'ref_cast.wast', # Requires ref.extern wast constants - 'ref_test.wast', # Requires ref.extern wast constants + 'ref_cast.wast', # Requires host references to not be externalized i31refs + 'ref_test.wast', # Requires host references to not be externalized i31refs 'struct.wast', # Requires ref.struct wast constants 'type-rec.wast', # Requires wast `register` support 'type-subtyping.wast', # ShellExternalInterface::callTable does not handle subtyping 'call_indirect.wast', # Bug with 64-bit inline element segment parsing 'memory64.wast', # Multiple memories now allowed - 'table_fill.wast', # Requires ref.extern wast constants - 'table_get.wast', # Requires ref.extern wast constants - 'table_grow.wast', # Requires ref.extern wast constants 'table_init.wast', # Requires support for elem.drop - 'table_set.wast', # Requires ref.extern wast constants 'imports0.wast', # Requires wast `register` support 'imports2.wast', # Requires wast `register` support 'imports3.wast', # Requires wast `register` support diff --git a/scripts/test/wasm2js.py b/scripts/test/wasm2js.py index f7c9bd47909..d716e5fe665 100644 --- a/scripts/test/wasm2js.py +++ b/scripts/test/wasm2js.py @@ -30,6 +30,7 @@ wasm2js_skipped_tests = [ 'empty_imported_table.wast', 'br.wast', # depends on multivalue + 'br_table.wast', # needs support for externref in assert_return ] diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index a3a6c14ce85..00269a57771 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -25,7 +25,17 @@ using namespace std::string_view_literals; namespace { Result const_(Lexer& in) { - // TODO: handle `ref.extern n` as well. + if (in.takeSExprStart("ref.extern"sv)) { + auto n = in.takeI32(); + if (!n) { + return in.err("expected host reference payload"); + } + if (!in.takeRParen()) { + return in.err("expected end of ref.extern"); + } + // Represent host references as externalized i31s. + return Literal::makeI31(*n, Unshared).externalize(); + } return parseConst(in); } diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 65185796516..eda4facc945 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -318,7 +318,8 @@ struct Shell { return Err{err.str()}; } } else if (auto* ref = std::get_if(&expected)) { - if (!val.type.isRef() || val.type.getHeapType() != ref->type) { + if (!val.type.isRef() || + !HeapType::isSubType(val.type.getHeapType(), ref->type)) { err << "expected " << ref->type << " reference, got " << val << atIndex(); return Err{err.str()}; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 1bf135c403e..cbd2b31d68e 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -3172,20 +3172,17 @@ class ModuleRunnerBase : public ExpressionRunner { } auto info = getTableInstanceInfo(curr->table); - Index tableSize = info.interface()->tableSize(info.name); + uint64_t tableSize = info.interface()->tableSize(info.name); auto* table = info.instance->wasm.getTable(info.name); Flow ret = Literal::makeFromInt64(tableSize, table->indexType); Flow fail = Literal::makeFromInt64(-1, table->indexType); - Index delta = deltaFlow.getSingleValue().geti32(); + uint64_t delta = deltaFlow.getSingleValue().getUnsigned(); - if (tableSize >= uint32_t(-1) - delta) { + uint64_t newSize; + if (std::ckd_add(&newSize, tableSize, delta)) { return fail; } - if (uint64_t(tableSize) + uint64_t(delta) > uint64_t(table->max)) { - return fail; - } - Index newSize = tableSize + delta; - if (newSize > WebLimitations::MaxTableSize) { + if (newSize > table->max || newSize > WebLimitations::MaxTableSize) { return fail; } if (!info.interface()->growTable( diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 650318be3c5..d60e2f8a9a0 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -463,6 +463,9 @@ bool Literal::operator==(const Literal& other) const { if (type.getHeapType().isMaybeShared(HeapType::i31)) { return i32 == other.i32; } + if (type.getHeapType().isMaybeShared(HeapType::ext)) { + return internalize() == other.internalize(); + } WASM_UNREACHABLE("unexpected type"); } WASM_UNREACHABLE("unexpected type"); diff --git a/test/spec/br_table.wast b/test/spec/br_table.wast deleted file mode 100644 index 58abe38a4f2..00000000000 --- a/test/spec/br_table.wast +++ /dev/null @@ -1,1593 +0,0 @@ -;; Test `br_table` operator - -(module - ;; Auxiliary definition - (func $dummy) - - (func (export "type-i32") - (block (drop (i32.ctz (br_table 0 0 (i32.const 0))))) - ) - (func (export "type-i64") - (block (drop (i64.ctz (br_table 0 0 (i32.const 0))))) - ) - (func (export "type-f32") - (block (drop (f32.neg (br_table 0 0 (i32.const 0))))) - ) - (func (export "type-f64") - (block (drop (f64.neg (br_table 0 0 (i32.const 0))))) - ) - - (func (export "type-i32-value") (result i32) - (block (result i32) (i32.ctz (br_table 0 0 (i32.const 1) (i32.const 0)))) - ) - (func (export "type-i64-value") (result i64) - (block (result i64) (i64.ctz (br_table 0 0 (i64.const 2) (i32.const 0)))) - ) - (func (export "type-f32-value") (result f32) - (block (result f32) (f32.neg (br_table 0 0 (f32.const 3) (i32.const 0)))) - ) - (func (export "type-f64-value") (result f64) - (block (result f64) (f64.neg (br_table 0 0 (f64.const 4) (i32.const 0)))) - ) - - (func (export "empty") (param i32) (result i32) - (block (br_table 0 (local.get 0)) (return (i32.const 21))) - (i32.const 22) - ) - (func (export "empty-value") (param i32) (result i32) - (block (result i32) - (br_table 0 (i32.const 33) (local.get 0)) (i32.const 31) - ) - ) - - (func (export "singleton") (param i32) (result i32) - (block - (block - (br_table 1 0 (local.get 0)) - (return (i32.const 21)) - ) - (return (i32.const 20)) - ) - (i32.const 22) - ) - - (func (export "singleton-value") (param i32) (result i32) - (block (result i32) - (drop - (block (result i32) - (br_table 0 1 (i32.const 33) (local.get 0)) - (return (i32.const 31)) - ) - ) - (i32.const 32) - ) - ) - - (func (export "multiple") (param i32) (result i32) - (block - (block - (block - (block - (block - (br_table 3 2 1 0 4 (local.get 0)) - (return (i32.const 99)) - ) - (return (i32.const 100)) - ) - (return (i32.const 101)) - ) - (return (i32.const 102)) - ) - (return (i32.const 103)) - ) - (i32.const 104) - ) - - (func (export "multiple-value") (param i32) (result i32) - (local i32) - (local.set 1 (block (result i32) - (local.set 1 (block (result i32) - (local.set 1 (block (result i32) - (local.set 1 (block (result i32) - (local.set 1 (block (result i32) - (br_table 3 2 1 0 4 (i32.const 200) (local.get 0)) - (return (i32.add (local.get 1) (i32.const 99))) - )) - (return (i32.add (local.get 1) (i32.const 10))) - )) - (return (i32.add (local.get 1) (i32.const 11))) - )) - (return (i32.add (local.get 1) (i32.const 12))) - )) - (return (i32.add (local.get 1) (i32.const 13))) - )) - (i32.add (local.get 1) (i32.const 14)) - ) - - (func (export "large") (param i32) (result i32) - (block - (block - (br_table - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 - (local.get 0) - ) - (return (i32.const -1)) - ) - (return (i32.const 0)) - ) - (return (i32.const 1)) - ) - - (func (export "as-block-first") - (block (br_table 0 0 0 (i32.const 0)) (call $dummy)) - ) - (func (export "as-block-mid") - (block (call $dummy) (br_table 0 0 0 (i32.const 0)) (call $dummy)) - ) - (func (export "as-block-last") - (block (nop) (call $dummy) (br_table 0 0 0 (i32.const 0))) - ) - (func (export "as-block-value") (result i32) - (block (result i32) - (nop) (call $dummy) (br_table 0 0 0 (i32.const 2) (i32.const 0)) - ) - ) - - (func (export "as-loop-first") (result i32) - (loop (result i32) (br_table 1 1 (i32.const 3) (i32.const 0)) (i32.const 1)) - ) - (func (export "as-loop-mid") (result i32) - (loop (result i32) - (call $dummy) - (br_table 1 1 1 (i32.const 4) (i32.const -1)) - (i32.const 2) - ) - ) - (func (export "as-loop-last") (result i32) - (loop (result i32) - (nop) (call $dummy) (br_table 1 1 1 (i32.const 5) (i32.const 1)) - ) - ) - - (func (export "as-br-value") (result i32) - (block (result i32) (br 0 (br_table 0 (i32.const 9) (i32.const 0)))) - ) - - (func (export "as-br_if-cond") - (block (br_if 0 (br_table 0 0 0 (i32.const 1)))) - ) - (func (export "as-br_if-value") (result i32) - (block (result i32) - (drop (br_if 0 (br_table 0 (i32.const 8) (i32.const 0)) (i32.const 1))) - (i32.const 7) - ) - ) - (func (export "as-br_if-value-cond") (result i32) - (block (result i32) - (drop (br_if 0 (i32.const 6) (br_table 0 0 (i32.const 9) (i32.const 0)))) - (i32.const 7) - ) - ) - - (func (export "as-br_table-index") - (block (br_table 0 0 0 (br_table 0 (i32.const 1)))) - ) - (func (export "as-br_table-value") (result i32) - (block (result i32) - (br_table 0 0 0 (br_table 0 (i32.const 10) (i32.const 0)) (i32.const 1)) - (i32.const 7) - ) - ) - (func (export "as-br_table-value-index") (result i32) - (block (result i32) - (br_table 0 0 (i32.const 6) (br_table 0 (i32.const 11) (i32.const 1))) - (i32.const 7) - ) - ) - - (func (export "as-return-value") (result i64) - (block (result i64) (return (br_table 0 (i64.const 7) (i32.const 0)))) - ) - - (func (export "as-if-cond") (result i32) - (block (result i32) - (if (result i32) - (br_table 0 (i32.const 2) (i32.const 0)) - (then (i32.const 0)) - (else (i32.const 1)) - ) - ) - ) - (func (export "as-if-then") (param i32 i32) (result i32) - (block (result i32) - (if (result i32) - (local.get 0) - (then (br_table 1 (i32.const 3) (i32.const 0))) - (else (local.get 1)) - ) - ) - ) - (func (export "as-if-else") (param i32 i32) (result i32) - (block (result i32) - (if (result i32) - (local.get 0) - (then (local.get 1)) - (else (br_table 1 0 (i32.const 4) (i32.const 0))) - ) - ) - ) - - (func (export "as-select-first") (param i32 i32) (result i32) - (block (result i32) - (select - (br_table 0 (i32.const 5) (i32.const 0)) (local.get 0) (local.get 1) - ) - ) - ) - (func (export "as-select-second") (param i32 i32) (result i32) - (block (result i32) - (select - (local.get 0) (br_table 0 (i32.const 6) (i32.const 1)) (local.get 1) - ) - ) - ) - (func (export "as-select-cond") (result i32) - (block (result i32) - (select - (i32.const 0) (i32.const 1) (br_table 0 (i32.const 7) (i32.const 1)) - ) - ) - ) - - (func $f (param i32 i32 i32) (result i32) (i32.const -1)) - (func (export "as-call-first") (result i32) - (block (result i32) - (call $f - (br_table 0 (i32.const 12) (i32.const 1)) (i32.const 2) (i32.const 3) - ) - ) - ) - (func (export "as-call-mid") (result i32) - (block (result i32) - (call $f - (i32.const 1) (br_table 0 (i32.const 13) (i32.const 1)) (i32.const 3) - ) - ) - ) - (func (export "as-call-last") (result i32) - (block (result i32) - (call $f - (i32.const 1) (i32.const 2) (br_table 0 (i32.const 14) (i32.const 1)) - ) - ) - ) - - (type $sig (func (param i32 i32 i32) (result i32))) - (table funcref (elem $f)) - (func (export "as-call_indirect-first") (result i32) - (block (result i32) - (call_indirect (type $sig) - (br_table 0 (i32.const 20) (i32.const 1)) (i32.const 1) (i32.const 2) - (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-mid") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) (br_table 0 (i32.const 21) (i32.const 1)) (i32.const 2) - (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-last") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (br_table 0 (i32.const 22) (i32.const 1)) - (i32.const 3) - ) - ) - ) - (func (export "as-call_indirect-func") (result i32) - (block (result i32) - (call_indirect (type $sig) - (i32.const 0) (i32.const 1) (i32.const 2) - (br_table 0 (i32.const 23) (i32.const 1)) - ) - ) - ) - - (func (export "as-local.set-value") (result i32) - (local f32) - (block (result i32) - (local.set 0 (br_table 0 (i32.const 17) (i32.const 1))) - (i32.const -1) - ) - ) - (func (export "as-local.tee-value") (result i32) - (local i32) - (block (result i32) - (local.set 0 (br_table 0 (i32.const 1) (i32.const 1))) - (i32.const -1) - ) - ) - (global $a (mut i32) (i32.const 10)) - (func (export "as-global.set-value") (result i32) - (block (result i32) - (global.set $a (br_table 0 (i32.const 1) (i32.const 1))) - (i32.const -1) - ) - ) - - (memory 1) - (func (export "as-load-address") (result f32) - (block (result f32) (f32.load (br_table 0 (f32.const 1.7) (i32.const 1)))) - ) - (func (export "as-loadN-address") (result i64) - (block (result i64) (i64.load8_s (br_table 0 (i64.const 30) (i32.const 1)))) - ) - - (func (export "as-store-address") (result i32) - (block (result i32) - (f64.store (br_table 0 (i32.const 30) (i32.const 1)) (f64.const 7)) - (i32.const -1) - ) - ) - (func (export "as-store-value") (result i32) - (block (result i32) - (i64.store (i32.const 2) (br_table 0 (i32.const 31) (i32.const 1))) - (i32.const -1) - ) - ) - - (func (export "as-storeN-address") (result i32) - (block (result i32) - (i32.store8 (br_table 0 (i32.const 32) (i32.const 0)) (i32.const 7)) - (i32.const -1) - ) - ) - (func (export "as-storeN-value") (result i32) - (block (result i32) - (i64.store16 (i32.const 2) (br_table 0 (i32.const 33) (i32.const 0))) - (i32.const -1) - ) - ) - - (func (export "as-unary-operand") (result f32) - (block (result f32) (f32.neg (br_table 0 (f32.const 3.4) (i32.const 0)))) - ) - - (func (export "as-binary-left") (result i32) - (block (result i32) - (i32.add (br_table 0 0 (i32.const 3) (i32.const 0)) (i32.const 10)) - ) - ) - (func (export "as-binary-right") (result i64) - (block (result i64) - (i64.sub (i64.const 10) (br_table 0 (i64.const 45) (i32.const 0))) - ) - ) - - (func (export "as-test-operand") (result i32) - (block (result i32) (i32.eqz (br_table 0 (i32.const 44) (i32.const 0)))) - ) - - (func (export "as-compare-left") (result i32) - (block (result i32) - (f64.le (br_table 0 0 (i32.const 43) (i32.const 0)) (f64.const 10)) - ) - ) - (func (export "as-compare-right") (result i32) - (block (result i32) - (f32.ne (f32.const 10) (br_table 0 (i32.const 42) (i32.const 0))) - ) - ) - - (func (export "as-convert-operand") (result i32) - (block (result i32) - (i32.wrap_i64 (br_table 0 (i32.const 41) (i32.const 0))) - ) - ) - - (func (export "as-memory.grow-size") (result i32) - (block (result i32) (memory.grow (br_table 0 (i32.const 40) (i32.const 0)))) - ) - - (func (export "nested-block-value") (param i32) (result i32) - (block (result i32) - (drop (i32.const -1)) - (i32.add - (i32.const 1) - (block (result i32) - (i32.add - (i32.const 2) - (block (result i32) - (drop (i32.const 4)) - (i32.add - (i32.const 8) - (br_table 0 1 2 (i32.const 16) (local.get 0)) - ) - ) - ) - ) - ) - ) - ) - - (func (export "nested-br-value") (param i32) (result i32) - (block (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (br 0 (br_table 2 1 0 (i32.const 8) (local.get 0))) - ) - ) - (i32.const 16) - ) - ) - ) - ) - - (func (export "nested-br_if-value") (param i32) (result i32) - (block (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (drop - (br_if 0 - (br_table 0 1 2 (i32.const 8) (local.get 0)) - (i32.const 1) - ) - ) - (i32.const 32) - ) - ) - (i32.const 16) - ) - ) - ) - ) - - (func (export "nested-br_if-value-cond") (param i32) (result i32) - (block (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (br_if 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (local.get 0))) - ) - (i32.const 16) - ) - ) - ) - ) - - (func (export "nested-br_table-value") (param i32) (result i32) - (block (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (drop - (block (result i32) - (drop (i32.const 4)) - (br_table 0 (br_table 0 1 2 (i32.const 8) (local.get 0)) (i32.const 1)) - (i32.const 32) - ) - ) - (i32.const 16) - ) - ) - ) - ) - - (func (export "nested-br_table-value-index") (param i32) (result i32) - (block (result i32) - (i32.add - (i32.const 1) - (block (result i32) - (drop (i32.const 2)) - (br_table 0 (i32.const 4) (br_table 0 1 0 (i32.const 8) (local.get 0))) - (i32.const 16) - ) - ) - ) - ) - - (func (export "nested-br_table-loop-block") (param i32) (result i32) - (local.set 0 - (loop (result i32) - (block - (br_table 1 0 0 (local.get 0)) - ) - (i32.const 0) - ) - ) - (loop (result i32) - (block - (br_table 0 1 1 (local.get 0)) - ) - (i32.const 3) - ) - ) -) - -(assert_return (invoke "type-i32")) -(assert_return (invoke "type-i64")) -(assert_return (invoke "type-f32")) -(assert_return (invoke "type-f64")) - -(assert_return (invoke "type-i32-value") (i32.const 1)) -(assert_return (invoke "type-i64-value") (i64.const 2)) -(assert_return (invoke "type-f32-value") (f32.const 3)) -(assert_return (invoke "type-f64-value") (f64.const 4)) - -(assert_return (invoke "empty" (i32.const 0)) (i32.const 22)) -(assert_return (invoke "empty" (i32.const 1)) (i32.const 22)) -(assert_return (invoke "empty" (i32.const 11)) (i32.const 22)) -(assert_return (invoke "empty" (i32.const -1)) (i32.const 22)) -(assert_return (invoke "empty" (i32.const -100)) (i32.const 22)) -(assert_return (invoke "empty" (i32.const 0xffffffff)) (i32.const 22)) - -(assert_return (invoke "empty-value" (i32.const 0)) (i32.const 33)) -(assert_return (invoke "empty-value" (i32.const 1)) (i32.const 33)) -(assert_return (invoke "empty-value" (i32.const 11)) (i32.const 33)) -(assert_return (invoke "empty-value" (i32.const -1)) (i32.const 33)) -(assert_return (invoke "empty-value" (i32.const -100)) (i32.const 33)) -(assert_return (invoke "empty-value" (i32.const 0xffffffff)) (i32.const 33)) - -(assert_return (invoke "singleton" (i32.const 0)) (i32.const 22)) -(assert_return (invoke "singleton" (i32.const 1)) (i32.const 20)) -(assert_return (invoke "singleton" (i32.const 11)) (i32.const 20)) -(assert_return (invoke "singleton" (i32.const -1)) (i32.const 20)) -(assert_return (invoke "singleton" (i32.const -100)) (i32.const 20)) -(assert_return (invoke "singleton" (i32.const 0xffffffff)) (i32.const 20)) - -(assert_return (invoke "singleton-value" (i32.const 0)) (i32.const 32)) -(assert_return (invoke "singleton-value" (i32.const 1)) (i32.const 33)) -(assert_return (invoke "singleton-value" (i32.const 11)) (i32.const 33)) -(assert_return (invoke "singleton-value" (i32.const -1)) (i32.const 33)) -(assert_return (invoke "singleton-value" (i32.const -100)) (i32.const 33)) -(assert_return (invoke "singleton-value" (i32.const 0xffffffff)) (i32.const 33)) - -(assert_return (invoke "multiple" (i32.const 0)) (i32.const 103)) -(assert_return (invoke "multiple" (i32.const 1)) (i32.const 102)) -(assert_return (invoke "multiple" (i32.const 2)) (i32.const 101)) -(assert_return (invoke "multiple" (i32.const 3)) (i32.const 100)) -(assert_return (invoke "multiple" (i32.const 4)) (i32.const 104)) -(assert_return (invoke "multiple" (i32.const 5)) (i32.const 104)) -(assert_return (invoke "multiple" (i32.const 6)) (i32.const 104)) -(assert_return (invoke "multiple" (i32.const 10)) (i32.const 104)) -(assert_return (invoke "multiple" (i32.const -1)) (i32.const 104)) -(assert_return (invoke "multiple" (i32.const 0xffffffff)) (i32.const 104)) - -(assert_return (invoke "multiple-value" (i32.const 0)) (i32.const 213)) -(assert_return (invoke "multiple-value" (i32.const 1)) (i32.const 212)) -(assert_return (invoke "multiple-value" (i32.const 2)) (i32.const 211)) -(assert_return (invoke "multiple-value" (i32.const 3)) (i32.const 210)) -(assert_return (invoke "multiple-value" (i32.const 4)) (i32.const 214)) -(assert_return (invoke "multiple-value" (i32.const 5)) (i32.const 214)) -(assert_return (invoke "multiple-value" (i32.const 6)) (i32.const 214)) -(assert_return (invoke "multiple-value" (i32.const 10)) (i32.const 214)) -(assert_return (invoke "multiple-value" (i32.const -1)) (i32.const 214)) -(assert_return (invoke "multiple-value" (i32.const 0xffffffff)) (i32.const 214)) - -(assert_return (invoke "large" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "large" (i32.const 1)) (i32.const 1)) -(assert_return (invoke "large" (i32.const 100)) (i32.const 0)) -(assert_return (invoke "large" (i32.const 101)) (i32.const 1)) -(assert_return (invoke "large" (i32.const 10000)) (i32.const 0)) -(assert_return (invoke "large" (i32.const 10001)) (i32.const 1)) -(assert_return (invoke "large" (i32.const 1000000)) (i32.const 1)) -(assert_return (invoke "large" (i32.const 1000001)) (i32.const 1)) - -(assert_return (invoke "as-block-first")) -(assert_return (invoke "as-block-mid")) -(assert_return (invoke "as-block-last")) -(assert_return (invoke "as-block-value") (i32.const 2)) - -(assert_return (invoke "as-loop-first") (i32.const 3)) -(assert_return (invoke "as-loop-mid") (i32.const 4)) -(assert_return (invoke "as-loop-last") (i32.const 5)) - -(assert_return (invoke "as-br-value") (i32.const 9)) - -(assert_return (invoke "as-br_if-cond")) -(assert_return (invoke "as-br_if-value") (i32.const 8)) -(assert_return (invoke "as-br_if-value-cond") (i32.const 9)) - -(assert_return (invoke "as-br_table-index")) -(assert_return (invoke "as-br_table-value") (i32.const 10)) -(assert_return (invoke "as-br_table-value-index") (i32.const 11)) - -(assert_return (invoke "as-return-value") (i64.const 7)) - -(assert_return (invoke "as-if-cond") (i32.const 2)) -(assert_return (invoke "as-if-then" (i32.const 1) (i32.const 6)) (i32.const 3)) -(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 6)) (i32.const 4)) -(assert_return (invoke "as-if-else" (i32.const 1) (i32.const 6)) (i32.const 6)) - -(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-first" (i32.const 1) (i32.const 6)) (i32.const 5)) -(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-second" (i32.const 1) (i32.const 6)) (i32.const 6)) -(assert_return (invoke "as-select-cond") (i32.const 7)) - -(assert_return (invoke "as-call-first") (i32.const 12)) -(assert_return (invoke "as-call-mid") (i32.const 13)) -(assert_return (invoke "as-call-last") (i32.const 14)) - -(assert_return (invoke "as-call_indirect-first") (i32.const 20)) -(assert_return (invoke "as-call_indirect-mid") (i32.const 21)) -(assert_return (invoke "as-call_indirect-last") (i32.const 22)) -(assert_return (invoke "as-call_indirect-func") (i32.const 23)) - -(assert_return (invoke "as-local.set-value") (i32.const 17)) -(assert_return (invoke "as-local.tee-value") (i32.const 1)) -(assert_return (invoke "as-global.set-value") (i32.const 1)) - -(assert_return (invoke "as-load-address") (f32.const 1.7)) -(assert_return (invoke "as-loadN-address") (i64.const 30)) - -(assert_return (invoke "as-store-address") (i32.const 30)) -(assert_return (invoke "as-store-value") (i32.const 31)) -(assert_return (invoke "as-storeN-address") (i32.const 32)) -(assert_return (invoke "as-storeN-value") (i32.const 33)) - -(assert_return (invoke "as-unary-operand") (f32.const 3.4)) - -(assert_return (invoke "as-binary-left") (i32.const 3)) -(assert_return (invoke "as-binary-right") (i64.const 45)) - -(assert_return (invoke "as-test-operand") (i32.const 44)) - -(assert_return (invoke "as-compare-left") (i32.const 43)) -(assert_return (invoke "as-compare-right") (i32.const 42)) - -(assert_return (invoke "as-convert-operand") (i32.const 41)) - -(assert_return (invoke "as-memory.grow-size") (i32.const 40)) - -(assert_return (invoke "nested-block-value" (i32.const 0)) (i32.const 19)) -(assert_return (invoke "nested-block-value" (i32.const 1)) (i32.const 17)) -(assert_return (invoke "nested-block-value" (i32.const 2)) (i32.const 16)) -(assert_return (invoke "nested-block-value" (i32.const 10)) (i32.const 16)) -(assert_return (invoke "nested-block-value" (i32.const -1)) (i32.const 16)) -(assert_return (invoke "nested-block-value" (i32.const 100000)) (i32.const 16)) - -(assert_return (invoke "nested-br-value" (i32.const 0)) (i32.const 8)) -(assert_return (invoke "nested-br-value" (i32.const 1)) (i32.const 9)) -(assert_return (invoke "nested-br-value" (i32.const 2)) (i32.const 17)) -(assert_return (invoke "nested-br-value" (i32.const 11)) (i32.const 17)) -(assert_return (invoke "nested-br-value" (i32.const -4)) (i32.const 17)) -(assert_return (invoke "nested-br-value" (i32.const 10213210)) (i32.const 17)) - -(assert_return (invoke "nested-br_if-value" (i32.const 0)) (i32.const 17)) -(assert_return (invoke "nested-br_if-value" (i32.const 1)) (i32.const 9)) -(assert_return (invoke "nested-br_if-value" (i32.const 2)) (i32.const 8)) -(assert_return (invoke "nested-br_if-value" (i32.const 9)) (i32.const 8)) -(assert_return (invoke "nested-br_if-value" (i32.const -9)) (i32.const 8)) -(assert_return (invoke "nested-br_if-value" (i32.const 999999)) (i32.const 8)) - -(assert_return (invoke "nested-br_if-value-cond" (i32.const 0)) (i32.const 9)) -(assert_return (invoke "nested-br_if-value-cond" (i32.const 1)) (i32.const 8)) -(assert_return (invoke "nested-br_if-value-cond" (i32.const 2)) (i32.const 9)) -(assert_return (invoke "nested-br_if-value-cond" (i32.const 3)) (i32.const 9)) -(assert_return (invoke "nested-br_if-value-cond" (i32.const -1000000)) (i32.const 9)) -(assert_return (invoke "nested-br_if-value-cond" (i32.const 9423975)) (i32.const 9)) - -(assert_return (invoke "nested-br_table-value" (i32.const 0)) (i32.const 17)) -(assert_return (invoke "nested-br_table-value" (i32.const 1)) (i32.const 9)) -(assert_return (invoke "nested-br_table-value" (i32.const 2)) (i32.const 8)) -(assert_return (invoke "nested-br_table-value" (i32.const 9)) (i32.const 8)) -(assert_return (invoke "nested-br_table-value" (i32.const -9)) (i32.const 8)) -(assert_return (invoke "nested-br_table-value" (i32.const 999999)) (i32.const 8)) - -(assert_return (invoke "nested-br_table-value-index" (i32.const 0)) (i32.const 9)) -(assert_return (invoke "nested-br_table-value-index" (i32.const 1)) (i32.const 8)) -(assert_return (invoke "nested-br_table-value-index" (i32.const 2)) (i32.const 9)) -(assert_return (invoke "nested-br_table-value-index" (i32.const 3)) (i32.const 9)) -(assert_return (invoke "nested-br_table-value-index" (i32.const -1000000)) (i32.const 9)) -(assert_return (invoke "nested-br_table-value-index" (i32.const 9423975)) (i32.const 9)) - -(assert_return (invoke "nested-br_table-loop-block" (i32.const 1)) (i32.const 3)) - -(assert_invalid - (module (func $type-arg-void-vs-num (result i32) - (block (br_table 0 (i32.const 1)) (i32.const 1)) - )) - "type mismatch" -) - -(assert_invalid - (module (func $type-arg-empty-vs-num (result i32) - (block (br_table 0) (i32.const 1)) - )) - "type mismatch" -) - -(assert_invalid - (module (func $type-arg-void-vs-num (result i32) - (block (result i32) (br_table 0 (nop) (i32.const 1)) (i32.const 1)) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-num-vs-num (result i32) - (block (result i32) - (br_table 0 0 0 (i64.const 1) (i32.const 1)) (i32.const 1) - ) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-num-vs-arg-num - (block - (block (result f32) - (br_table 0 1 (f32.const 0) (i32.const 0)) - ) - (drop) - ) - )) - "type mismatch" -) - -(assert_invalid - (module (func $type-index-void-vs-i32 - (block (br_table 0 0 0 (nop))) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-index-num-vs-i32 - (block (br_table 0 (i64.const 0))) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-index-void-vs-i32 (result i32) - (block (result i32) (br_table 0 0 (i32.const 0) (nop)) (i32.const 1)) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-void-vs-num-nested (result i32) - (block (result i32) (i32.const 0) (block (br_table 1 (i32.const 0)))) - )) - "type mismatch" -) -(assert_invalid - (module (func $type-arg-index-num-vs-i32 (result i32) - (block (result i32) - (br_table 0 0 (i32.const 0) (i64.const 0)) (i32.const 1) - ) - )) - "type mismatch" -) - -(assert_invalid - (module (func $type-arg-void-vs-num (result i32) - (block (br_table 0 (i32.const 1)) (i32.const 1)) - )) - "type mismatch" -) - -(assert_invalid - (module - (func $type-arg-index-empty-in-then - (block - (i32.const 0) (i32.const 0) - (if (result i32) (then (br_table 0))) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-value-empty-in-then - (block - (i32.const 0) (i32.const 0) - (if (result i32) (then (br_table 0 (i32.const 1)))) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-index-empty-in-return - (block (result i32) - (return (br_table 0)) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (func $type-arg-value-empty-in-return - (block (result i32) - (return (br_table 0 (i32.const 1))) - ) - (i32.eqz) (drop) - ) - ) - "type mismatch" -) - - -(assert_invalid - (module (func $unbound-label - (block (br_table 2 1 (i32.const 1))) - )) - "unknown label" -) -(assert_invalid - (module (func $unbound-nested-label - (block (block (br_table 0 5 (i32.const 1)))) - )) - "unknown label" -) -(assert_invalid - (module (func $large-label - (block (br_table 0 0x10000001 0 (i32.const 1))) - )) - "unknown label" -) - -(assert_invalid - (module (func $unbound-label-default - (block (br_table 1 2 (i32.const 1))) - )) - "unknown label" -) -(assert_invalid - (module (func $unbound-nested-label-default - (block (block (br_table 0 5 (i32.const 1)))) - )) - "unknown label" -) -(assert_invalid - (module (func $large-label-default - (block (br_table 0 0 0x10000001 (i32.const 1))) - )) - "unknown label" -) - diff --git a/test/spec/table_fill.wast b/test/spec/table_fill.wast deleted file mode 100644 index 5471e2e23ec..00000000000 --- a/test/spec/table_fill.wast +++ /dev/null @@ -1,222 +0,0 @@ -(module - (table $t 10 externref) - - (func (export "fill") (param $i i32) (param $r externref) (param $n i32) - (table.fill $t (local.get $i) (local.get $r) (local.get $n)) - ) - - (func (export "fill-abbrev") (param $i i32) (param $r externref) (param $n i32) - (table.fill (local.get $i) (local.get $r) (local.get $n)) - ) - - (func (export "get") (param $i i32) (result externref) - (table.get $t (local.get $i)) - ) - - (table $t64 i64 10 externref) - - (func (export "fill-t64") (param $i i64) (param $r externref) (param $n i64) - (table.fill $t64 (local.get $i) (local.get $r) (local.get $n)) - ) - - (func (export "get-t64") (param $i i64) (result externref) - (table.get $t64 (local.get $i)) - ) -) - -(assert_return (invoke "get" (i32.const 1)) (ref.null extern)) -(assert_return (invoke "get" (i32.const 2)) (ref.null extern)) -(assert_return (invoke "get" (i32.const 3)) (ref.null extern)) -(assert_return (invoke "get" (i32.const 4)) (ref.null extern)) -(assert_return (invoke "get" (i32.const 5)) (ref.null extern)) - -;; (assert_return (invoke "fill" (i32.const 2) (ref.extern 1) (i32.const 3))) -(assert_return (invoke "get" (i32.const 1)) (ref.null extern)) -;; (assert_return (invoke "get" (i32.const 2)) (ref.extern 1)) -;; (assert_return (invoke "get" (i32.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get" (i32.const 4)) (ref.extern 1)) -(assert_return (invoke "get" (i32.const 5)) (ref.null extern)) - -;; (assert_return (invoke "fill" (i32.const 4) (ref.extern 2) (i32.const 2))) -;; (assert_return (invoke "get" (i32.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get" (i32.const 4)) (ref.extern 2)) -;; (assert_return (invoke "get" (i32.const 5)) (ref.extern 2)) -(assert_return (invoke "get" (i32.const 6)) (ref.null extern)) - -;; (assert_return (invoke "fill" (i32.const 4) (ref.extern 3) (i32.const 0))) -;; (assert_return (invoke "get" (i32.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get" (i32.const 4)) (ref.extern 2)) -;; (assert_return (invoke "get" (i32.const 5)) (ref.extern 2)) - -;; (assert_return (invoke "fill" (i32.const 8) (ref.extern 4) (i32.const 2))) -(assert_return (invoke "get" (i32.const 7)) (ref.null extern)) -;; (assert_return (invoke "get" (i32.const 8)) (ref.extern 4)) -;; (assert_return (invoke "get" (i32.const 9)) (ref.extern 4)) - -(assert_return (invoke "fill-abbrev" (i32.const 9) (ref.null extern) (i32.const 1))) -;; (assert_return (invoke "get" (i32.const 8)) (ref.extern 4)) -(assert_return (invoke "get" (i32.const 9)) (ref.null extern)) - -;; (assert_return (invoke "fill" (i32.const 10) (ref.extern 5) (i32.const 0))) -(assert_return (invoke "get" (i32.const 9)) (ref.null extern)) - -;; (assert_trap -;; (invoke "fill" (i32.const 8) (ref.extern 6) (i32.const 3)) -;; "out of bounds table access" -;;) -(assert_return (invoke "get" (i32.const 7)) (ref.null extern)) -;;(assert_return (invoke "get" (i32.const 8)) (ref.extern 4)) -(assert_return (invoke "get" (i32.const 9)) (ref.null extern)) - -(assert_trap - (invoke "fill" (i32.const 11) (ref.null extern) (i32.const 0)) - "out of bounds table access" -) - -(assert_trap - (invoke "fill" (i32.const 11) (ref.null extern) (i32.const 10)) - "out of bounds table access" -) - -;; Same as above but for t64 - -(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) -(assert_return (invoke "get-t64" (i64.const 2)) (ref.null extern)) -(assert_return (invoke "get-t64" (i64.const 3)) (ref.null extern)) -(assert_return (invoke "get-t64" (i64.const 4)) (ref.null extern)) -(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) - -;; (assert_return (invoke "fill-t64" (i64.const 2) (ref.extern 1) (i64.const 3))) -(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) -;; (assert_return (invoke "get-t64" (i64.const 2)) (ref.extern 1)) -;; (assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 1)) -(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) - -;; (assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 2) (i64.const 2))) -;; (assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) -;; (assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) -(assert_return (invoke "get-t64" (i64.const 6)) (ref.null extern)) - -;; (assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 3) (i64.const 0))) -;; (assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) -;; (assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) -;; (assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) - -;; (assert_return (invoke "fill-t64" (i64.const 8) (ref.extern 4) (i64.const 2))) -(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) -;; (assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) -;; (assert_return (invoke "get-t64" (i64.const 9)) (ref.extern 4)) - -(assert_return (invoke "fill-t64" (i64.const 9) (ref.null extern) (i64.const 1))) -;; (assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) -(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) - -;; (assert_return (invoke "fill-t64" (i64.const 10) (ref.extern 5) (i64.const 0))) -(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) - -;; (assert_trap -;; (invoke "fill-t64" (i64.const 8) (ref.extern 6) (i64.const 3)) -;; "out of bounds table access" -;; ) -(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) -;; (assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) -(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) - -(assert_trap - (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 0)) - "out of bounds table access" -) - -(assert_trap - (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 10)) - "out of bounds table access" -) - -;; Type errors - -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-value-length-empty-vs-i32-i32 - (table.fill $t) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-empty-vs-i32 - (table.fill $t (ref.null extern) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-value-empty-vs - (table.fill $t (i32.const 1) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-length-empty-vs-i32 - (table.fill $t (i32.const 1) (ref.null extern)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 externref) - (func $type-index-f32-vs-i32 - (table.fill $t (f32.const 1) (ref.null extern) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 funcref) - (func $type-value-vs-funcref (param $r externref) - (table.fill $t (i32.const 1) (local.get $r) (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 externref) - (func $type-length-f32-vs-i32 - (table.fill $t (i32.const 1) (ref.null extern) (f32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t1 1 externref) - (table $t2 1 funcref) - (func $type-value-externref-vs-funcref-multi (param $r externref) - (table.fill $t2 (i32.const 0) (local.get $r) (i32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t 1 externref) - (func $type-result-empty-vs-num (result i32) - (table.fill $t (i32.const 0) (ref.null extern) (i32.const 1)) - ) - ) - "type mismatch" -) diff --git a/test/spec/table_get.wast b/test/spec/table_get.wast deleted file mode 100644 index cc24ba3ec5c..00000000000 --- a/test/spec/table_get.wast +++ /dev/null @@ -1,94 +0,0 @@ -(module - (table $t2 2 externref) - (table $t3 3 funcref) - (table $t64 i64 3 funcref) - (elem (table $t3) (i32.const 1) func $dummy) - (func $dummy) - - (func (export "init") - ;; (table.set $t2 (i32.const 1) (local.get $r)) - (table.set $t3 (i32.const 2) (table.get $t3 (i32.const 1))) - ) - - (func (export "get-externref") (param $i i32) (result externref) - (table.get (local.get $i)) - ) - (func $f3 (export "get-funcref") (param $i i32) (result funcref) - (table.get $t3 (local.get $i)) - ) - (func $f4 (export "get-funcref-t64") (param $i i64) (result funcref) - (table.get $t64 (local.get $i)) - ) - - (func (export "is_null-funcref") (param $i i32) (result i32) - (ref.is_null (call $f3 (local.get $i))) - ) -) - -;; (invoke "init" (ref.extern 1)) -(invoke "init") - -(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern)) -;; (assert_return (invoke "get-externref" (i32.const 1)) (ref.extern 1)) - -(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func)) -(assert_return (invoke "get-funcref-t64" (i64.const 0)) (ref.null func)) -(assert_return (invoke "is_null-funcref" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "is_null-funcref" (i32.const 2)) (i32.const 0)) - -(assert_trap (invoke "get-externref" (i32.const 2)) "out of bounds table access") -(assert_trap (invoke "get-funcref" (i32.const 3)) "out of bounds table access") -(assert_trap (invoke "get-externref" (i32.const -1)) "out of bounds table access") -(assert_trap (invoke "get-funcref" (i32.const -1)) "out of bounds table access") - - -;; Type errors - -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-empty-vs-i32 (result externref) - (table.get $t) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-f32-vs-i32 (result externref) - (table.get $t (f32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t 10 externref) - (func $type-result-externref-vs-empty - (table.get $t (i32.const 0)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-result-externref-vs-funcref (result funcref) - (table.get $t (i32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t1 1 funcref) - (table $t2 1 externref) - (func $type-result-externref-vs-funcref-multi (result funcref) - (table.get $t2 (i32.const 0)) - ) - ) - "type mismatch" -) diff --git a/test/spec/table_grow.wast b/test/spec/table_grow.wast deleted file mode 100644 index a3a25b071ad..00000000000 --- a/test/spec/table_grow.wast +++ /dev/null @@ -1,174 +0,0 @@ -(module - (table $t 0 externref) - - (func (export "get") (param $i i32) (result externref) (table.get $t (local.get $i))) - (func (export "set") (param $i i32) (param $r externref) (table.set $t (local.get $i) (local.get $r))) - - (func (export "grow") (param $sz i32) (param $init externref) (result i32) - (table.grow $t (local.get $init) (local.get $sz)) - ) - (func (export "size") (result i32) (table.size $t)) -) - -(assert_return (invoke "size") (i32.const 0)) -;; (assert_trap (invoke "set" (i32.const 0) (ref.extern 2)) "out of bounds table access") -(assert_trap (invoke "get" (i32.const 0)) "out of bounds table access") - -(assert_return (invoke "grow" (i32.const 1) (ref.null extern)) (i32.const 0)) -(assert_return (invoke "size") (i32.const 1)) -(assert_return (invoke "get" (i32.const 0)) (ref.null extern)) -;; (assert_return (invoke "set" (i32.const 0) (ref.extern 2))) -;; (assert_return (invoke "get" (i32.const 0)) (ref.extern 2)) -;; (assert_trap (invoke "set" (i32.const 1) (ref.extern 2)) "out of bounds table access") -;; (assert_trap (invoke "get" (i32.const 1)) "out of bounds table access") - -;; (assert_return (invoke "grow" (i32.const 4) (ref.extern 3)) (i32.const 1)) -;; (assert_return (invoke "size") (i32.const 5)) -;; (assert_return (invoke "get" (i32.const 0)) (ref.extern 2)) -;; (assert_return (invoke "set" (i32.const 0) (ref.extern 2))) -;; (assert_return (invoke "get" (i32.const 0)) (ref.extern 2)) -;; (assert_return (invoke "get" (i32.const 1)) (ref.extern 3)) -;; (assert_return (invoke "get" (i32.const 4)) (ref.extern 3)) -;; (assert_return (invoke "set" (i32.const 4) (ref.extern 4))) -;; (assert_return (invoke "get" (i32.const 4)) (ref.extern 4)) -;; (assert_trap (invoke "set" (i32.const 5) (ref.extern 2)) "out of bounds table access") -;; (assert_trap (invoke "get" (i32.const 5)) "out of bounds table access") - - -;; Reject growing to size outside i32 value range -;; TODO: parse error -;; (module -;; (table $t 0x10 funcref) -;; (elem declare func $f) -;; (func $f (export "grow") (result i32) -;; (table.grow $t (ref.func $f) (i32.const 0xffff_fff0)) -;; ) -;; ) - -;; (assert_return (invoke "grow") (i32.const -1)) - - -(module - (table $t 0 externref) - (func (export "grow") (param i32) (result i32) - (table.grow $t (ref.null extern) (local.get 0)) - ) -) - -(assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "grow" (i32.const 2)) (i32.const 1)) -(assert_return (invoke "grow" (i32.const 800)) (i32.const 3)) - - -(module - (table $t 0 10 externref) - (func (export "grow") (param i32) (result i32) - (table.grow $t (ref.null extern) (local.get 0)) - ) -) - -(assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) -(assert_return (invoke "grow" (i32.const 2)) (i32.const 2)) -(assert_return (invoke "grow" (i32.const 6)) (i32.const 4)) -(assert_return (invoke "grow" (i32.const 0)) (i32.const 10)) -(assert_return (invoke "grow" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) - - -(module - (table $t 10 funcref) - (func (export "grow") (param i32) (result i32) - (table.grow $t (ref.null func) (local.get 0)) - ) - (elem declare func 1) - (func (export "check-table-null") (param i32 i32) (result funcref) - (local funcref) - (local.set 2 (ref.func 1)) - (block - (loop - (local.set 2 (table.get $t (local.get 0))) - (br_if 1 (i32.eqz (ref.is_null (local.get 2)))) - (br_if 1 (i32.ge_u (local.get 0) (local.get 1))) - (local.set 0 (i32.add (local.get 0) (i32.const 1))) - (br_if 0 (i32.le_u (local.get 0) (local.get 1))) - ) - ) - (local.get 2) - ) -) - -(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 9)) (ref.null func)) -(assert_return (invoke "grow" (i32.const 10)) (i32.const 10)) -(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 19)) (ref.null func)) - - -;; Type errors - -(assert_invalid - (module - (table $t 0 externref) - (func $type-init-size-empty-vs-i32-externref (result i32) - (table.grow $t) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 externref) - (func $type-size-empty-vs-i32 (result i32) - (table.grow $t (ref.null extern)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 externref) - (func $type-init-empty-vs-externref (result i32) - (table.grow $t (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 externref) - (func $type-size-f32-vs-i32 (result i32) - (table.grow $t (ref.null extern) (f32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 0 funcref) - (func $type-init-externref-vs-funcref (param $r externref) (result i32) - (table.grow $t (local.get $r) (i32.const 1)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t 1 externref) - (func $type-result-i32-vs-empty - (table.grow $t (ref.null extern) (i32.const 0)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 1 externref) - (func $type-result-i32-vs-f32 (result f32) - (table.grow $t (ref.null extern) (i32.const 0)) - ) - ) - "type mismatch" -) diff --git a/test/spec/table_set.wast b/test/spec/table_set.wast deleted file mode 100644 index 7ec3fc6c24c..00000000000 --- a/test/spec/table_set.wast +++ /dev/null @@ -1,129 +0,0 @@ -(module - (table $t2 1 externref) - (table $t3 2 funcref) - (table $t64 i64 2 funcref) - (elem (table $t3) (i32.const 1) func $dummy) - (func $dummy) - - (func (export "get-externref") (param $i i32) (result externref) - (table.get $t2 (local.get $i)) - ) - (func $f3 (export "get-funcref") (param $i i32) (result funcref) - (table.get $t3 (local.get $i)) - ) - (func $f4 (export "get-funcref-t64") (param $i i64) (result funcref) - (table.get $t64 (local.get $i)) - ) - - (func (export "set-externref") (param $i i32) (param $r externref) - (table.set (local.get $i) (local.get $r)) - ) - (func (export "set-funcref") (param $i i32) (param $r funcref) - (table.set $t3 (local.get $i) (local.get $r)) - ) - (func (export "set-funcref-from") (param $i i32) (param $j i32) - (table.set $t3 (local.get $i) (table.get $t3 (local.get $j))) - ) - (func (export "set-funcref-t64") (param $i i64) (param $r funcref) - (table.set $t64 (local.get $i) (local.get $r)) - ) - - (func (export "is_null-funcref") (param $i i32) (result i32) - (ref.is_null (call $f3 (local.get $i))) - ) -) - -(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern)) -;; (assert_return (invoke "set-externref" (i32.const 0) (ref.extern 1))) -;; (assert_return (invoke "get-externref" (i32.const 0)) (ref.extern 1)) -(assert_return (invoke "set-externref" (i32.const 0) (ref.null extern))) -(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern)) - -(assert_return (invoke "set-funcref-t64" (i64.const 0) (ref.null func))) -(assert_return (invoke "get-funcref-t64" (i64.const 0)) (ref.null func)) - -(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func)) -(assert_return (invoke "set-funcref-from" (i32.const 0) (i32.const 1))) -(assert_return (invoke "is_null-funcref" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "set-funcref" (i32.const 0) (ref.null func))) -(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func)) - -(assert_trap (invoke "set-externref" (i32.const 2) (ref.null extern)) "out of bounds table access") -(assert_trap (invoke "set-funcref" (i32.const 3) (ref.null func)) "out of bounds table access") -(assert_trap (invoke "set-externref" (i32.const -1) (ref.null extern)) "out of bounds table access") -(assert_trap (invoke "set-funcref" (i32.const -1) (ref.null func)) "out of bounds table access") - -;; (assert_trap (invoke "set-externref" (i32.const 2) (ref.extern 0)) "out of bounds table access") -(assert_trap (invoke "set-funcref-from" (i32.const 3) (i32.const 1)) "out of bounds table access") -;; (assert_trap (invoke "set-externref" (i32.const -1) (ref.extern 0)) "out of bounds table access") -(assert_trap (invoke "set-funcref-from" (i32.const -1) (i32.const 1)) "out of bounds table access") - - -;; Type errors - -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-value-empty-vs-i32-externref - (table.set $t) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-index-empty-vs-i32 - (table.set $t (ref.null extern)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-value-empty-vs-externref - (table.set $t (i32.const 1)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 externref) - (func $type-size-f32-vs-i32 - (table.set $t (f32.const 1) (ref.null extern)) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (table $t 10 funcref) - (func $type-value-externref-vs-funcref (param $r externref) - (table.set $t (i32.const 1) (local.get $r)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t1 1 externref) - (table $t2 1 funcref) - (func $type-value-externref-vs-funcref-multi (param $r externref) - (table.set $t2 (i32.const 0) (local.get $r)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (table $t 10 externref) - (func $type-result-empty-vs-num (result i32) - (table.set $t (i32.const 0) (ref.null extern)) - ) - ) - "type mismatch" -) From 21ddb853559bde490b4f02db576d4b8cd48d3106 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 21 Aug 2024 14:58:57 -0700 Subject: [PATCH 535/553] [NFC] hash constant string as void* (#6863) possible-contents.h hashes the location for caught exnrefs by hashing an arbitrary string, "caught-exnref-location". It previously used `std::hash` for this, but some standard library implementations report an error when this template instantiation is used because hashing the location of a string is almost never correct. In this case it is fine, so switch to using `std::hash`. --- src/ir/possible-contents.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h index 7b88483cf8c..945d59d2623 100644 --- a/src/ir/possible-contents.h +++ b/src/ir/possible-contents.h @@ -620,7 +620,7 @@ template<> struct hash { template<> struct hash { size_t operator()(const wasm::CaughtExnRefLocation& loc) const { - return std::hash()("caught-exnref-location"); + return std::hash()("caught-exnref-location"); } }; From 99db0d9c7c33bcea7b7730bb5684f41176146f83 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 21 Aug 2024 15:03:46 -0700 Subject: [PATCH 536/553] [FP16] Implement arithmetic operations. (#6855) Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md --- scripts/gen-s-parser.py | 8 ++ src/gen-s-parser.inc | 73 +++++++++++- src/ir/child-typer.h | 8 ++ src/ir/cost.h | 16 +++ src/literal.h | 9 ++ src/passes/Print.cpp | 25 +++++ src/tools/fuzzing/fuzzing.cpp | 6 + src/wasm-binary.h | 8 ++ src/wasm-interpreter.h | 17 +++ src/wasm.h | 8 ++ src/wasm/literal.cpp | 51 ++++++++- src/wasm/wasm-binary.cpp | 32 ++++++ src/wasm/wasm-stack.cpp | 24 ++++ src/wasm/wasm-validator.cpp | 8 ++ test/lit/basic/f16.wast | 201 +++++++++++++++++++++++++++++++++- test/spec/f16.wast | 66 +++++++++++ 16 files changed, 549 insertions(+), 11 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 86826ad795f..39d621f4861 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -452,6 +452,14 @@ ("i64x2.extmul_high_i32x4_s", "makeBinary(BinaryOp::ExtMulHighSVecI64x2)"), ("i64x2.extmul_low_i32x4_u", "makeBinary(BinaryOp::ExtMulLowUVecI64x2)"), ("i64x2.extmul_high_i32x4_u", "makeBinary(BinaryOp::ExtMulHighUVecI64x2)"), + ("f16x8.add", "makeBinary(BinaryOp::AddVecF16x8)"), + ("f16x8.sub", "makeBinary(BinaryOp::SubVecF16x8)"), + ("f16x8.mul", "makeBinary(BinaryOp::MulVecF16x8)"), + ("f16x8.div", "makeBinary(BinaryOp::DivVecF16x8)"), + ("f16x8.min", "makeBinary(BinaryOp::MinVecF16x8)"), + ("f16x8.max", "makeBinary(BinaryOp::MaxVecF16x8)"), + ("f16x8.pmin", "makeBinary(BinaryOp::PMinVecF16x8)"), + ("f16x8.pmax", "makeBinary(BinaryOp::PMaxVecF16x8)"), ("f32x4.abs", "makeUnary(UnaryOp::AbsVecF32x4)"), ("f32x4.neg", "makeUnary(UnaryOp::NegVecF32x4)"), ("f32x4.sqrt", "makeUnary(UnaryOp::SqrtVecF32x4)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 2fa658e65f3..f4afd1f1b6f 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -309,6 +309,18 @@ switch (buf[0]) { switch (buf[1]) { case '1': { switch (buf[6]) { + case 'a': + if (op == "f16x8.add"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'd': + if (op == "f16x8.div"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::DivVecF16x8)); + return Ok{}; + } + goto parse_error; case 'e': { switch (buf[7]) { case 'q': @@ -360,24 +372,75 @@ switch (buf[0]) { default: goto parse_error; } } + case 'm': { + switch (buf[7]) { + case 'a': + if (op == "f16x8.max"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MaxVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'i': + if (op == "f16x8.min"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MinVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'u': + if (op == "f16x8.mul"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MulVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } case 'n': if (op == "f16x8.ne"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::NeVecF16x8)); return Ok{}; } goto parse_error; + case 'p': { + switch (buf[8]) { + case 'a': + if (op == "f16x8.pmax"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::PMaxVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'i': + if (op == "f16x8.pmin"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::PMinVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } case 'r': if (op == "f16x8.replace_lane"sv) { CHECK_ERR(makeSIMDReplace(ctx, pos, annotations, SIMDReplaceOp::ReplaceLaneVecF16x8, 8)); return Ok{}; } goto parse_error; - case 's': - if (op == "f16x8.splat"sv) { - CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SplatVecF16x8)); - return Ok{}; + case 's': { + switch (buf[7]) { + case 'p': + if (op == "f16x8.splat"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SplatVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'u': + if (op == "f16x8.sub"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::SubVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } default: goto parse_error; } } diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index 725bc842e27..fe65b209bea 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -627,6 +627,14 @@ template struct ChildTyper : OverriddenVisitor { case ExtMulHighSVecI64x2: case ExtMulLowUVecI64x2: case ExtMulHighUVecI64x2: + case AddVecF16x8: + case SubVecF16x8: + case MulVecF16x8: + case DivVecF16x8: + case MinVecF16x8: + case MaxVecF16x8: + case PMinVecF16x8: + case PMaxVecF16x8: case AddVecF32x4: case SubVecF32x4: case MulVecF32x4: diff --git a/src/ir/cost.h b/src/ir/cost.h index 11370acabb5..0b2b6315b09 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -475,6 +475,22 @@ struct CostAnalyzer : public OverriddenVisitor { case ExtMulHighSVecI64x2: case ExtMulLowUVecI64x2: case ExtMulHighUVecI64x2: + case AddVecF16x8: + case SubVecF16x8: + ret = 1; + break; + case MulVecF16x8: + ret = 2; + break; + case DivVecF16x8: + ret = 3; + break; + case MinVecF16x8: + case MaxVecF16x8: + case PMinVecF16x8: + case PMaxVecF16x8: + ret = 1; + break; case AddVecF32x4: case SubVecF32x4: ret = 1; diff --git a/src/literal.h b/src/literal.h index dd6247d001c..882a990275b 100644 --- a/src/literal.h +++ b/src/literal.h @@ -382,6 +382,7 @@ class Literal { Literal convertUIToF32() const; Literal convertSIToF64() const; Literal convertUIToF64() const; + Literal convertF32ToF16() const; Literal truncSatToSI32() const; Literal truncSatToSI64() const; @@ -618,6 +619,14 @@ class Literal { Literal extMulHighSI64x2(const Literal& other) const; Literal extMulLowUI64x2(const Literal& other) const; Literal extMulHighUI64x2(const Literal& other) const; + Literal addF16x8(const Literal& other) const; + Literal subF16x8(const Literal& other) const; + Literal mulF16x8(const Literal& other) const; + Literal divF16x8(const Literal& other) const; + Literal minF16x8(const Literal& other) const; + Literal maxF16x8(const Literal& other) const; + Literal pminF16x8(const Literal& other) const; + Literal pmaxF16x8(const Literal& other) const; Literal absF32x4() const; Literal negF32x4() const; Literal sqrtF32x4() const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 6350347c46d..4986982c731 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1901,6 +1901,31 @@ struct PrintExpressionContents o << "i64x2.extmul_high_i32x4_u"; break; + case AddVecF16x8: + o << "f16x8.add"; + break; + case SubVecF16x8: + o << "f16x8.sub"; + break; + case MulVecF16x8: + o << "f16x8.mul"; + break; + case DivVecF16x8: + o << "f16x8.div"; + break; + case MinVecF16x8: + o << "f16x8.min"; + break; + case MaxVecF16x8: + o << "f16x8.max"; + break; + case PMinVecF16x8: + o << "f16x8.pmin"; + break; + case PMaxVecF16x8: + o << "f16x8.pmax"; + break; + case AddVecF32x4: o << "f32x4.add"; break; diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index bebf4f9892c..a143d2ff2c3 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -3358,6 +3358,12 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) { DotSVecI16x8ToVecI32x4, AddVecI64x2, SubVecI64x2, + AddVecF16x8, + SubVecF16x8, + MulVecF16x8, + DivVecF16x8, + MinVecF16x8, + MaxVecF16x8, AddVecF32x4, SubVecF32x4, MulVecF32x4, diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 8c199022487..1fbe7535c5e 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1064,6 +1064,14 @@ enum ASTNodes { F16x8Gt = 0x13a, F16x8Le = 0x13b, F16x8Ge = 0x13c, + F16x8Add = 0x13d, + F16x8Sub = 0x13e, + F16x8Mul = 0x13f, + F16x8Div = 0x140, + F16x8Min = 0x141, + F16x8Max = 0xe142, + F16x8Pmin = 0x143, + F16x8Pmax = 0x144, // bulk memory opcodes diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index cbd2b31d68e..81b755f9f05 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1014,6 +1014,23 @@ class ExpressionRunner : public OverriddenVisitor { case ExtMulHighUVecI64x2: return left.extMulHighUI64x2(right); + case AddVecF16x8: + return left.addF16x8(right); + case SubVecF16x8: + return left.subF16x8(right); + case MulVecF16x8: + return left.mulF16x8(right); + case DivVecF16x8: + return left.divF16x8(right); + case MinVecF16x8: + return left.minF16x8(right); + case MaxVecF16x8: + return left.maxF16x8(right); + case PMinVecF16x8: + return left.pminF16x8(right); + case PMaxVecF16x8: + return left.pmaxF16x8(right); + case AddVecF32x4: return left.addF32x4(right); case SubVecF32x4: diff --git a/src/wasm.h b/src/wasm.h index 9d43a4f9fcc..6f82196b709 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -452,6 +452,14 @@ enum BinaryOp { ExtMulHighSVecI64x2, ExtMulLowUVecI64x2, ExtMulHighUVecI64x2, + AddVecF16x8, + SubVecF16x8, + MulVecF16x8, + DivVecF16x8, + MinVecF16x8, + MaxVecF16x8, + PMinVecF16x8, + PMaxVecF16x8, AddVecF32x4, SubVecF32x4, MulVecF32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index d60e2f8a9a0..65c2b4e62af 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -856,6 +856,10 @@ Literal Literal::convertUIToF64() const { WASM_UNREACHABLE("invalid type"); } +Literal Literal::convertF32ToF16() const { + return Literal(fp16_ieee_from_fp32_value(getf32())); +} + template struct AsInt { using type = void; }; template<> struct AsInt { using type = int32_t; }; template<> struct AsInt { using type = int64_t; }; @@ -1791,8 +1795,7 @@ Literal Literal::splatI16x8() const { return splat(*this); } Literal Literal::splatI32x4() const { return splat(*this); } Literal Literal::splatI64x2() const { return splat(*this); } Literal Literal::splatF16x8() const { - uint16_t f16 = fp16_ieee_from_fp32_value(getf32()); - return splat(Literal(f16)); + return splat(convertF32ToF16()); } Literal Literal::splatF32x4() const { return splat(*this); } Literal Literal::splatF64x2() const { return splat(*this); } @@ -1848,7 +1851,7 @@ Literal Literal::replaceLaneI64x2(const Literal& other, uint8_t index) const { } Literal Literal::replaceLaneF16x8(const Literal& other, uint8_t index) const { return replace<8, &Literal::getLanesF16x8>( - *this, Literal(fp16_ieee_from_fp32_value(other.getf32())), index); + *this, other.convertF32ToF16(), index); } Literal Literal::replaceLaneF32x4(const Literal& other, uint8_t index) const { return replace<4, &Literal::getLanesF32x4>(*this, other, index); @@ -2286,14 +2289,20 @@ Literal Literal::geF64x2(const Literal& other) const { other); } +static Literal passThrough(const Literal& literal) { return literal; } +static Literal toFP16(const Literal& literal) { + return literal.convertF32ToF16(); +} + template (Literal::*IntoLanes)() const, - Literal (Literal::*BinaryOp)(const Literal&) const> + Literal (Literal::*BinaryOp)(const Literal&) const, + Literal (*Convert)(const Literal&) = passThrough> static Literal binary(const Literal& val, const Literal& other) { LaneArray lanes = (val.*IntoLanes)(); LaneArray other_lanes = (other.*IntoLanes)(); for (size_t i = 0; i < Lanes; ++i) { - lanes[i] = (lanes[i].*BinaryOp)(other_lanes[i]); + lanes[i] = Convert((lanes[i].*BinaryOp)(other_lanes[i])); } return Literal(lanes); } @@ -2418,6 +2427,38 @@ Literal Literal::subI64x2(const Literal& other) const { Literal Literal::mulI64x2(const Literal& other) const { return binary<2, &Literal::getLanesI64x2, &Literal::mul>(*this, other); } +Literal Literal::addF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::add, &toFP16>(*this, + other); +} +Literal Literal::subF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::sub, &toFP16>(*this, + other); +} +Literal Literal::mulF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::mul, &toFP16>(*this, + other); +} +Literal Literal::divF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::div, &toFP16>(*this, + other); +} +Literal Literal::minF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::min, &toFP16>(*this, + other); +} +Literal Literal::maxF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::max, &toFP16>(*this, + other); +} +Literal Literal::pminF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::pmin, &toFP16>(*this, + other); +} +Literal Literal::pmaxF16x8(const Literal& other) const { + return binary<8, &Literal::getLanesF16x8, &Literal::pmax, &toFP16>(*this, + other); +} Literal Literal::addF32x4(const Literal& other) const { return binary<4, &Literal::getLanesF32x4, &Literal::add>(*this, other); } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 865ca39cac2..e84639801e3 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6174,6 +6174,38 @@ bool WasmBinaryReader::maybeVisitSIMDBinary(Expression*& out, uint32_t code) { curr = allocator.alloc(); curr->op = ExtMulHighUVecI64x2; break; + case BinaryConsts::F16x8Add: + curr = allocator.alloc(); + curr->op = AddVecF16x8; + break; + case BinaryConsts::F16x8Sub: + curr = allocator.alloc(); + curr->op = SubVecF16x8; + break; + case BinaryConsts::F16x8Mul: + curr = allocator.alloc(); + curr->op = MulVecF16x8; + break; + case BinaryConsts::F16x8Div: + curr = allocator.alloc(); + curr->op = DivVecF16x8; + break; + case BinaryConsts::F16x8Min: + curr = allocator.alloc(); + curr->op = MinVecF16x8; + break; + case BinaryConsts::F16x8Max: + curr = allocator.alloc(); + curr->op = MaxVecF16x8; + break; + case BinaryConsts::F16x8Pmin: + curr = allocator.alloc(); + curr->op = PMinVecF16x8; + break; + case BinaryConsts::F16x8Pmax: + curr = allocator.alloc(); + curr->op = PMaxVecF16x8; + break; case BinaryConsts::F32x4Add: curr = allocator.alloc(); curr->op = AddVecF32x4; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 1c2c2c42bac..b7bfea61718 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1873,6 +1873,30 @@ void BinaryInstWriter::visitBinary(Binary* curr) { << U32LEB(BinaryConsts::I64x2ExtmulHighI32x4U); break; + case AddVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Add); + break; + case SubVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Sub); + break; + case MulVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Mul); + break; + case DivVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Div); + break; + case MinVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Min); + break; + case MaxVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Max); + break; + case PMinVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Pmin); + break; + case PMaxVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Pmax); + break; case AddVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Add); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 0bdc186584a..24f5379fbd0 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1813,6 +1813,14 @@ void FunctionValidator::visitBinary(Binary* curr) { case ExtMulHighSVecI64x2: case ExtMulLowUVecI64x2: case ExtMulHighUVecI64x2: + case AddVecF16x8: + case SubVecF16x8: + case MulVecF16x8: + case DivVecF16x8: + case MinVecF16x8: + case MaxVecF16x8: + case PMinVecF16x8: + case PMaxVecF16x8: case AddVecF32x4: case SubVecF32x4: case MulVecF32x4: diff --git a/test/lit/basic/f16.wast b/test/lit/basic/f16.wast index 21c9fc100c5..df3c0ef2d89 100644 --- a/test/lit/basic/f16.wast +++ b/test/lit/basic/f16.wast @@ -233,7 +233,150 @@ (local.get $1) ) ) - + ;; CHECK-TEXT: (func $f16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.add + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.add (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.add + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.add (param $0 v128) (param $1 v128) (result v128) + (f16x8.add + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.sub + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.sub (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.sub + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.sub (param $0 v128) (param $1 v128) (result v128) + (f16x8.sub + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.mul + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.mul (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.mul + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.mul (param $0 v128) (param $1 v128) (result v128) + (f16x8.mul + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.div + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.div (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.div + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.div (param $0 v128) (param $1 v128) (result v128) + (f16x8.div + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.min + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.min (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.min + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.min (param $0 v128) (param $1 v128) (result v128) + (f16x8.min + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.max + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.max (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.max + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.max (param $0 v128) (param $1 v128) (result v128) + (f16x8.max + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.pmin + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.pmin (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.pmin + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.pmin (param $0 v128) (param $1 v128) (result v128) + (f16x8.pmin + (local.get $0) + (local.get $1) + ) + ) + ;; CHECK-TEXT: (func $f16x8.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.pmax + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: (local.get $1) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.pmax (type $0) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.pmax + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: (local.get $1) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.pmax (param $0 v128) (param $1 v128) (result v128) + (f16x8.pmax + (local.get $0) + (local.get $1) + ) + ) ) ;; CHECK-BIN-NODEBUG: (type $0 (func (param v128 v128) (result v128))) @@ -322,3 +465,59 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $11 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.add +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $12 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.sub +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $13 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.mul +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $14 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.div +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $15 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.min +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $16 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.max +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $17 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.pmin +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $18 (type $0) (param $0 v128) (param $1 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.pmax +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/spec/f16.wast b/test/spec/f16.wast index 360464e153a..70d0043f7be 100644 --- a/test/spec/f16.wast +++ b/test/spec/f16.wast @@ -17,6 +17,14 @@ (func (export "f16x8.gt") (param $0 v128) (param $1 v128) (result v128) (f16x8.gt (local.get $0) (local.get $1))) (func (export "f16x8.le") (param $0 v128) (param $1 v128) (result v128) (f16x8.le (local.get $0) (local.get $1))) (func (export "f16x8.ge") (param $0 v128) (param $1 v128) (result v128) (f16x8.ge (local.get $0) (local.get $1))) + (func (export "f16x8.add") (param $0 v128) (param $1 v128) (result v128) (f16x8.add (local.get $0) (local.get $1))) + (func (export "f16x8.sub") (param $0 v128) (param $1 v128) (result v128) (f16x8.sub (local.get $0) (local.get $1))) + (func (export "f16x8.mul") (param $0 v128) (param $1 v128) (result v128) (f16x8.mul (local.get $0) (local.get $1))) + (func (export "f16x8.div") (param $0 v128) (param $1 v128) (result v128) (f16x8.div (local.get $0) (local.get $1))) + (func (export "f16x8.min") (param $0 v128) (param $1 v128) (result v128) (f16x8.min (local.get $0) (local.get $1))) + (func (export "f16x8.max") (param $0 v128) (param $1 v128) (result v128) (f16x8.max (local.get $0) (local.get $1))) + (func (export "f16x8.pmin") (param $0 v128) (param $1 v128) (result v128) (f16x8.pmin (local.get $0) (local.get $1))) + (func (export "f16x8.pmax") (param $0 v128) (param $1 v128) (result v128) (f16x8.pmax (local.get $0) (local.get $1))) ) (assert_return (invoke "f32.load_f16") (f32.const 42.0)) @@ -81,3 +89,61 @@ ) (v128.const i16x8 -1 0 -1 0 -1 0 -1 0) ) + +;; arithmetic operations +(assert_return (invoke "f16x8.add" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan inf 3 -1 0 1 2 + (v128.const i16x8 0x7e00 0x7e00 0x7c00 0x4200 0xbc00 0 0x3c00 0x4000)) +(assert_return (invoke "f16x8.sub" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan nan 0 -1 -2 1 0 + (v128.const i16x8 0x7e00 0x7e00 0x7e00 0 0xbc00 0xc000 0x3c00 0)) +(assert_return (invoke "f16x8.mul" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan inf 2.25 0 -1 0 1 + (v128.const i16x8 0x7e00 0x7e00 0x7c00 0x4080 0x8000 0xbc00 0 0x3c00)) +(assert_return (invoke "f16x8.div" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan nan 1 -inf -1 inf 1 + (v128.const i16x8 0x7e00 0x7e00 0x7e00 0x3c00 0xfc00 0xbc00 0x7c00 0x3c00)) +(assert_return (invoke "f16x8.min" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan inf 1.5 -1 -1 0 1 + (v128.const i16x8 0x7e00 0x7e00 0x7c00 0x3e00 0xbc00 0xbc00 0 0x3c00)) +(assert_return (invoke "f16x8.max" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan nan inf 1.5 0 1 1 1 + (v128.const i16x8 0x7e00 0x7e00 0x7c00 0x3e00 0 0x3c00 0x3c00 0x3c00)) +(assert_return (invoke "f16x8.pmin" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan -nan inf 1.5 -1 -1 0 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0 0x3c00)) +(assert_return (invoke "f16x8.pmax" + ;; nan -nan inf 1.5 -1 -1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0xbc00 0xbc00 0x3c00 0x3c00) + ;; 42 -nan inf 1.5 0 1 0 1 + (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) + ;; nan -nan inf 1.5 0 1 1 1 + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0 0x3c00 0x3c00 0x3c00)) From 692e55c14bd3055b1aae49681bb8e62c757c678d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 21 Aug 2024 15:05:22 -0700 Subject: [PATCH 537/553] Add a string lowering mode disallowing non-UTF-8 strings (#6861) The best way to lower strings is via the "magic imports" API that uses the names of imported string globals as their values. This approach only works for valid UTF-8 strings, though. The existing string-lowering-magic-imports pass falls back to putting non-UTF-8 strings in a JSON custom section, but this requires the runtime to support that custom section for correctness. To help catch errors early when runtimes do not support the strings custom section, add a new pass that uses magic imports and raises an error if there are any invalid strings. --- src/passes/StringLowering.cpp | 21 +++++++++++++++++++-- src/passes/pass.cpp | 4 ++++ src/passes/passes.h | 1 + test/lit/help/wasm-metadce.test | 5 +++++ test/lit/help/wasm-opt.test | 5 +++++ test/lit/help/wasm2js.test | 5 +++++ test/lit/passes/string-lowering.wast | 7 +++++++ 7 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index fa5c1c9a8ac..92e3268dc22 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -194,8 +194,16 @@ struct StringLowering : public StringGathering { // instead of emitting them into the JSON custom section. bool useMagicImports; - StringLowering(bool useMagicImports = false) - : useMagicImports(useMagicImports) {} + // Whether to throw a fatal error on non-UTF8 strings that would not be able + // to use the "magic import" mechanism. Only usable in conjunction with magic + // imports. + bool assertUTF8; + + StringLowering(bool useMagicImports = false, bool assertUTF8 = false) + : useMagicImports(useMagicImports), assertUTF8(assertUTF8) { + // If we are asserting valid UTF-8, we must be using magic imports. + assert(!assertUTF8 || useMagicImports); + } void run(Module* module) override { if (!module->features.has(FeatureSet::Strings)) { @@ -238,6 +246,12 @@ struct StringLowering : public StringGathering { global->module = "'"; global->base = Name(utf8.str()); } else { + if (assertUTF8) { + std::stringstream escaped; + String::printEscaped(escaped, utf8.str()); + Fatal() << "Cannot lower non-UTF-16 string " << escaped.str() + << '\n'; + } global->module = "string.const"; global->base = std::to_string(jsonImportIndex); if (first) { @@ -534,5 +548,8 @@ struct StringLowering : public StringGathering { Pass* createStringGatheringPass() { return new StringGathering(); } Pass* createStringLoweringPass() { return new StringLowering(); } Pass* createStringLoweringMagicImportPass() { return new StringLowering(true); } +Pass* createStringLoweringMagicImportAssertPass() { + return new StringLowering(true, true); +} } // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ccfc7b728d3..35d2f677998 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -503,6 +503,10 @@ void PassRegistry::registerPasses() { "string-lowering-magic-imports", "same as string-lowering, but encodes well-formed strings as magic imports", createStringLoweringMagicImportPass); + registerPass("string-lowering-magic-imports-assert", + "same as string-lowering-magic-imports, but raise a fatal error " + "if there are invalid strings", + createStringLoweringMagicImportAssertPass); registerPass( "strip", "deprecated; same as strip-debug", createStripDebugPass); registerPass("stack-check", diff --git a/src/passes/passes.h b/src/passes/passes.h index 9fcb5f95fb2..a95365676a5 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -158,6 +158,7 @@ Pass* createStackCheckPass(); Pass* createStringGatheringPass(); Pass* createStringLoweringPass(); Pass* createStringLoweringMagicImportPass(); +Pass* createStringLoweringMagicImportAssertPass(); Pass* createStripDebugPass(); Pass* createStripDWARFPass(); Pass* createStripProducersPass(); diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index c40f2e22be6..e25a0214d10 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -478,6 +478,11 @@ ;; CHECK-NEXT: encodes well-formed strings as ;; CHECK-NEXT: magic imports ;; CHECK-NEXT: +;; CHECK-NEXT: --string-lowering-magic-imports-assert same as +;; CHECK-NEXT: string-lowering-magic-imports, +;; CHECK-NEXT: but raise a fatal error if there +;; CHECK-NEXT: are invalid strings +;; CHECK-NEXT: ;; CHECK-NEXT: --strip deprecated; same as strip-debug ;; CHECK-NEXT: ;; CHECK-NEXT: --strip-debug strip debug info (including the diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index a1df2640a6b..3a577099b2e 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -487,6 +487,11 @@ ;; CHECK-NEXT: encodes well-formed strings as ;; CHECK-NEXT: magic imports ;; CHECK-NEXT: +;; CHECK-NEXT: --string-lowering-magic-imports-assert same as +;; CHECK-NEXT: string-lowering-magic-imports, +;; CHECK-NEXT: but raise a fatal error if there +;; CHECK-NEXT: are invalid strings +;; CHECK-NEXT: ;; CHECK-NEXT: --strip deprecated; same as strip-debug ;; CHECK-NEXT: ;; CHECK-NEXT: --strip-debug strip debug info (including the diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index beefdbbd718..3c0a17e7a70 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -441,6 +441,11 @@ ;; CHECK-NEXT: encodes well-formed strings as ;; CHECK-NEXT: magic imports ;; CHECK-NEXT: +;; CHECK-NEXT: --string-lowering-magic-imports-assert same as +;; CHECK-NEXT: string-lowering-magic-imports, +;; CHECK-NEXT: but raise a fatal error if there +;; CHECK-NEXT: are invalid strings +;; CHECK-NEXT: ;; CHECK-NEXT: --strip deprecated; same as strip-debug ;; CHECK-NEXT: ;; CHECK-NEXT: --strip-debug strip debug info (including the diff --git a/test/lit/passes/string-lowering.wast b/test/lit/passes/string-lowering.wast index de684889adf..0182082f4e5 100644 --- a/test/lit/passes/string-lowering.wast +++ b/test/lit/passes/string-lowering.wast @@ -35,9 +35,16 @@ ;; RUN: wasm-opt %s --string-lowering-magic-imports -all -S -o - \ ;; RUN: | filecheck %s --check-prefix=MAGIC ;; +;; If we use magic imports with asserts, we should get an error. +;; +;; RUN: not wasm-opt %s --string-lowering-magic-imports-assert -all -S -o - \ +;; RUN: 2>&1 | filecheck %s --check-prefix=ASSERT +;; ;; CHECK: custom section "string.consts", size 136, contents: "[\"bar\",\"foo\",\"needs\\tescaping\\u0000.'#%\\\"- .\\r\\n\\\\08\\f\\n\\r\\t.\\ua66e\",\"unpaired high surrogate \\ud800 \",\"unpaired low surrogate \\udf48 \"]" ;; ;; MAGIC: custom section "string.consts", size 68, contents: "[\"unpaired high surrogate \\ud800 \",\"unpaired low surrogate \\udf48 \"]" +;; +;; ASSERT: Fatal: Cannot lower non-UTF-16 string "unpaired high surrogate \ef\bf\bd " ;; The custom section should parse OK using JSON.parse from node. ;; (Note we run --remove-unused-module-elements to remove externref-using From 60bd610acaa91cab538497342eb06e3b50d2fac9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 21 Aug 2024 16:12:42 -0700 Subject: [PATCH 538/553] [NFC] Avoid quadratic time in StackIROptimizer::removeUnneededBlocks() (#6859) This is in quite ancient code, so it's a long-standing issue, but it got worse when we enabled StackIR in more situations (#6568), which made it more noticeable, I think. For example, testing on test_biggerswitch in Emscripten, the LLVM part is pretty slow too so the Binaryen slowdown didn't stand out hugely, but just doing wasm-opt --optimize-level=2 input.wasm -o output.wasm (that is, do no work, but set the optimize level to 2 so that StackIR opts are run) used to take 28 seconds (!). With this PR that goes down to less than 1. --- src/wasm/wasm-stack-opts.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/wasm/wasm-stack-opts.cpp b/src/wasm/wasm-stack-opts.cpp index 5e18cf26f4c..cf4c094b534 100644 --- a/src/wasm/wasm-stack-opts.cpp +++ b/src/wasm/wasm-stack-opts.cpp @@ -18,6 +18,7 @@ // Operations on Stack IR. // +#include "ir/branch-utils.h" #include "ir/iteration.h" #include "ir/local-graph.h" #include "pass.h" @@ -269,17 +270,26 @@ void StackIROptimizer::local2Stack() { } } -// There may be unnecessary blocks we can remove: blocks -// without branches to them are always ok to remove. -// TODO: a branch to a block in an if body can become -// a branch to that if body +// There may be unnecessary blocks we can remove: blocks without arriving +// branches are always ok to remove. +// TODO: A branch to a block in an if body can become a branch to that if body. void StackIROptimizer::removeUnneededBlocks() { + // First, find all branch targets. + std::unordered_set targets; + for (auto*& inst : insts) { + if (inst) { + BranchUtils::operateOnScopeNameUses( + inst->origin, [&](Name& name) { targets.insert(name); }); + } + } + + // Remove untargeted blocks. for (auto*& inst : insts) { if (!inst) { continue; } if (auto* block = inst->origin->dynCast()) { - if (!BranchUtils::BranchSeeker::has(block, block->name)) { + if (!block->name.is() || !targets.count(block->name)) { // TODO optimize, maybe run remove-unused-names inst = nullptr; } From 2d99e10c03e619b01688268319c1cd43f7539e33 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 21 Aug 2024 16:13:21 -0700 Subject: [PATCH 539/553] [NFC] Avoid quadratic time when precomputing blocks (#6862) When precomputing fails on a child block of a parent block, there is no point to precompute the parent, as that will fail as well. This makes --precompute on Emscripten's test_biggerswitch go from 1.44 seconds to 0.02 seconds (not a typo, that is 72x faster). The absolute number is not that big, but we do run this pass more than once, so it saves a noticeable chunk of time. --- src/passes/Precompute.cpp | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index c60136ec791..6e0d7535f98 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -363,6 +363,73 @@ struct Precompute } } + void visitBlock(Block* curr) { + // When block precomputation fails, it can lead to quadratic slowness due to + // the "tower of blocks" pattern used to implement switches: + // + // (block + // (block + // ... + // (block + // (br_table .. + // + // If we try to precompute each block here, and fail on each, then we end up + // doing quadratic work. This is also wasted work as once a nested block + // fails to precompute there is not really a chance to succeed on the + // parent. If we do *not* fail to precompute, however, then we do want to + // precompute such nested blocks, e.g.: + // + // (block $out + // (block + // (br $out) + // ) + // ) + // + // Here we *can* precompute the inner block, so when we get to the outer one + // we see this: + // + // (block $out + // (br $out) + // ) + // + // And that precomputes to nothing. Therefore when we see a child of the + // block that is another block (it failed to precompute to something + // simpler) then we leave early here. + // + // Note that in theory we could still precompute here if wasm had + // instructions that allow such things, e.g.: + // + // (block $out + // (block + // (cause side effect1) + // (cause side effect2) + // ) + // (undo those side effects exactly) + // ) + // + // We are forced to invent a side effect that we can precisely undo (unlike, + // say locals - a local.set would persist outside of the block, and even if + // we did another set to the original value, this pass doesn't track values + // that way). Only with that can we make the inner block un-precomputable + // (because there are side effects) but the outer one is (because those + // effects are undone). Note that it is critical that we have two things in + // the block, so that we can't precompute it to one of them (which is what + // we did to the br in the previous example). Note also that this is still + // optimizable using other passes, as merge-blocks will fold the two blocks + // together. + if (!curr->list.empty() && curr->list[0]->is()) { + // The first child is a block, that is, it could not be simplified, so + // this looks like the "tower of blocks" pattern. Avoid quadratic time + // here as explained above. (We could also look at other children of the + // block, but the only real-world pattern identified so far is on the + // first child, so keep things simple here.) + return; + } + + // Otherwise, precompute normally like all other expressions. + visitExpression(curr); + } + // If we failed to precompute a constant, perhaps we can still precompute part // of an expression. Specifically, consider this case: // From 95a280f70ef529c3c506d628648a96f2d267f4c1 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Thu, 22 Aug 2024 11:21:53 -0700 Subject: [PATCH 540/553] [FP16] Add a feature flag for FP16. (#6864) Ensure the "fp16" feature is enabled for FP16 instructions. --- src/tools/fuzzing/fuzzing.cpp | 247 +++++++++--------- src/tools/tool-options.h | 1 + src/wasm-binary.h | 1 + src/wasm-features.h | 7 +- src/wasm/wasm-binary.cpp | 4 + src/wasm/wasm-validator.cpp | 42 ++- src/wasm/wasm.cpp | 1 + test/binaryen.js/kitchen-sink.js.txt | 2 +- test/example/c-api-kitchen-sink.txt | 2 +- test/lit/help/wasm-as.test | 4 + test/lit/help/wasm-ctor-eval.test | 4 + test/lit/help/wasm-dis.test | 4 + test/lit/help/wasm-emscripten-finalize.test | 4 + test/lit/help/wasm-merge.test | 4 + test/lit/help/wasm-metadce.test | 4 + test/lit/help/wasm-opt.test | 4 + test/lit/help/wasm-reduce.test | 4 + test/lit/help/wasm-split.test | 4 + test/lit/help/wasm2js.test | 4 + test/lit/validation/fp16.wast | 11 + ..._roundtrip_print-features_all-features.txt | 1 + test/unit/test_features.py | 1 + 22 files changed, 226 insertions(+), 134 deletions(-) create mode 100644 test/lit/validation/fp16.wast diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index a143d2ff2c3..7a3007e437a 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -3271,116 +3271,119 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) { } case Type::v128: { assert(wasm.features.hasSIMD()); - return buildBinary({pick(EqVecI8x16, - NeVecI8x16, - LtSVecI8x16, - LtUVecI8x16, - GtSVecI8x16, - GtUVecI8x16, - LeSVecI8x16, - LeUVecI8x16, - GeSVecI8x16, - GeUVecI8x16, - EqVecI16x8, - NeVecI16x8, - LtSVecI16x8, - LtUVecI16x8, - GtSVecI16x8, - GtUVecI16x8, - LeSVecI16x8, - LeUVecI16x8, - GeSVecI16x8, - GeUVecI16x8, - EqVecI32x4, - NeVecI32x4, - LtSVecI32x4, - LtUVecI32x4, - GtSVecI32x4, - GtUVecI32x4, - LeSVecI32x4, - LeUVecI32x4, - GeSVecI32x4, - GeUVecI32x4, - EqVecF16x8, - EqVecF16x8, - NeVecF16x8, - LtVecF16x8, - GtVecF16x8, - LeVecF16x8, - GeVecF16x8, - EqVecF32x4, - NeVecF32x4, - LtVecF32x4, - GtVecF32x4, - LeVecF32x4, - GeVecF32x4, - EqVecF64x2, - NeVecF64x2, - LtVecF64x2, - GtVecF64x2, - LeVecF64x2, - GeVecF64x2, - AndVec128, - OrVec128, - XorVec128, - AndNotVec128, - AddVecI8x16, - AddSatSVecI8x16, - AddSatUVecI8x16, - SubVecI8x16, - SubSatSVecI8x16, - SubSatUVecI8x16, - MinSVecI8x16, - MinUVecI8x16, - MaxSVecI8x16, - MaxUVecI8x16, - // TODO: avgr_u - // TODO: q15mulr_sat_s - // TODO: extmul - AddVecI16x8, - AddSatSVecI16x8, - AddSatUVecI16x8, - SubVecI16x8, - SubSatSVecI16x8, - SubSatUVecI16x8, - MulVecI16x8, - MinSVecI16x8, - MinUVecI16x8, - MaxSVecI16x8, - MaxUVecI16x8, - AddVecI32x4, - SubVecI32x4, - MulVecI32x4, - MinSVecI32x4, - MinUVecI32x4, - MaxSVecI32x4, - MaxUVecI32x4, - DotSVecI16x8ToVecI32x4, - AddVecI64x2, - SubVecI64x2, - AddVecF16x8, - SubVecF16x8, - MulVecF16x8, - DivVecF16x8, - MinVecF16x8, - MaxVecF16x8, - AddVecF32x4, - SubVecF32x4, - MulVecF32x4, - DivVecF32x4, - MinVecF32x4, - MaxVecF32x4, - AddVecF64x2, - SubVecF64x2, - MulVecF64x2, - DivVecF64x2, - MinVecF64x2, - MaxVecF64x2, - NarrowSVecI16x8ToVecI8x16, - NarrowUVecI16x8ToVecI8x16, - NarrowSVecI32x4ToVecI16x8, - NarrowUVecI32x4ToVecI16x8, - SwizzleVecI8x16), + return buildBinary({pick(FeatureOptions() + .add(FeatureSet::SIMD, + EqVecI8x16, + NeVecI8x16, + LtSVecI8x16, + LtUVecI8x16, + GtSVecI8x16, + GtUVecI8x16, + LeSVecI8x16, + LeUVecI8x16, + GeSVecI8x16, + GeUVecI8x16, + EqVecI16x8, + NeVecI16x8, + LtSVecI16x8, + LtUVecI16x8, + GtSVecI16x8, + GtUVecI16x8, + LeSVecI16x8, + LeUVecI16x8, + GeSVecI16x8, + GeUVecI16x8, + EqVecI32x4, + NeVecI32x4, + LtSVecI32x4, + LtUVecI32x4, + GtSVecI32x4, + GtUVecI32x4, + LeSVecI32x4, + LeUVecI32x4, + GeSVecI32x4, + GeUVecI32x4, + EqVecF32x4, + NeVecF32x4, + LtVecF32x4, + GtVecF32x4, + LeVecF32x4, + GeVecF32x4, + EqVecF64x2, + NeVecF64x2, + LtVecF64x2, + GtVecF64x2, + LeVecF64x2, + GeVecF64x2, + AndVec128, + OrVec128, + XorVec128, + AndNotVec128, + AddVecI8x16, + AddSatSVecI8x16, + AddSatUVecI8x16, + SubVecI8x16, + SubSatSVecI8x16, + SubSatUVecI8x16, + MinSVecI8x16, + MinUVecI8x16, + MaxSVecI8x16, + MaxUVecI8x16, + // TODO: avgr_u + // TODO: q15mulr_sat_s + // TODO: extmul + AddVecI16x8, + AddSatSVecI16x8, + AddSatUVecI16x8, + SubVecI16x8, + SubSatSVecI16x8, + SubSatUVecI16x8, + MulVecI16x8, + MinSVecI16x8, + MinUVecI16x8, + MaxSVecI16x8, + MaxUVecI16x8, + AddVecI32x4, + SubVecI32x4, + MulVecI32x4, + MinSVecI32x4, + MinUVecI32x4, + MaxSVecI32x4, + MaxUVecI32x4, + DotSVecI16x8ToVecI32x4, + AddVecI64x2, + SubVecI64x2, + AddVecF32x4, + SubVecF32x4, + MulVecF32x4, + DivVecF32x4, + MinVecF32x4, + MaxVecF32x4, + AddVecF64x2, + SubVecF64x2, + MulVecF64x2, + DivVecF64x2, + MinVecF64x2, + MaxVecF64x2, + NarrowSVecI16x8ToVecI8x16, + NarrowUVecI16x8ToVecI8x16, + NarrowSVecI32x4ToVecI16x8, + NarrowUVecI32x4ToVecI16x8, + SwizzleVecI8x16) + .add(FeatureSet::FP16, + EqVecF16x8, + EqVecF16x8, + NeVecF16x8, + LtVecF16x8, + GtVecF16x8, + LeVecF16x8, + GeVecF16x8, + AddVecF16x8, + SubVecF16x8, + MulVecF16x8, + DivVecF16x8, + MinVecF16x8, + MaxVecF16x8)), make(Type::v128), make(Type::v128)}); } @@ -3586,7 +3589,9 @@ Expression* TranslateToFuzzReader::makeSIMDExtract(Type type) { op = ExtractLaneVecI64x2; break; case Type::f32: - op = ExtractLaneVecF32x4; + op = pick(FeatureOptions() + .add(FeatureSet::SIMD, ExtractLaneVecF32x4) + .add(FeatureSet::FP16, ExtractLaneVecF16x8)); break; case Type::f64: op = ExtractLaneVecF64x2; @@ -3621,12 +3626,16 @@ Expression* TranslateToFuzzReader::makeSIMDExtract(Type type) { } Expression* TranslateToFuzzReader::makeSIMDReplace() { - SIMDReplaceOp op = pick(ReplaceLaneVecI8x16, - ReplaceLaneVecI16x8, - ReplaceLaneVecI32x4, - ReplaceLaneVecI64x2, - ReplaceLaneVecF32x4, - ReplaceLaneVecF64x2); + SIMDReplaceOp op = + pick(FeatureOptions() + .add(FeatureSet::SIMD, + ReplaceLaneVecI8x16, + ReplaceLaneVecI16x8, + ReplaceLaneVecI32x4, + ReplaceLaneVecI64x2, + ReplaceLaneVecF32x4, + ReplaceLaneVecF64x2) + .add(FeatureSet::FeatureSet::FP16, ReplaceLaneVecF16x8)); Expression* vec = make(Type::v128); uint8_t index; Type lane_t; @@ -3647,6 +3656,10 @@ Expression* TranslateToFuzzReader::makeSIMDReplace() { index = upTo(2); lane_t = Type::i64; break; + case ReplaceLaneVecF16x8: + index = upTo(8); + lane_t = Type::f32; + break; case ReplaceLaneVecF32x4: index = upTo(4); lane_t = Type::f32; diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h index c9d891a00bb..bfa9a9b5c40 100644 --- a/src/tools/tool-options.h +++ b/src/tools/tool-options.h @@ -95,6 +95,7 @@ struct ToolOptions : public Options { .addFeature(FeatureSet::MultiMemory, "multimemory") .addFeature(FeatureSet::TypedContinuations, "typed continuations") .addFeature(FeatureSet::SharedEverything, "shared-everything threads") + .addFeature(FeatureSet::FP16, "float 16 operations") .add("--enable-typed-function-references", "", "Deprecated compatibility flag", diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 1fbe7535c5e..a4439f02699 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -436,6 +436,7 @@ extern const char* StringsFeature; extern const char* MultiMemoryFeature; extern const char* TypedContinuationsFeature; extern const char* SharedEverythingFeature; +extern const char* FP16Feature; enum Subsection { NameModule = 0, diff --git a/src/wasm-features.h b/src/wasm-features.h index 366b7520008..92b07b5477f 100644 --- a/src/wasm-features.h +++ b/src/wasm-features.h @@ -46,11 +46,12 @@ struct FeatureSet { MultiMemory = 1 << 15, TypedContinuations = 1 << 16, SharedEverything = 1 << 17, + FP16 = 1 << 18, MVP = None, // Keep in sync with llvm default features: // https://github.com/llvm/llvm-project/blob/c7576cb89d6c95f03968076e902d3adfd1996577/clang/lib/Basic/Targets/WebAssembly.cpp#L150-L153 Default = SignExt | MutableGlobals, - All = (1 << 18) - 1, + All = (1 << 19) - 1, }; static std::string toString(Feature f) { @@ -91,6 +92,8 @@ struct FeatureSet { return "typed-continuations"; case SharedEverything: return "shared-everything"; + case FP16: + return "fp16"; default: WASM_UNREACHABLE("unexpected feature"); } @@ -141,6 +144,7 @@ struct FeatureSet { bool hasSharedEverything() const { return (features & SharedEverything) != 0; } + bool hasFP16() const { return (features & FP16) != 0; } bool hasAll() const { return (features & All) != 0; } void set(FeatureSet f, bool v = true) { @@ -164,6 +168,7 @@ struct FeatureSet { void setMultiMemory(bool v = true) { set(MultiMemory, v); } void setTypedContinuations(bool v = true) { set(TypedContinuations, v); } void setSharedEverything(bool v = true) { set(SharedEverything, v); } + void setFP16(bool v = true) { set(FP16, v); } void setMVP() { features = MVP; } void setAll() { features = All; } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index e84639801e3..06d17fdfb9b 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1358,6 +1358,8 @@ void WasmBinaryWriter::writeFeaturesSection() { return BinaryConsts::CustomSections::TypedContinuationsFeature; case FeatureSet::SharedEverything: return BinaryConsts::CustomSections::SharedEverythingFeature; + case FeatureSet::FP16: + return BinaryConsts::CustomSections::FP16Feature; case FeatureSet::None: case FeatureSet::Default: case FeatureSet::All: @@ -3892,6 +3894,8 @@ void WasmBinaryReader::readFeatures(size_t payloadLen) { feature = FeatureSet::TypedContinuations; } else if (name == BinaryConsts::CustomSections::SharedEverythingFeature) { feature = FeatureSet::SharedEverything; + } else if (name == BinaryConsts::CustomSections::FP16Feature) { + feature = FeatureSet::FP16; } else { // Silently ignore unknown features (this may be and old binaryen running // on a new wasm). diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 24f5379fbd0..4881ea7ac25 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1274,6 +1274,9 @@ void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) { lanes = 2; break; case ExtractLaneVecF16x8: + shouldBeTrue(getModule()->features.hasFP16(), + curr, + "FP16 operations require FP16 [--enable-fp16]"); lane_t = Type::f32; lanes = 8; break; @@ -1324,6 +1327,9 @@ void FunctionValidator::visitSIMDReplace(SIMDReplace* curr) { lanes = 2; break; case ReplaceLaneVecF16x8: + shouldBeTrue(getModule()->features.hasFP16(), + curr, + "FP16 operations require FP16 [--enable-fp16]"); lane_t = Type::f32; lanes = 8; break; @@ -1708,6 +1714,24 @@ void FunctionValidator::visitBinary(Binary* curr) { curr->left->type, Type(Type::f64), curr, "f64 op"); break; } + case EqVecF16x8: + case NeVecF16x8: + case LtVecF16x8: + case LeVecF16x8: + case GtVecF16x8: + case GeVecF16x8: + case AddVecF16x8: + case SubVecF16x8: + case MulVecF16x8: + case DivVecF16x8: + case MinVecF16x8: + case MaxVecF16x8: + case PMinVecF16x8: + case PMaxVecF16x8: + shouldBeTrue(getModule()->features.hasFP16(), + curr, + "FP16 operations require FP16 [--enable-fp16]"); + [[fallthrough]]; case EqVecI8x16: case NeVecI8x16: case LtSVecI8x16: @@ -1744,12 +1768,6 @@ void FunctionValidator::visitBinary(Binary* curr) { case LeSVecI64x2: case GtSVecI64x2: case GeSVecI64x2: - case EqVecF16x8: - case NeVecF16x8: - case LtVecF16x8: - case LeVecF16x8: - case GtVecF16x8: - case GeVecF16x8: case EqVecF32x4: case NeVecF32x4: case LtVecF32x4: @@ -1813,14 +1831,6 @@ void FunctionValidator::visitBinary(Binary* curr) { case ExtMulHighSVecI64x2: case ExtMulLowUVecI64x2: case ExtMulHighUVecI64x2: - case AddVecF16x8: - case SubVecF16x8: - case MulVecF16x8: - case DivVecF16x8: - case MinVecF16x8: - case MaxVecF16x8: - case PMinVecF16x8: - case PMaxVecF16x8: case AddVecF32x4: case SubVecF32x4: case MulVecF32x4: @@ -2060,6 +2070,10 @@ void FunctionValidator::visitUnary(Unary* curr) { curr->value->type, Type(Type::i64), curr, "expected i64 splat value"); break; case SplatVecF16x8: + shouldBeTrue(getModule()->features.hasFP16(), + curr, + "FP16 operations require FP16 [--enable-fp16]"); + [[fallthrough]]; case SplatVecF32x4: shouldBeEqual( curr->type, Type(Type::v128), curr, "expected splat to have v128 type"); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index ff641c7eb0a..e768f0dc498 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -56,6 +56,7 @@ const char* StringsFeature = "strings"; const char* MultiMemoryFeature = "multimemory"; const char* TypedContinuationsFeature = "typed-continuations"; const char* SharedEverythingFeature = "shared-everything"; +const char* FP16Feature = "fp16"; } // namespace CustomSections } // namespace BinaryConsts diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 212194c9c86..d41301751d5 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -33,7 +33,7 @@ Features.RelaxedSIMD: 4096 Features.ExtendedConst: 8192 Features.Strings: 16384 Features.MultiMemory: 32768 -Features.All: 262143 +Features.All: 524287 InvalidId: 0 BlockId: 1 IfId: 2 diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index e568cfba01c..17344ccab13 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -47,7 +47,7 @@ BinaryenFeatureMemory64: 2048 BinaryenFeatureRelaxedSIMD: 4096 BinaryenFeatureExtendedConst: 8192 BinaryenFeatureStrings: 16384 -BinaryenFeatureAll: 262143 +BinaryenFeatureAll: 524287 (f32.neg (f32.const -33.61199951171875) ) diff --git a/test/lit/help/wasm-as.test b/test/lit/help/wasm-as.test index 3a863dbd6b4..a2ee3d45e52 100644 --- a/test/lit/help/wasm-as.test +++ b/test/lit/help/wasm-as.test @@ -112,6 +112,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-ctor-eval.test b/test/lit/help/wasm-ctor-eval.test index 2d57e3e8cc3..4ad75a8d061 100644 --- a/test/lit/help/wasm-ctor-eval.test +++ b/test/lit/help/wasm-ctor-eval.test @@ -119,6 +119,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-dis.test b/test/lit/help/wasm-dis.test index 63c7f8bd0b1..96e999c2c7b 100644 --- a/test/lit/help/wasm-dis.test +++ b/test/lit/help/wasm-dis.test @@ -105,6 +105,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-emscripten-finalize.test b/test/lit/help/wasm-emscripten-finalize.test index c92960dfbeb..fbf86209c69 100644 --- a/test/lit/help/wasm-emscripten-finalize.test +++ b/test/lit/help/wasm-emscripten-finalize.test @@ -147,6 +147,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-merge.test b/test/lit/help/wasm-merge.test index fe3f1cdb29e..108fd367373 100644 --- a/test/lit/help/wasm-merge.test +++ b/test/lit/help/wasm-merge.test @@ -135,6 +135,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test index e25a0214d10..665d78746ad 100644 --- a/test/lit/help/wasm-metadce.test +++ b/test/lit/help/wasm-metadce.test @@ -734,6 +734,10 @@ ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything ;; CHECK-NEXT: threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 3a577099b2e..4eea3c4313d 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -743,6 +743,10 @@ ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything ;; CHECK-NEXT: threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-reduce.test b/test/lit/help/wasm-reduce.test index cacf260fab5..61e171ba91d 100644 --- a/test/lit/help/wasm-reduce.test +++ b/test/lit/help/wasm-reduce.test @@ -141,6 +141,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test index bc09796d77e..a6074c85df8 100644 --- a/test/lit/help/wasm-split.test +++ b/test/lit/help/wasm-split.test @@ -222,6 +222,10 @@ ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test index 3c0a17e7a70..501d1d3f17b 100644 --- a/test/lit/help/wasm2js.test +++ b/test/lit/help/wasm2js.test @@ -697,6 +697,10 @@ ;; CHECK-NEXT: --disable-shared-everything Disable shared-everything ;; CHECK-NEXT: threads ;; CHECK-NEXT: +;; CHECK-NEXT: --enable-fp16 Enable float 16 operations +;; CHECK-NEXT: +;; CHECK-NEXT: --disable-fp16 Disable float 16 operations +;; CHECK-NEXT: ;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag ;; CHECK-NEXT: ;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag diff --git a/test/lit/validation/fp16.wast b/test/lit/validation/fp16.wast new file mode 100644 index 00000000000..b1c8ce9c2d7 --- /dev/null +++ b/test/lit/validation/fp16.wast @@ -0,0 +1,11 @@ +;; Test that fp16 operations require the fp16 feature. + +;; RUN: not wasm-opt %s --enable-simd 2>&1 | filecheck %s --check-prefix NO-FP16 +;; RUN: wasm-opt %s --enable-simd --enable-fp16 -o - -S | filecheck %s --check-prefix FP16 + +;; NO-FP16: FP16 operations require FP16 [--enable-fp16] +;; FP16: (type $0 (func (param v128 v128) (result v128))) + +(module + (func (export "f16x8.add") (param $0 v128) (param $1 v128) (result v128) (f16x8.add (local.get $0) (local.get $1))) +) diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt index 2c6523e6d92..901f43bc504 100644 --- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt +++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt @@ -16,6 +16,7 @@ --enable-multimemory --enable-typed-continuations --enable-shared-everything +--enable-fp16 (module (type $0 (func (result v128 externref))) (func $foo (type $0) (result v128 externref) diff --git a/test/unit/test_features.py b/test/unit/test_features.py index 3bd9ac127a4..f5c3fabc507 100644 --- a/test/unit/test_features.py +++ b/test/unit/test_features.py @@ -426,4 +426,5 @@ def test_emit_all_features(self): '--enable-multimemory', '--enable-typed-continuations', '--enable-shared-everything', + '--enable-fp16', ], p2.stdout.splitlines()) From dacc6e57048dc9af133c98ea3c843f8b912c9980 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 26 Aug 2024 10:15:00 -0700 Subject: [PATCH 541/553] Support more reference constants in wast scripts (#6865) Spec tests use constants like `ref.array` and `ref.eq` to assert that exported function return references of the correct types. Support more such constants in the wast parser. Also fix a bug where the interpretation of `array.new_data` for arrays of packed fields was not properly truncating the packed data. Move the function for reading fields from memory from literal.cpp to wasm-interpreter.h, where the function for truncating packed data lives. Other bugs prevent us from enabling any more spec tests as a result of this change, but we can get farther through several of them before failing. Update the comments about the failures accordingly. --- scripts/test/shared.py | 6 +++--- src/literal.h | 1 - src/parser/wast-parser.cpp | 28 ++++++++++++++++++++++++++++ src/wasm-interpreter.h | 24 +++++++++++++++++++++--- src/wasm/literal.cpp | 18 ------------------ 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 019d2b25188..4ca065d0358 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -452,16 +452,16 @@ def get_tests(test_dir, extensions=[], recursive=False): 'table.wast', # Requires support for table default elements 'type-equivalence.wast', # Recursive types allowed by GC 'unreached-invalid.wast', # Requires more precise unreachable validation - 'array.wast', # Requires ref.array wast constants + 'array.wast', # Requires support for table default elements 'array_init_elem.wast', # Requires support for elem.drop 'br_if.wast', # Requires more precise branch validation 'br_on_cast.wast', # Requires sending values on br_on_cast 'br_on_cast_fail.wast', # Requires sending values on br_on_cast_fail 'extern.wast', # Requires ref.host wast constants - 'i31.wast', # Requires ref.i31 wast constants + 'i31.wast', # Requires support for table default elements 'ref_cast.wast', # Requires host references to not be externalized i31refs 'ref_test.wast', # Requires host references to not be externalized i31refs - 'struct.wast', # Requires ref.struct wast constants + 'struct.wast', # Duplicate field names not properly rejected 'type-rec.wast', # Requires wast `register` support 'type-subtyping.wast', # ShellExternalInterface::callTable does not handle subtyping 'call_indirect.wast', # Bug with 64-bit inline element segment parsing diff --git a/src/literal.h b/src/literal.h index 882a990275b..df9a16d9a50 100644 --- a/src/literal.h +++ b/src/literal.h @@ -211,7 +211,6 @@ class Literal { } static Literal makeFromMemory(void* p, Type type); - static Literal makeFromMemory(void* p, const Field& field); static Literal makeSignedMin(Type type) { switch (type.getBasic()) { diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 00269a57771..5eaf352b739 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -217,6 +217,34 @@ Result result(Lexer& in) { return RefResult{HeapType::func}; } + if (in.takeSExprStart("ref.struct")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.struct"); + } + return RefResult{HeapType::struct_}; + } + + if (in.takeSExprStart("ref.array")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.array"); + } + return RefResult{HeapType::array}; + } + + if (in.takeSExprStart("ref.eq")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.eq"); + } + return RefResult{HeapType::eq}; + } + + if (in.takeSExprStart("ref.i31")) { + if (!in.takeRParen()) { + return in.err("expected end of ref.i31"); + } + return RefResult{HeapType::i31}; + } + if (in.takeSExprStart("ref.i31_shared")) { if (!in.takeRParen()) { return in.err("expected end of ref.i31_shared"); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 81b755f9f05..77349fd332e 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2196,7 +2196,7 @@ class ExpressionRunner : public OverriddenVisitor { WASM_UNREACHABLE("unimp"); } -private: +protected: // Truncate the value if we need to. The storage is just a list of Literals, // so we can't just write the value like we would to a C struct field and // expect it to truncate for us. Instead, we truncate so the stored value is @@ -2231,6 +2231,24 @@ class ExpressionRunner : public OverriddenVisitor { } return value; } + + Literal makeFromMemory(void* p, Field field) { + switch (field.packedType) { + case Field::not_packed: + return Literal::makeFromMemory(p, field.type); + case Field::i8: { + int8_t i; + memcpy(&i, p, sizeof(i)); + return truncateForPacking(Literal(int32_t(i)), field); + } + case Field::i16: { + int16_t i; + memcpy(&i, p, sizeof(i)); + return truncateForPacking(Literal(int32_t(i)), field); + } + } + WASM_UNREACHABLE("unexpected type"); + } }; // Execute a suspected constant expression (precompute and C-API). @@ -3972,7 +3990,7 @@ class ModuleRunnerBase : public ExpressionRunner { contents.reserve(size); for (Index i = offset; i < end; i += elemBytes) { auto addr = (void*)&seg.data[i]; - contents.push_back(Literal::makeFromMemory(addr, element)); + contents.push_back(this->makeFromMemory(addr, element)); } return self()->makeGCData(contents, curr->type); } @@ -4052,7 +4070,7 @@ class ModuleRunnerBase : public ExpressionRunner { } for (size_t i = 0; i < sizeVal; i++) { void* addr = (void*)&seg->data[offsetVal + i * elemSize]; - data->values[indexVal + i] = Literal::makeFromMemory(addr, elem); + data->values[indexVal + i] = this->makeFromMemory(addr, elem); } return {}; } diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 65c2b4e62af..6a4614a90e7 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -294,24 +294,6 @@ Literal Literal::makeFromMemory(void* p, Type type) { } } -Literal Literal::makeFromMemory(void* p, const Field& field) { - switch (field.packedType) { - case Field::not_packed: - return makeFromMemory(p, field.type); - case Field::i8: { - int8_t i; - memcpy(&i, p, sizeof(i)); - return Literal(int32_t(i)); - } - case Field::i16: { - int16_t i; - memcpy(&i, p, sizeof(i)); - return Literal(int32_t(i)); - } - } - WASM_UNREACHABLE("unexpected type"); -} - Literal Literal::standardizeNaN(const Literal& input) { if (!std::isnan(input.getFloat())) { return input; From b7af8dac2fe457d47d6b29cabb8327457341bffe Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Mon, 26 Aug 2024 13:51:18 -0700 Subject: [PATCH 542/553] Fix the fp16 header include. (#6871) --- third_party/FP16/include/fp16/bitcasts.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/third_party/FP16/include/fp16/bitcasts.h b/third_party/FP16/include/fp16/bitcasts.h index ae68843259c..9353961e38d 100644 --- a/third_party/FP16/include/fp16/bitcasts.h +++ b/third_party/FP16/include/fp16/bitcasts.h @@ -8,11 +8,7 @@ #include #endif -#if defined(__INTEL_COMPILER) || defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64)) - #include -#endif - -#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64)) +#if (defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64))) || defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1932) && (defined(_M_IX86) || defined(_M_X64))) #include #endif From 50181145e39304785ccedcd84be9cb7cc428b1f2 Mon Sep 17 00:00:00 2001 From: mtb Date: Mon, 26 Aug 2024 23:13:39 +0200 Subject: [PATCH 543/553] Fix null dereference in FunctionValidator (#6849) visitBlock() and validateCallParamsAndResult() both assumed they were running inside a function, but might be called on global code too. Calls and blocks are invalid in global positions, so we should error there, but must do so properly without a null deref. Fixes #6847 Fixes #6848 --- src/wasm/wasm-validator.cpp | 13 +++++++++++-- test/lit/validation/function-missing.wast | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/lit/validation/function-missing.wast diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 4881ea7ac25..f77eeefe78d 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -606,9 +606,13 @@ struct FunctionValidator : public WalkerPass> { Type(Type::unreachable), printable, "return_call* should have unreachable type"); + auto* func = getFunction(); + if (!shouldBeTrue(!!func, curr, "function not defined")) { + return; + } shouldBeSubType( sig.results, - getFunction()->getResults(), + func->getResults(), printable, "return_call* callee return type must match caller return type"); } else { @@ -696,7 +700,12 @@ void FunctionValidator::visitBlock(Block* curr) { } breakTypes.erase(iter); } - switch (getFunction()->profile) { + + auto* func = getFunction(); + if (!shouldBeTrue(!!func, curr, "function not defined")) { + return; + } + switch (func->profile) { case IRProfile::Normal: validateNormalBlockElements(curr); break; diff --git a/test/lit/validation/function-missing.wast b/test/lit/validation/function-missing.wast new file mode 100644 index 00000000000..5510644a7ea --- /dev/null +++ b/test/lit/validation/function-missing.wast @@ -0,0 +1,14 @@ +;; Test that we validate functions declaration and usage for globals. + +;; RUN: not wasm-opt %s -all 2>&1 | filecheck %s + +(module + ;; CHECK: function not defined + (global (mut i32) (block)) + + ;; CHECK: function not defined + (global (mut i32) (return_call 0)) + + (func $0 + ) +) \ No newline at end of file From 459bc0797f67cb2a8fd4598bb7143b34036608d9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 26 Aug 2024 16:00:45 -0700 Subject: [PATCH 544/553] [NFC] Optimize ParamUtils::getUsedParams() (#6866) This constructed a LocalGraph, which computes the sets that reach each get. But all we need to know is which params are live, so instead we can do a liveness computation (which is just a boolean, not the list of sets). Also, it is simple to get the liveness computation to only work on the parameters and not all the locals, as a further optimization. Existing tests cover this, though I did find that the case of unreachability needed a new test. On a large testcase I am looking at, this makes --dae 17% faster. --- src/passes/DeadArgumentElimination.cpp | 2 +- src/passes/SignaturePruning.cpp | 2 +- src/passes/param-utils.cpp | 55 +++++++++++++++++++------- src/passes/param-utils.h | 2 +- test/lit/passes/dae_all-features.wast | 31 +++++++++++++++ 5 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index 83cd7e86d07..99a70965475 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -158,7 +158,7 @@ struct DAEScanner // part of, say if we are exported, or if another parallel function finds a // RefFunc to us and updates it before we check it). if (numParams > 0 && !info->hasUnseenCalls) { - auto usedParams = ParamUtils::getUsedParams(func); + auto usedParams = ParamUtils::getUsedParams(func, getModule()); for (Index i = 0; i < numParams; i++) { if (usedParams.count(i) == 0) { info->unusedParams.insert(i); diff --git a/src/passes/SignaturePruning.cpp b/src/passes/SignaturePruning.cpp index 4480c18321e..a9fb4d23aa4 100644 --- a/src/passes/SignaturePruning.cpp +++ b/src/passes/SignaturePruning.cpp @@ -96,7 +96,7 @@ struct SignaturePruning : public Pass { info.calls = std::move(FindAll(func->body).list); info.callRefs = std::move(FindAll(func->body).list); - info.usedParams = ParamUtils::getUsedParams(func); + info.usedParams = ParamUtils::getUsedParams(func, module); }); // A map of types to all the information combined over all the functions diff --git a/src/passes/param-utils.cpp b/src/passes/param-utils.cpp index 0caccff1168..f54f91bd9b6 100644 --- a/src/passes/param-utils.cpp +++ b/src/passes/param-utils.cpp @@ -15,9 +15,9 @@ */ #include "passes/param-utils.h" +#include "cfg/liveness-traversal.h" #include "ir/eh-utils.h" #include "ir/function-utils.h" -#include "ir/local-graph.h" #include "ir/localize.h" #include "ir/possible-constant.h" #include "ir/type-updating.h" @@ -28,25 +28,50 @@ namespace wasm::ParamUtils { -std::unordered_set getUsedParams(Function* func) { - LocalGraph localGraph(func); - - std::unordered_set usedParams; - - for (auto& [get, sets] : localGraph.getSetses) { - if (!func->isParam(get->index)) { - continue; +std::unordered_set getUsedParams(Function* func, Module* module) { + // To find which params are used, compute liveness at the entry. + // TODO: We could write bespoke code here rather than reuse LivenessWalker, as + // we only need liveness at the entry. The code below computes it for + // the param indexes in the entire function. However, there are usually + // very few params (compared to locals, which we ignore here), so this + // may be fast enough, and is very simple. + struct ParamLiveness + : public LivenessWalker> { + using Super = LivenessWalker>; + + // Branches outside of the function can be ignored, as we only look at + // locals, which vanish when we leave. + bool ignoreBranchesOutsideOfFunc = true; + + // Ignore unreachable code and non-params. + static void doVisitLocalGet(ParamLiveness* self, Expression** currp) { + auto* get = (*currp)->cast(); + if (self->currBasicBlock && self->getFunction()->isParam(get->index)) { + Super::doVisitLocalGet(self, currp); + } } - - for (auto* set : sets) { - // A nullptr value indicates there is no LocalSet* that sets the value, - // so it must be the parameter value. - if (!set) { - usedParams.insert(get->index); + static void doVisitLocalSet(ParamLiveness* self, Expression** currp) { + auto* set = (*currp)->cast(); + if (self->currBasicBlock && self->getFunction()->isParam(set->index)) { + Super::doVisitLocalSet(self, currp); } } + } walker; + walker.setModule(module); + walker.walkFunction(func); + + if (!walker.entry) { + // Empty function: nothing is used. + return {}; } + // We now have a sorted vector of the live params at the entry. Convert that + // to a set. + auto& sortedLiveness = walker.entry->contents.start; + std::unordered_set usedParams; + for (auto live : sortedLiveness) { + usedParams.insert(live); + } return usedParams; } diff --git a/src/passes/param-utils.h b/src/passes/param-utils.h index 4c458390afa..35e5d9f808a 100644 --- a/src/passes/param-utils.h +++ b/src/passes/param-utils.h @@ -42,7 +42,7 @@ namespace wasm::ParamUtils { // function foo(x) { // bar(x); // read of a param value // } -std::unordered_set getUsedParams(Function* func); +std::unordered_set getUsedParams(Function* func, Module* module); // The outcome of an attempt to remove a parameter(s). enum RemovalOutcome { diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast index 17ea77942f5..da9558dd8e0 100644 --- a/test/lit/passes/dae_all-features.wast +++ b/test/lit/passes/dae_all-features.wast @@ -940,3 +940,34 @@ (unreachable) ) ) + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (type $1 (func (param i32))) + + ;; CHECK: (func $target (type $0) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $target (param $0 i32) + ;; The parameter here is unused: there is a get, but it is unreachable. We can + ;; remove the parameter here, and in the caller below. + (unreachable) + (drop + (local.get $0) + ) + ) + + ;; CHECK: (func $caller (type $1) (param $x i32) + ;; CHECK-NEXT: (call $target) + ;; CHECK-NEXT: ) + (func $caller (param $x i32) + (call $target + (local.get $x) + ) + ) +) From 6c2d0e20906248ab8f8365702b35fd67db29c44f Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 27 Aug 2024 11:14:54 -0700 Subject: [PATCH 545/553] [FP16] Implement unary operations. (#6867) Specified at https://github.com/WebAssembly/half-precision/blob/main/proposals/half-precision/Overview.md --- scripts/gen-s-parser.py | 7 ++ src/gen-s-parser.inc | 68 +++++++++-- src/ir/child-typer.h | 7 ++ src/ir/cost.h | 7 ++ src/literal.h | 7 ++ src/passes/Print.cpp | 21 ++++ src/tools/fuzzing/fuzzing.cpp | 61 ++++++---- src/wasm-binary.h | 7 ++ src/wasm-interpreter.h | 14 +++ src/wasm.h | 7 ++ src/wasm/literal.cpp | 36 ++++-- src/wasm/wasm-binary.cpp | 28 +++++ src/wasm/wasm-stack.cpp | 22 ++++ src/wasm/wasm-validator.cpp | 11 ++ src/wasm/wasm.cpp | 7 ++ test/lit/basic/f16.wast | 213 +++++++++++++++++++++++++++++----- test/spec/f16.wast | 40 +++++++ 17 files changed, 493 insertions(+), 70 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 39d621f4861..49fa6afb63b 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -452,6 +452,9 @@ ("i64x2.extmul_high_i32x4_s", "makeBinary(BinaryOp::ExtMulHighSVecI64x2)"), ("i64x2.extmul_low_i32x4_u", "makeBinary(BinaryOp::ExtMulLowUVecI64x2)"), ("i64x2.extmul_high_i32x4_u", "makeBinary(BinaryOp::ExtMulHighUVecI64x2)"), + ("f16x8.abs", "makeUnary(UnaryOp::AbsVecF16x8)"), + ("f16x8.neg", "makeUnary(UnaryOp::NegVecF16x8)"), + ("f16x8.sqrt", "makeUnary(UnaryOp::SqrtVecF16x8)"), ("f16x8.add", "makeBinary(BinaryOp::AddVecF16x8)"), ("f16x8.sub", "makeBinary(BinaryOp::SubVecF16x8)"), ("f16x8.mul", "makeBinary(BinaryOp::MulVecF16x8)"), @@ -460,6 +463,10 @@ ("f16x8.max", "makeBinary(BinaryOp::MaxVecF16x8)"), ("f16x8.pmin", "makeBinary(BinaryOp::PMinVecF16x8)"), ("f16x8.pmax", "makeBinary(BinaryOp::PMaxVecF16x8)"), + ("f16x8.ceil", "makeUnary(UnaryOp::CeilVecF16x8)"), + ("f16x8.floor", "makeUnary(UnaryOp::FloorVecF16x8)"), + ("f16x8.trunc", "makeUnary(UnaryOp::TruncVecF16x8)"), + ("f16x8.nearest", "makeUnary(UnaryOp::NearestVecF16x8)"), ("f32x4.abs", "makeUnary(UnaryOp::AbsVecF32x4)"), ("f32x4.neg", "makeUnary(UnaryOp::NegVecF32x4)"), ("f32x4.sqrt", "makeUnary(UnaryOp::SqrtVecF32x4)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index f4afd1f1b6f..7d4fbe81914 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -309,9 +309,26 @@ switch (buf[0]) { switch (buf[1]) { case '1': { switch (buf[6]) { - case 'a': - if (op == "f16x8.add"sv) { - CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddVecF16x8)); + case 'a': { + switch (buf[7]) { + case 'b': + if (op == "f16x8.abs"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::AbsVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'd': + if (op == "f16x8.add"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; + } + } + case 'c': + if (op == "f16x8.ceil"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::CeilVecF16x8)); return Ok{}; } goto parse_error; @@ -338,6 +355,12 @@ switch (buf[0]) { default: goto parse_error; } } + case 'f': + if (op == "f16x8.floor"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::FloorVecF16x8)); + return Ok{}; + } + goto parse_error; case 'g': { switch (buf[7]) { case 'e': @@ -395,12 +418,29 @@ switch (buf[0]) { default: goto parse_error; } } - case 'n': - if (op == "f16x8.ne"sv) { - CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::NeVecF16x8)); - return Ok{}; + case 'n': { + switch (buf[8]) { + case '\0': + if (op == "f16x8.ne"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::NeVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'a': + if (op == "f16x8.nearest"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::NearestVecF16x8)); + return Ok{}; + } + goto parse_error; + case 'g': + if (op == "f16x8.neg"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::NegVecF16x8)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 'p': { switch (buf[8]) { case 'a': @@ -432,6 +472,12 @@ switch (buf[0]) { return Ok{}; } goto parse_error; + case 'q': + if (op == "f16x8.sqrt"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SqrtVecF16x8)); + return Ok{}; + } + goto parse_error; case 'u': if (op == "f16x8.sub"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::SubVecF16x8)); @@ -441,6 +487,12 @@ switch (buf[0]) { default: goto parse_error; } } + case 't': + if (op == "f16x8.trunc"sv) { + CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::TruncVecF16x8)); + return Ok{}; + } + goto parse_error; default: goto parse_error; } } diff --git a/src/ir/child-typer.h b/src/ir/child-typer.h index fe65b209bea..638bb9c33ae 100644 --- a/src/ir/child-typer.h +++ b/src/ir/child-typer.h @@ -372,6 +372,13 @@ template struct ChildTyper : OverriddenVisitor { case NegVecI16x8: case NegVecI32x4: case NegVecI64x2: + case AbsVecF16x8: + case NegVecF16x8: + case SqrtVecF16x8: + case CeilVecF16x8: + case FloorVecF16x8: + case TruncVecF16x8: + case NearestVecF16x8: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4: diff --git a/src/ir/cost.h b/src/ir/cost.h index 0b2b6315b09..f541a450658 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -206,6 +206,13 @@ struct CostAnalyzer : public OverriddenVisitor { case NegVecI64x2: case AllTrueVecI64x2: case BitmaskVecI64x2: + case AbsVecF16x8: + case NegVecF16x8: + case SqrtVecF16x8: + case CeilVecF16x8: + case FloorVecF16x8: + case TruncVecF16x8: + case NearestVecF16x8: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4: diff --git a/src/literal.h b/src/literal.h index df9a16d9a50..7bedab5b400 100644 --- a/src/literal.h +++ b/src/literal.h @@ -618,6 +618,9 @@ class Literal { Literal extMulHighSI64x2(const Literal& other) const; Literal extMulLowUI64x2(const Literal& other) const; Literal extMulHighUI64x2(const Literal& other) const; + Literal absF16x8() const; + Literal negF16x8() const; + Literal sqrtF16x8() const; Literal addF16x8(const Literal& other) const; Literal subF16x8(const Literal& other) const; Literal mulF16x8(const Literal& other) const; @@ -626,6 +629,10 @@ class Literal { Literal maxF16x8(const Literal& other) const; Literal pminF16x8(const Literal& other) const; Literal pmaxF16x8(const Literal& other) const; + Literal ceilF16x8() const; + Literal floorF16x8() const; + Literal truncF16x8() const; + Literal nearestF16x8() const; Literal absF32x4() const; Literal negF32x4() const; Literal sqrtF32x4() const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 4986982c731..8f53481b70d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1209,6 +1209,27 @@ struct PrintExpressionContents case BitmaskVecI64x2: o << "i64x2.bitmask"; break; + case AbsVecF16x8: + o << "f16x8.abs"; + break; + case NegVecF16x8: + o << "f16x8.neg"; + break; + case SqrtVecF16x8: + o << "f16x8.sqrt"; + break; + case CeilVecF16x8: + o << "f16x8.ceil"; + break; + case FloorVecF16x8: + o << "f16x8.floor"; + break; + case TruncVecF16x8: + o << "f16x8.trunc"; + break; + case NearestVecF16x8: + o << "f16x8.nearest"; + break; case AbsVecF32x4: o << "f32x4.abs"; break; diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 7a3007e437a..a66fa6772d0 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -3109,31 +3109,42 @@ Expression* TranslateToFuzzReader::makeUnary(Type type) { case 3: return buildUnary({SplatVecF64x2, make(Type::f64)}); case 4: - return buildUnary({pick(NotVec128, - // TODO: add additional SIMD instructions - NegVecI8x16, - NegVecI16x8, - NegVecI32x4, - NegVecI64x2, - AbsVecF32x4, - NegVecF32x4, - SqrtVecF32x4, - AbsVecF64x2, - NegVecF64x2, - SqrtVecF64x2, - TruncSatSVecF32x4ToVecI32x4, - TruncSatUVecF32x4ToVecI32x4, - ConvertSVecI32x4ToVecF32x4, - ConvertUVecI32x4ToVecF32x4, - ExtendLowSVecI8x16ToVecI16x8, - ExtendHighSVecI8x16ToVecI16x8, - ExtendLowUVecI8x16ToVecI16x8, - ExtendHighUVecI8x16ToVecI16x8, - ExtendLowSVecI16x8ToVecI32x4, - ExtendHighSVecI16x8ToVecI32x4, - ExtendLowUVecI16x8ToVecI32x4, - ExtendHighUVecI16x8ToVecI32x4), - make(Type::v128)}); + return buildUnary( + {pick(FeatureOptions() + .add(FeatureSet::SIMD, + NotVec128, + // TODO: add additional SIMD instructions + NegVecI8x16, + NegVecI16x8, + NegVecI32x4, + NegVecI64x2, + AbsVecF32x4, + NegVecF32x4, + SqrtVecF32x4, + AbsVecF64x2, + NegVecF64x2, + SqrtVecF64x2, + TruncSatSVecF32x4ToVecI32x4, + TruncSatUVecF32x4ToVecI32x4, + ConvertSVecI32x4ToVecF32x4, + ConvertUVecI32x4ToVecF32x4, + ExtendLowSVecI8x16ToVecI16x8, + ExtendHighSVecI8x16ToVecI16x8, + ExtendLowUVecI8x16ToVecI16x8, + ExtendHighUVecI8x16ToVecI16x8, + ExtendLowSVecI16x8ToVecI32x4, + ExtendHighSVecI16x8ToVecI32x4, + ExtendLowUVecI16x8ToVecI32x4, + ExtendHighUVecI16x8ToVecI32x4) + .add(FeatureSet::FP16, + AbsVecF16x8, + NegVecF16x8, + SqrtVecF16x8, + CeilVecF16x8, + FloorVecF16x8, + TruncVecF16x8, + NearestVecF16x8)), + make(Type::v128)}); } WASM_UNREACHABLE("invalid value"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index a4439f02699..9ce355b48a1 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1059,6 +1059,13 @@ enum ASTNodes { F16x8Splat = 0x120, F16x8ExtractLane = 0x121, F16x8ReplaceLane = 0x122, + F16x8Abs = 0x130, + F16x8Neg = 0x131, + F16x8Sqrt = 0x132, + F16x8Ceil = 0x133, + F16x8Floor = 0x134, + F16x8Trunc = 0x135, + F16x8Nearest = 0x136, F16x8Eq = 0x137, F16x8Ne = 0x138, F16x8Lt = 0x139, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 77349fd332e..50fc296fe3d 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -531,6 +531,20 @@ class ExpressionRunner : public OverriddenVisitor { return value.allTrueI64x2(); case BitmaskVecI64x2: return value.bitmaskI64x2(); + case AbsVecF16x8: + return value.absF16x8(); + case NegVecF16x8: + return value.negF16x8(); + case SqrtVecF16x8: + return value.sqrtF16x8(); + case CeilVecF16x8: + return value.ceilF16x8(); + case FloorVecF16x8: + return value.floorF16x8(); + case TruncVecF16x8: + return value.truncF16x8(); + case NearestVecF16x8: + return value.nearestF16x8(); case AbsVecF32x4: return value.absF32x4(); case NegVecF32x4: diff --git a/src/wasm.h b/src/wasm.h index 6f82196b709..a707ab7a4b1 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -179,6 +179,13 @@ enum UnaryOp { NegVecI64x2, AllTrueVecI64x2, BitmaskVecI64x2, + AbsVecF16x8, + NegVecF16x8, + SqrtVecF16x8, + CeilVecF16x8, + FloorVecF16x8, + TruncVecF16x8, + NearestVecF16x8, AbsVecF32x4, NegVecF32x4, SqrtVecF32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 6a4614a90e7..1b84ba53c02 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -1842,13 +1842,19 @@ Literal Literal::replaceLaneF64x2(const Literal& other, uint8_t index) const { return replace<2, &Literal::getLanesF64x2>(*this, other, index); } +static Literal passThrough(const Literal& literal) { return literal; } +static Literal toFP16(const Literal& literal) { + return literal.convertF32ToF16(); +} + template (Literal::*IntoLanes)() const, - Literal (Literal::*UnaryOp)(void) const> + Literal (Literal::*UnaryOp)(void) const, + Literal (*Convert)(const Literal&) = passThrough> static Literal unary(const Literal& val) { LaneArray lanes = (val.*IntoLanes)(); for (size_t i = 0; i < Lanes; ++i) { - lanes[i] = (lanes[i].*UnaryOp)(); + lanes[i] = Convert((lanes[i].*UnaryOp)()); } return Literal(lanes); } @@ -1885,6 +1891,27 @@ Literal Literal::negI32x4() const { Literal Literal::negI64x2() const { return unary<2, &Literal::getLanesI64x2, &Literal::neg>(*this); } +Literal Literal::absF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::abs, &toFP16>(*this); +} +Literal Literal::negF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::neg, &toFP16>(*this); +} +Literal Literal::sqrtF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::sqrt, &toFP16>(*this); +} +Literal Literal::ceilF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::ceil, &toFP16>(*this); +} +Literal Literal::floorF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::floor, &toFP16>(*this); +} +Literal Literal::truncF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::trunc, &toFP16>(*this); +} +Literal Literal::nearestF16x8() const { + return unary<8, &Literal::getLanesF16x8, &Literal::nearbyint, &toFP16>(*this); +} Literal Literal::absF32x4() const { return unary<4, &Literal::getLanesF32x4, &Literal::abs>(*this); } @@ -2271,11 +2298,6 @@ Literal Literal::geF64x2(const Literal& other) const { other); } -static Literal passThrough(const Literal& literal) { return literal; } -static Literal toFP16(const Literal& literal) { - return literal.convertF32ToF16(); -} - template (Literal::*IntoLanes)() const, Literal (Literal::*BinaryOp)(const Literal&) const, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 06d17fdfb9b..16a926182a4 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6439,6 +6439,34 @@ bool WasmBinaryReader::maybeVisitSIMDUnary(Expression*& out, uint32_t code) { curr = allocator.alloc(); curr->op = BitmaskVecI64x2; break; + case BinaryConsts::F16x8Abs: + curr = allocator.alloc(); + curr->op = AbsVecF16x8; + break; + case BinaryConsts::F16x8Neg: + curr = allocator.alloc(); + curr->op = NegVecF16x8; + break; + case BinaryConsts::F16x8Sqrt: + curr = allocator.alloc(); + curr->op = SqrtVecF16x8; + break; + case BinaryConsts::F16x8Ceil: + curr = allocator.alloc(); + curr->op = CeilVecF16x8; + break; + case BinaryConsts::F16x8Floor: + curr = allocator.alloc(); + curr->op = FloorVecF16x8; + break; + case BinaryConsts::F16x8Trunc: + curr = allocator.alloc(); + curr->op = TruncVecF16x8; + break; + case BinaryConsts::F16x8Nearest: + curr = allocator.alloc(); + curr->op = NearestVecF16x8; + break; case BinaryConsts::F32x4Abs: curr = allocator.alloc(); curr->op = AbsVecF32x4; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index b7bfea61718..59593ddde36 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1132,6 +1132,28 @@ void BinaryInstWriter::visitUnary(Unary* curr) { o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Bitmask); break; + case AbsVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Abs); + break; + case NegVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Neg); + break; + case SqrtVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Sqrt); + break; + case CeilVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Ceil); + break; + case FloorVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Floor); + break; + case TruncVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Trunc); + break; + case NearestVecF16x8: + o << int8_t(BinaryConsts::SIMDPrefix) + << U32LEB(BinaryConsts::F16x8Nearest); + break; case AbsVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Abs); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index f77eeefe78d..40726d7cd12 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2095,6 +2095,17 @@ void FunctionValidator::visitUnary(Unary* curr) { shouldBeEqual( curr->value->type, Type(Type::f64), curr, "expected f64 splat value"); break; + case AbsVecF16x8: + case NegVecF16x8: + case SqrtVecF16x8: + case CeilVecF16x8: + case FloorVecF16x8: + case TruncVecF16x8: + case NearestVecF16x8: + shouldBeTrue(getModule()->features.hasFP16(), + curr, + "FP16 operations require FP16 [--enable-fp16]"); + [[fallthrough]]; case NotVec128: case PopcntVecI8x16: case AbsVecI8x16: diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index e768f0dc498..98146dfbcc3 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -652,6 +652,13 @@ void Unary::finalize() { case NegVecI16x8: case NegVecI32x4: case NegVecI64x2: + case AbsVecF16x8: + case NegVecF16x8: + case SqrtVecF16x8: + case CeilVecF16x8: + case FloorVecF16x8: + case TruncVecF16x8: + case NearestVecF16x8: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4: diff --git a/test/lit/basic/f16.wast b/test/lit/basic/f16.wast index df3c0ef2d89..2e5ac57ddf2 100644 --- a/test/lit/basic/f16.wast +++ b/test/lit/basic/f16.wast @@ -15,38 +15,42 @@ ;; CHECK-TEXT: (type $0 (func (param v128 v128) (result v128))) - ;; CHECK-TEXT: (type $1 (func (param i32) (result f32))) + ;; CHECK-TEXT: (type $1 (func (param v128) (result v128))) - ;; CHECK-TEXT: (type $2 (func (param i32 f32))) + ;; CHECK-TEXT: (type $2 (func (param i32) (result f32))) - ;; CHECK-TEXT: (type $3 (func (param f32) (result v128))) + ;; CHECK-TEXT: (type $3 (func (param i32 f32))) - ;; CHECK-TEXT: (type $4 (func (param v128) (result f32))) + ;; CHECK-TEXT: (type $4 (func (param f32) (result v128))) - ;; CHECK-TEXT: (type $5 (func (param v128 f32) (result v128))) + ;; CHECK-TEXT: (type $5 (func (param v128) (result f32))) + + ;; CHECK-TEXT: (type $6 (func (param v128 f32) (result v128))) ;; CHECK-TEXT: (memory $0 1 1) - ;; CHECK-TEXT: (func $f32.load_f16 (type $1) (param $0 i32) (result f32) + ;; CHECK-TEXT: (func $f32.load_f16 (type $2) (param $0 i32) (result f32) ;; CHECK-TEXT-NEXT: (f32.load_f16 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $0 (func (param v128 v128) (result v128))) - ;; CHECK-BIN: (type $1 (func (param i32) (result f32))) + ;; CHECK-BIN: (type $1 (func (param v128) (result v128))) + + ;; CHECK-BIN: (type $2 (func (param i32) (result f32))) - ;; CHECK-BIN: (type $2 (func (param i32 f32))) + ;; CHECK-BIN: (type $3 (func (param i32 f32))) - ;; CHECK-BIN: (type $3 (func (param f32) (result v128))) + ;; CHECK-BIN: (type $4 (func (param f32) (result v128))) - ;; CHECK-BIN: (type $4 (func (param v128) (result f32))) + ;; CHECK-BIN: (type $5 (func (param v128) (result f32))) - ;; CHECK-BIN: (type $5 (func (param v128 f32) (result v128))) + ;; CHECK-BIN: (type $6 (func (param v128 f32) (result v128))) ;; CHECK-BIN: (memory $0 1 1) - ;; CHECK-BIN: (func $f32.load_f16 (type $1) (param $0 i32) (result f32) + ;; CHECK-BIN: (func $f32.load_f16 (type $2) (param $0 i32) (result f32) ;; CHECK-BIN-NEXT: (f32.load_f16 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -56,13 +60,13 @@ (local.get $0) ) ) - ;; CHECK-TEXT: (func $f32.store_f16 (type $2) (param $0 i32) (param $1 f32) + ;; CHECK-TEXT: (func $f32.store_f16 (type $3) (param $0 i32) (param $1 f32) ;; CHECK-TEXT-NEXT: (f32.store_f16 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f32.store_f16 (type $2) (param $0 i32) (param $1 f32) + ;; CHECK-BIN: (func $f32.store_f16 (type $3) (param $0 i32) (param $1 f32) ;; CHECK-BIN-NEXT: (f32.store_f16 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) @@ -75,12 +79,12 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.splat (type $3) (param $0 f32) (result v128) + ;; CHECK-TEXT: (func $f16x8.splat (type $4) (param $0 f32) (result v128) ;; CHECK-TEXT-NEXT: (f16x8.splat ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.splat (type $3) (param $0 f32) (result v128) + ;; CHECK-BIN: (func $f16x8.splat (type $4) (param $0 f32) (result v128) ;; CHECK-BIN-NEXT: (f16x8.splat ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -91,12 +95,12 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.extract_lane (type $4) (param $0 v128) (result f32) + ;; CHECK-TEXT: (func $f16x8.extract_lane (type $5) (param $0 v128) (result f32) ;; CHECK-TEXT-NEXT: (f16x8.extract_lane 0 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.extract_lane (type $4) (param $0 v128) (result f32) + ;; CHECK-BIN: (func $f16x8.extract_lane (type $5) (param $0 v128) (result f32) ;; CHECK-BIN-NEXT: (f16x8.extract_lane 0 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: ) @@ -107,13 +111,13 @@ ) ) - ;; CHECK-TEXT: (func $f16x8.replace_lane (type $5) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-TEXT: (func $f16x8.replace_lane (type $6) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-TEXT-NEXT: (f16x8.replace_lane 0 ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f16x8.replace_lane (type $5) (param $0 v128) (param $1 f32) (result v128) + ;; CHECK-BIN: (func $f16x8.replace_lane (type $6) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-BIN-NEXT: (f16x8.replace_lane 0 ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) @@ -377,47 +381,154 @@ (local.get $1) ) ) + ;; CHECK-TEXT: (func $f16x8.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.abs + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.abs (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.abs + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.abs (param $0 v128) (result v128) + (f16x8.abs + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.neg + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.neg (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.neg + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.neg (param $0 v128) (result v128) + (f16x8.neg + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.sqrt + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.sqrt (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.sqrt + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.sqrt (param $0 v128) (result v128) + (f16x8.sqrt + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.ceil + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.ceil (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.ceil + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.ceil (param $0 v128) (result v128) + (f16x8.ceil + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.floor + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.floor (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.floor + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.floor (param $0 v128) (result v128) + (f16x8.floor + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.trunc + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.trunc (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.trunc + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.trunc (param $0 v128) (result v128) + (f16x8.trunc + (local.get $0) + ) + ) + ;; CHECK-TEXT: (func $f16x8.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f16x8.nearest + ;; CHECK-TEXT-NEXT: (local.get $0) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-TEXT-NEXT: ) + ;; CHECK-BIN: (func $f16x8.nearest (type $1) (param $0 v128) (result v128) + ;; CHECK-BIN-NEXT: (f16x8.nearest + ;; CHECK-BIN-NEXT: (local.get $0) + ;; CHECK-BIN-NEXT: ) + ;; CHECK-BIN-NEXT: ) + (func $f16x8.nearest (param $0 v128) (result v128) + (f16x8.nearest + (local.get $0) + ) + ) ) ;; CHECK-BIN-NODEBUG: (type $0 (func (param v128 v128) (result v128))) -;; CHECK-BIN-NODEBUG: (type $1 (func (param i32) (result f32))) +;; CHECK-BIN-NODEBUG: (type $1 (func (param v128) (result v128))) -;; CHECK-BIN-NODEBUG: (type $2 (func (param i32 f32))) +;; CHECK-BIN-NODEBUG: (type $2 (func (param i32) (result f32))) -;; CHECK-BIN-NODEBUG: (type $3 (func (param f32) (result v128))) +;; CHECK-BIN-NODEBUG: (type $3 (func (param i32 f32))) -;; CHECK-BIN-NODEBUG: (type $4 (func (param v128) (result f32))) +;; CHECK-BIN-NODEBUG: (type $4 (func (param f32) (result v128))) -;; CHECK-BIN-NODEBUG: (type $5 (func (param v128 f32) (result v128))) +;; CHECK-BIN-NODEBUG: (type $5 (func (param v128) (result f32))) + +;; CHECK-BIN-NODEBUG: (type $6 (func (param v128 f32) (result v128))) ;; CHECK-BIN-NODEBUG: (memory $0 1 1) -;; CHECK-BIN-NODEBUG: (func $0 (type $1) (param $0 i32) (result f32) +;; CHECK-BIN-NODEBUG: (func $0 (type $2) (param $0 i32) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (f32.load_f16 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $1 (type $2) (param $0 i32) (param $1 f32) +;; CHECK-BIN-NODEBUG: (func $1 (type $3) (param $0 i32) (param $1 f32) ;; CHECK-BIN-NODEBUG-NEXT: (f32.store_f16 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $2 (type $3) (param $0 f32) (result v128) +;; CHECK-BIN-NODEBUG: (func $2 (type $4) (param $0 f32) (result v128) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.splat ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $3 (type $4) (param $0 v128) (result f32) +;; CHECK-BIN-NODEBUG: (func $3 (type $5) (param $0 v128) (result f32) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.extract_lane 0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG: (func $4 (type $5) (param $0 v128) (param $1 f32) (result v128) +;; CHECK-BIN-NODEBUG: (func $4 (type $6) (param $0 v128) (param $1 f32) (result v128) ;; CHECK-BIN-NODEBUG-NEXT: (f16x8.replace_lane 0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) @@ -521,3 +632,45 @@ ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $19 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.abs +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $20 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.neg +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $21 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.sqrt +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $22 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.ceil +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $23 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.floor +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $24 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.trunc +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) + +;; CHECK-BIN-NODEBUG: (func $25 (type $1) (param $0 v128) (result v128) +;; CHECK-BIN-NODEBUG-NEXT: (f16x8.nearest +;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) +;; CHECK-BIN-NODEBUG-NEXT: ) +;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/spec/f16.wast b/test/spec/f16.wast index 70d0043f7be..09ee9328b58 100644 --- a/test/spec/f16.wast +++ b/test/spec/f16.wast @@ -25,6 +25,13 @@ (func (export "f16x8.max") (param $0 v128) (param $1 v128) (result v128) (f16x8.max (local.get $0) (local.get $1))) (func (export "f16x8.pmin") (param $0 v128) (param $1 v128) (result v128) (f16x8.pmin (local.get $0) (local.get $1))) (func (export "f16x8.pmax") (param $0 v128) (param $1 v128) (result v128) (f16x8.pmax (local.get $0) (local.get $1))) + (func (export "f16x8.abs") (param $0 v128) (result v128) (f16x8.abs (local.get $0))) + (func (export "f16x8.neg") (param $0 v128) (result v128) (f16x8.neg (local.get $0))) + (func (export "f16x8.sqrt") (param $0 v128) (result v128) (f16x8.sqrt (local.get $0))) + (func (export "f16x8.ceil") (param $0 v128) (result v128) (f16x8.ceil (local.get $0))) + (func (export "f16x8.floor") (param $0 v128) (result v128) (f16x8.floor (local.get $0))) + (func (export "f16x8.trunc") (param $0 v128) (result v128) (f16x8.trunc (local.get $0))) + (func (export "f16x8.nearest") (param $0 v128) (result v128) (f16x8.nearest (local.get $0))) ) (assert_return (invoke "f32.load_f16") (f32.const 42.0)) @@ -147,3 +154,36 @@ (v128.const i16x8 0x5140 0xfe00 0x7c00 0x3e00 0 0x3c00 0 0x3c00)) ;; nan -nan inf 1.5 0 1 1 1 (v128.const i16x8 0x7e00 0xfe00 0x7c00 0x3e00 0 0x3c00 0x3c00 0x3c00)) + +;; unary arithmetic +(assert_return (invoke "f16x8.abs" + ;; nan -nan inf -inf -1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0xfc00 0xbc00 0x3c00 0x3e00 0x3ccd)) + ;; nan nan inf inf 1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0x7e00 0x7c00 0x7c00 0x3c00 0x3c00 0x3e00 0x3ccd)) +(assert_return (invoke "f16x8.neg" + ;; nan -nan inf -inf -1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0xfe00 0x7c00 0xfc00 0xbc00 0x3c00 0x3e00 0x3ccd)) + ;; -nan nan -inf inf 1 -1 -1.5 -1.2... + (v128.const i16x8 0xfe00 0x7e00 0xfc00 0x7c00 0x3c00 0xbc00 0xbe00 0xbccd)) +;; XXX Avoid tests that return -nan since it's non-deterministic. +(assert_return (invoke "f16x8.sqrt" + ;; nan 0 inf 4 16 1 1.5 1.2... + (v128.const i16x8 0x7e00 0 0x7c00 0x4400 0x4c00 0x3c00 0x3e00 0x3ccd)) + ;; nan 0 inf 2 4 1 1.22.. 1.09... + (v128.const i16x8 0x7e00 0 0x7c00 0x4000 0x4400 0x3c00 0x3ce6 0x3c62)) +(assert_return (invoke "f16x8.ceil" + ;; nan 0 inf -inf -1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x3e00 0x3ccd)) + ;; nan 0 inf -inf -1 1 2 2 + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x4000 0x4000)) +(assert_return (invoke "f16x8.floor" + ;; nan 0 inf -inf -1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x3e00 0x3ccd)) + ;; nan 0 inf -inf -1 1 1 1 + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x3c00 0x3c00)) +(assert_return (invoke "f16x8.nearest" + ;; nan 0 inf -inf -1 1 1.5 1.2... + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x3e00 0x3ccd)) + ;; nan 0 inf -inf -1 1 2 1 + (v128.const i16x8 0x7e00 0 0x7c00 0xfc00 0xbc00 0x3c00 0x4000 0x3c00)) From 52118e536238c10f6873390a6ca475a44350bc71 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 27 Aug 2024 12:50:07 -0700 Subject: [PATCH 546/553] Check for required actions when parsing wast (#6874) The parser function for `action` returned a `MaybeResult`, but we were treating it as returning a normal `Result` and not checking that it had contents in several places. Replace the current `action()` with `maybeAction()` and add a new `action()` that requires the action to be present. Fixes #6872. --- src/parser/wast-parser.cpp | 14 +++++++++++--- test/lit/parse-bad-assertion.wast | 8 ++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test/lit/parse-bad-assertion.wast diff --git a/src/parser/wast-parser.cpp b/src/parser/wast-parser.cpp index 5eaf352b739..0f7887f8fe2 100644 --- a/src/parser/wast-parser.cpp +++ b/src/parser/wast-parser.cpp @@ -49,7 +49,7 @@ Result consts(Lexer& in) { return lits; } -MaybeResult action(Lexer& in) { +MaybeResult maybeAction(Lexer& in) { if (in.takeSExprStart("invoke"sv)) { auto id = in.takeID(); auto name = in.takeName(); @@ -79,6 +79,14 @@ MaybeResult action(Lexer& in) { return {}; } +Result action(Lexer& in) { + if (auto a = maybeAction(in)) { + CHECK_ERR(a); + return *a; + } + return in.err("expected action"); +} + // (module id? binary string*) // (module id? quote string*) // (module ...) @@ -348,7 +356,7 @@ MaybeResult assertTrap(Lexer& in) { return {}; } auto pos = in.getPos(); - if (auto a = action(in)) { + if (auto a = maybeAction(in)) { CHECK_ERR(a); auto msg = in.takeString(); if (!msg) { @@ -423,7 +431,7 @@ Result command(Lexer& in) { CHECK_ERR(cmd); return *cmd; } - if (auto cmd = action(in)) { + if (auto cmd = maybeAction(in)) { CHECK_ERR(cmd); return *cmd; } diff --git a/test/lit/parse-bad-assertion.wast b/test/lit/parse-bad-assertion.wast new file mode 100644 index 00000000000..9e6c7ac7fad --- /dev/null +++ b/test/lit/parse-bad-assertion.wast @@ -0,0 +1,8 @@ +;; Check that we properly error when an action is missing from an assertion that +;; requires one. Regression test for #6872. + +;; RUN: not wasm-shell %s 2>&1 | filecheck %s + +(assert_exhaustion "wrong, lol") + +;; CHECK: 6:19: error: expected action From e2ceaa58c10e9ee3e9eece42466243f5a8aff125 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 27 Aug 2024 13:07:49 -0700 Subject: [PATCH 547/553] Rename relaxed SIMD fma instructions to match spec. (#6876) The instructions relaxed_fma and relaxed_fnma have been renamed to relaxed_madd and relaxed_nmadd. https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md#binary-format --- CHANGELOG.md | 2 + scripts/gen-s-parser.py | 8 +-- src/binaryen-c.cpp | 8 +-- src/binaryen-c.h | 8 +-- src/gen-s-parser.inc | 88 ++++++++++++++--------------- src/ir/cost.h | 8 +-- src/js/binaryen.js-post.js | 8 +-- src/literal.h | 12 ++-- src/passes/Print.cpp | 16 +++--- src/wasm-binary.h | 8 +-- src/wasm-interpreter.h | 16 +++--- src/wasm.h | 8 +-- src/wasm/literal.cpp | 32 ++++++----- src/wasm/wasm-binary.cpp | 16 +++--- src/wasm/wasm-stack.cpp | 16 +++--- test/example/c-api-kitchen-sink.c | 8 +-- test/example/c-api-kitchen-sink.txt | 8 +-- test/lit/basic/relaxed-simd.wast | 56 +++++++++--------- 18 files changed, 166 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c4e369c9bb..24ce7693f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ Current Trunk passes). (#6713) - A C APIs for getting/setting the type of Functions (#6721). - Allow using `--skip-pass` on the commandline multiple times (#6714). + - The instructions relaxed_fma and relaxed_fnma have been renamed to + relaxed_madd and relaxed_nmadd. v118 ---- diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 49fa6afb63b..0b5703b9e1f 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -547,10 +547,10 @@ ("i32x4.relaxed_trunc_f32x4_u", "makeUnary(UnaryOp::RelaxedTruncUVecF32x4ToVecI32x4)"), ("i32x4.relaxed_trunc_f64x2_s_zero", "makeUnary(UnaryOp::RelaxedTruncZeroSVecF64x2ToVecI32x4)"), ("i32x4.relaxed_trunc_f64x2_u_zero", "makeUnary(UnaryOp::RelaxedTruncZeroUVecF64x2ToVecI32x4)"), - ("f32x4.relaxed_fma", "makeSIMDTernary(SIMDTernaryOp::RelaxedFmaVecF32x4)"), - ("f32x4.relaxed_fms", "makeSIMDTernary(SIMDTernaryOp::RelaxedFmsVecF32x4)"), - ("f64x2.relaxed_fma", "makeSIMDTernary(SIMDTernaryOp::RelaxedFmaVecF64x2)"), - ("f64x2.relaxed_fms", "makeSIMDTernary(SIMDTernaryOp::RelaxedFmsVecF64x2)"), + ("f32x4.relaxed_madd", "makeSIMDTernary(SIMDTernaryOp::RelaxedMaddVecF32x4)"), + ("f32x4.relaxed_nmadd", "makeSIMDTernary(SIMDTernaryOp::RelaxedNmaddVecF32x4)"), + ("f64x2.relaxed_madd", "makeSIMDTernary(SIMDTernaryOp::RelaxedMaddVecF64x2)"), + ("f64x2.relaxed_nmadd", "makeSIMDTernary(SIMDTernaryOp::RelaxedNmaddVecF64x2)"), ("i8x16.laneselect", "makeSIMDTernary(SIMDTernaryOp::LaneselectI8x16)"), ("i16x8.laneselect", "makeSIMDTernary(SIMDTernaryOp::LaneselectI16x8)"), ("i32x4.laneselect", "makeSIMDTernary(SIMDTernaryOp::LaneselectI32x4)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index afc3dbe5414..31378ce22de 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -755,10 +755,10 @@ BinaryenOp BinaryenOrVec128(void) { return OrVec128; } BinaryenOp BinaryenXorVec128(void) { return XorVec128; } BinaryenOp BinaryenAndNotVec128(void) { return AndNotVec128; } BinaryenOp BinaryenBitselectVec128(void) { return Bitselect; } -BinaryenOp BinaryenRelaxedFmaVecF32x4(void) { return RelaxedFmaVecF32x4; } -BinaryenOp BinaryenRelaxedFmsVecF32x4(void) { return RelaxedFmsVecF32x4; } -BinaryenOp BinaryenRelaxedFmaVecF64x2(void) { return RelaxedFmaVecF64x2; } -BinaryenOp BinaryenRelaxedFmsVecF64x2(void) { return RelaxedFmsVecF64x2; } +BinaryenOp BinaryenRelaxedMaddVecF32x4(void) { return RelaxedMaddVecF32x4; } +BinaryenOp BinaryenRelaxedNmaddVecF32x4(void) { return RelaxedNmaddVecF32x4; } +BinaryenOp BinaryenRelaxedMaddVecF64x2(void) { return RelaxedMaddVecF64x2; } +BinaryenOp BinaryenRelaxedNmaddVecF64x2(void) { return RelaxedNmaddVecF64x2; } BinaryenOp BinaryenLaneselectI8x16(void) { return LaneselectI8x16; } BinaryenOp BinaryenLaneselectI16x8(void) { return LaneselectI16x8; } BinaryenOp BinaryenLaneselectI32x4(void) { return LaneselectI32x4; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 0b1319f3024..b23945d1839 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -497,10 +497,10 @@ BINARYEN_API BinaryenOp BinaryenOrVec128(void); BINARYEN_API BinaryenOp BinaryenXorVec128(void); BINARYEN_API BinaryenOp BinaryenAndNotVec128(void); BINARYEN_API BinaryenOp BinaryenBitselectVec128(void); -BINARYEN_API BinaryenOp BinaryenRelaxedFmaVecF32x4(void); -BINARYEN_API BinaryenOp BinaryenRelaxedFmsVecF32x4(void); -BINARYEN_API BinaryenOp BinaryenRelaxedFmaVecF64x2(void); -BINARYEN_API BinaryenOp BinaryenRelaxedFmsVecF64x2(void); +BINARYEN_API BinaryenOp BinaryenRelaxedMaddVecF32x4(void); +BINARYEN_API BinaryenOp BinaryenRelaxedNmaddVecF32x4(void); +BINARYEN_API BinaryenOp BinaryenRelaxedMaddVecF64x2(void); +BINARYEN_API BinaryenOp BinaryenRelaxedNmaddVecF64x2(void); BINARYEN_API BinaryenOp BinaryenLaneselectI8x16(void); BINARYEN_API BinaryenOp BinaryenLaneselectI16x8(void); BINARYEN_API BinaryenOp BinaryenLaneselectI32x4(void); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 7d4fbe81914..56a7c1cce83 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -952,31 +952,25 @@ switch (buf[0]) { switch (buf[8]) { case 'l': { switch (buf[14]) { - case 'f': { - switch (buf[16]) { - case 'a': - if (op == "f32x4.relaxed_fma"sv) { - CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedFmaVecF32x4)); - return Ok{}; - } - goto parse_error; - case 's': - if (op == "f32x4.relaxed_fms"sv) { - CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedFmsVecF32x4)); - return Ok{}; - } - goto parse_error; - default: goto parse_error; - } - } case 'm': { switch (buf[15]) { - case 'a': - if (op == "f32x4.relaxed_max"sv) { - CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMaxVecF32x4)); - return Ok{}; + case 'a': { + switch (buf[16]) { + case 'd': + if (op == "f32x4.relaxed_madd"sv) { + CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedMaddVecF32x4)); + return Ok{}; + } + goto parse_error; + case 'x': + if (op == "f32x4.relaxed_max"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMaxVecF32x4)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 'i': if (op == "f32x4.relaxed_min"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMinVecF32x4)); @@ -986,6 +980,12 @@ switch (buf[0]) { default: goto parse_error; } } + case 'n': + if (op == "f32x4.relaxed_nmadd"sv) { + CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedNmaddVecF32x4)); + return Ok{}; + } + goto parse_error; default: goto parse_error; } } @@ -1462,31 +1462,25 @@ switch (buf[0]) { switch (buf[8]) { case 'l': { switch (buf[14]) { - case 'f': { - switch (buf[16]) { - case 'a': - if (op == "f64x2.relaxed_fma"sv) { - CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedFmaVecF64x2)); - return Ok{}; - } - goto parse_error; - case 's': - if (op == "f64x2.relaxed_fms"sv) { - CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedFmsVecF64x2)); - return Ok{}; - } - goto parse_error; - default: goto parse_error; - } - } case 'm': { switch (buf[15]) { - case 'a': - if (op == "f64x2.relaxed_max"sv) { - CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMaxVecF64x2)); - return Ok{}; + case 'a': { + switch (buf[16]) { + case 'd': + if (op == "f64x2.relaxed_madd"sv) { + CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedMaddVecF64x2)); + return Ok{}; + } + goto parse_error; + case 'x': + if (op == "f64x2.relaxed_max"sv) { + CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMaxVecF64x2)); + return Ok{}; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } case 'i': if (op == "f64x2.relaxed_min"sv) { CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::RelaxedMinVecF64x2)); @@ -1496,6 +1490,12 @@ switch (buf[0]) { default: goto parse_error; } } + case 'n': + if (op == "f64x2.relaxed_nmadd"sv) { + CHECK_ERR(makeSIMDTernary(ctx, pos, annotations, SIMDTernaryOp::RelaxedNmaddVecF64x2)); + return Ok{}; + } + goto parse_error; default: goto parse_error; } } diff --git a/src/ir/cost.h b/src/ir/cost.h index f541a450658..99b945815e5 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -582,10 +582,10 @@ struct CostAnalyzer : public OverriddenVisitor { case LaneselectI16x8: case LaneselectI32x4: case LaneselectI64x2: - case RelaxedFmaVecF32x4: - case RelaxedFmsVecF32x4: - case RelaxedFmaVecF64x2: - case RelaxedFmsVecF64x2: + case RelaxedMaddVecF32x4: + case RelaxedNmaddVecF32x4: + case RelaxedMaddVecF64x2: + case RelaxedNmaddVecF64x2: case DotI8x16I7x16AddSToVecI32x4: ret = 1; break; diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 55e1a7ad7b3..40d08dceb55 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -383,10 +383,10 @@ function initializeConstants() { 'XorVec128', 'AndNotVec128', 'BitselectVec128', - 'RelaxedFmaVecF32x4', - 'RelaxedFmsVecF32x4', - 'RelaxedFmaVecF64x2', - 'RelaxedFmsVecF64x2', + 'RelaxedMaddVecF32x4', + 'RelaxedNmaddVecF32x4', + 'RelaxedMaddVecF64x2', + 'RelaxedNmaddVecF64x2', 'LaneselectI8x16', 'LaneselectI16x8', 'LaneselectI32x4', diff --git a/src/literal.h b/src/literal.h index 7bedab5b400..73289c83ba2 100644 --- a/src/literal.h +++ b/src/literal.h @@ -442,8 +442,8 @@ class Literal { // Fused multiply add and subtract. // Computes this + (left * right) to infinite precision then round once. - Literal fma(const Literal& left, const Literal& right) const; - Literal fms(const Literal& left, const Literal& right) const; + Literal madd(const Literal& left, const Literal& right) const; + Literal nmadd(const Literal& left, const Literal& right) const; std::array getLanesSI8x16() const; std::array getLanesUI8x16() const; @@ -694,10 +694,10 @@ class Literal { Literal demoteZeroToF32x4() const; Literal promoteLowToF64x2() const; Literal swizzleI8x16(const Literal& other) const; - Literal relaxedFmaF32x4(const Literal& left, const Literal& right) const; - Literal relaxedFmsF32x4(const Literal& left, const Literal& right) const; - Literal relaxedFmaF64x2(const Literal& left, const Literal& right) const; - Literal relaxedFmsF64x2(const Literal& left, const Literal& right) const; + Literal relaxedMaddF32x4(const Literal& left, const Literal& right) const; + Literal relaxedNmaddF32x4(const Literal& left, const Literal& right) const; + Literal relaxedMaddF64x2(const Literal& left, const Literal& right) const; + Literal relaxedNmaddF64x2(const Literal& left, const Literal& right) const; Literal externalize() const; Literal internalize() const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 8f53481b70d..024b6af5c46 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -770,17 +770,17 @@ struct PrintExpressionContents case LaneselectI64x2: o << "i64x2.laneselect"; break; - case RelaxedFmaVecF32x4: - o << "f32x4.relaxed_fma"; + case RelaxedMaddVecF32x4: + o << "f32x4.relaxed_madd"; break; - case RelaxedFmsVecF32x4: - o << "f32x4.relaxed_fms"; + case RelaxedNmaddVecF32x4: + o << "f32x4.relaxed_nmadd"; break; - case RelaxedFmaVecF64x2: - o << "f64x2.relaxed_fma"; + case RelaxedMaddVecF64x2: + o << "f64x2.relaxed_madd"; break; - case RelaxedFmsVecF64x2: - o << "f64x2.relaxed_fms"; + case RelaxedNmaddVecF64x2: + o << "f64x2.relaxed_nmadd"; break; case DotI8x16I7x16AddSToVecI32x4: o << "i32x4.dot_i8x16_i7x16_add_s"; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9ce355b48a1..e8ed293e7fd 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1037,10 +1037,10 @@ enum ASTNodes { I32x4RelaxedTruncF32x4U = 0x102, I32x4RelaxedTruncF64x2SZero = 0x103, I32x4RelaxedTruncF64x2UZero = 0x104, - F32x4RelaxedFma = 0x105, - F32x4RelaxedFms = 0x106, - F64x2RelaxedFma = 0x107, - F64x2RelaxedFms = 0x108, + F32x4RelaxedMadd = 0x105, + F32x4RelaxedNmadd = 0x106, + F64x2RelaxedMadd = 0x107, + F64x2RelaxedNmadd = 0x108, I8x16Laneselect = 0x109, I16x8Laneselect = 0x10a, I32x4Laneselect = 0x10b, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 50fc296fe3d..578b0a56940 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1201,14 +1201,14 @@ class ExpressionRunner : public OverriddenVisitor { case LaneselectI64x2: return c.bitselectV128(a, b); - case RelaxedFmaVecF32x4: - return a.relaxedFmaF32x4(b, c); - case RelaxedFmsVecF32x4: - return a.relaxedFmsF32x4(b, c); - case RelaxedFmaVecF64x2: - return a.relaxedFmaF64x2(b, c); - case RelaxedFmsVecF64x2: - return a.relaxedFmsF64x2(b, c); + case RelaxedMaddVecF32x4: + return a.relaxedMaddF32x4(b, c); + case RelaxedNmaddVecF32x4: + return a.relaxedNmaddF32x4(b, c); + case RelaxedMaddVecF64x2: + return a.relaxedMaddF64x2(b, c); + case RelaxedNmaddVecF64x2: + return a.relaxedNmaddF64x2(b, c); default: // TODO: implement signselect and dot_add WASM_UNREACHABLE("not implemented"); diff --git a/src/wasm.h b/src/wasm.h index a707ab7a4b1..86ee1297224 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -574,10 +574,10 @@ enum SIMDTernaryOp { Bitselect, // Relaxed SIMD - RelaxedFmaVecF32x4, - RelaxedFmsVecF32x4, - RelaxedFmaVecF64x2, - RelaxedFmsVecF64x2, + RelaxedMaddVecF32x4, + RelaxedNmaddVecF32x4, + RelaxedMaddVecF64x2, + RelaxedNmaddVecF64x2, LaneselectI8x16, LaneselectI16x8, LaneselectI32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 1b84ba53c02..c76856d152f 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -1671,7 +1671,7 @@ Literal Literal::copysign(const Literal& other) const { } } -Literal Literal::fma(const Literal& left, const Literal& right) const { +Literal Literal::madd(const Literal& left, const Literal& right) const { switch (type.getBasic()) { case Type::f32: return Literal(::fmaf(left.getf32(), right.getf32(), getf32())); @@ -1684,7 +1684,7 @@ Literal Literal::fma(const Literal& left, const Literal& right) const { } } -Literal Literal::fms(const Literal& left, const Literal& right) const { +Literal Literal::nmadd(const Literal& left, const Literal& right) const { switch (type.getBasic()) { case Type::f32: return Literal(::fmaf(-left.getf32(), right.getf32(), getf32())); @@ -2762,24 +2762,28 @@ static Literal ternary(const Literal& a, const Literal& b, const Literal& c) { } } // namespace -Literal Literal::relaxedFmaF32x4(const Literal& left, - const Literal& right) const { - return ternary<4, &Literal::getLanesF32x4, &Literal::fma>(*this, left, right); +Literal Literal::relaxedMaddF32x4(const Literal& left, + const Literal& right) const { + return ternary<4, &Literal::getLanesF32x4, &Literal::madd>( + *this, left, right); } -Literal Literal::relaxedFmsF32x4(const Literal& left, - const Literal& right) const { - return ternary<4, &Literal::getLanesF32x4, &Literal::fms>(*this, left, right); +Literal Literal::relaxedNmaddF32x4(const Literal& left, + const Literal& right) const { + return ternary<4, &Literal::getLanesF32x4, &Literal::nmadd>( + *this, left, right); } -Literal Literal::relaxedFmaF64x2(const Literal& left, - const Literal& right) const { - return ternary<2, &Literal::getLanesF64x2, &Literal::fma>(*this, left, right); +Literal Literal::relaxedMaddF64x2(const Literal& left, + const Literal& right) const { + return ternary<2, &Literal::getLanesF64x2, &Literal::madd>( + *this, left, right); } -Literal Literal::relaxedFmsF64x2(const Literal& left, - const Literal& right) const { - return ternary<2, &Literal::getLanesF64x2, &Literal::fms>(*this, left, right); +Literal Literal::relaxedNmaddF64x2(const Literal& left, + const Literal& right) const { + return ternary<2, &Literal::getLanesF64x2, &Literal::nmadd>( + *this, left, right); } Literal Literal::externalize() const { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 16a926182a4..8c684dc2f04 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6823,21 +6823,21 @@ bool WasmBinaryReader::maybeVisitSIMDTernary(Expression*& out, uint32_t code) { curr = allocator.alloc(); curr->op = LaneselectI64x2; break; - case BinaryConsts::F32x4RelaxedFma: + case BinaryConsts::F32x4RelaxedMadd: curr = allocator.alloc(); - curr->op = RelaxedFmaVecF32x4; + curr->op = RelaxedMaddVecF32x4; break; - case BinaryConsts::F32x4RelaxedFms: + case BinaryConsts::F32x4RelaxedNmadd: curr = allocator.alloc(); - curr->op = RelaxedFmsVecF32x4; + curr->op = RelaxedNmaddVecF32x4; break; - case BinaryConsts::F64x2RelaxedFma: + case BinaryConsts::F64x2RelaxedMadd: curr = allocator.alloc(); - curr->op = RelaxedFmaVecF64x2; + curr->op = RelaxedMaddVecF64x2; break; - case BinaryConsts::F64x2RelaxedFms: + case BinaryConsts::F64x2RelaxedNmadd: curr = allocator.alloc(); - curr->op = RelaxedFmsVecF64x2; + curr->op = RelaxedNmaddVecF64x2; break; case BinaryConsts::I32x4DotI8x16I7x16AddS: curr = allocator.alloc(); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 59593ddde36..140205b8518 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -657,17 +657,17 @@ void BinaryInstWriter::visitSIMDTernary(SIMDTernary* curr) { case LaneselectI64x2: o << U32LEB(BinaryConsts::I64x2Laneselect); break; - case RelaxedFmaVecF32x4: - o << U32LEB(BinaryConsts::F32x4RelaxedFma); + case RelaxedMaddVecF32x4: + o << U32LEB(BinaryConsts::F32x4RelaxedMadd); break; - case RelaxedFmsVecF32x4: - o << U32LEB(BinaryConsts::F32x4RelaxedFms); + case RelaxedNmaddVecF32x4: + o << U32LEB(BinaryConsts::F32x4RelaxedNmadd); break; - case RelaxedFmaVecF64x2: - o << U32LEB(BinaryConsts::F64x2RelaxedFma); + case RelaxedMaddVecF64x2: + o << U32LEB(BinaryConsts::F64x2RelaxedMadd); break; - case RelaxedFmsVecF64x2: - o << U32LEB(BinaryConsts::F64x2RelaxedFms); + case RelaxedNmaddVecF64x2: + o << U32LEB(BinaryConsts::F64x2RelaxedNmadd); break; case DotI8x16I7x16AddSToVecI32x4: o << U32LEB(BinaryConsts::I32x4DotI8x16I7x16AddS); diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 802789173de..d3f20e888f2 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -956,10 +956,10 @@ void test_core() { // Other SIMD makeSIMDShuffle(module), makeSIMDTernary(module, BinaryenBitselectVec128()), - makeSIMDTernary(module, BinaryenRelaxedFmaVecF32x4()), - makeSIMDTernary(module, BinaryenRelaxedFmsVecF32x4()), - makeSIMDTernary(module, BinaryenRelaxedFmaVecF64x2()), - makeSIMDTernary(module, BinaryenRelaxedFmsVecF64x2()), + makeSIMDTernary(module, BinaryenRelaxedMaddVecF32x4()), + makeSIMDTernary(module, BinaryenRelaxedNmaddVecF32x4()), + makeSIMDTernary(module, BinaryenRelaxedMaddVecF64x2()), + makeSIMDTernary(module, BinaryenRelaxedNmaddVecF64x2()), makeSIMDTernary(module, BinaryenLaneselectI8x16()), makeSIMDTernary(module, BinaryenLaneselectI16x8()), makeSIMDTernary(module, BinaryenLaneselectI32x4()), diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 17344ccab13..f1271f5479d 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1884,28 +1884,28 @@ BinaryenFeatureAll: 524287 ) ) (drop - (f32x4.relaxed_fma + (f32x4.relaxed_madd (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop - (f32x4.relaxed_fms + (f32x4.relaxed_nmadd (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop - (f64x2.relaxed_fma + (f64x2.relaxed_madd (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop - (f64x2.relaxed_fms + (f64x2.relaxed_nmadd (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) diff --git a/test/lit/basic/relaxed-simd.wast b/test/lit/basic/relaxed-simd.wast index 0024d5b93ab..1624d18b4d8 100644 --- a/test/lit/basic/relaxed-simd.wast +++ b/test/lit/basic/relaxed-simd.wast @@ -111,88 +111,88 @@ ) ) - ;; CHECK-TEXT: (func $f32x4.relaxed_fma (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-TEXT-NEXT: (f32x4.relaxed_fma + ;; CHECK-TEXT: (func $f32x4.relaxed_madd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.relaxed_madd ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: (local.get $2) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f32x4.relaxed_fma (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-BIN-NEXT: (f32x4.relaxed_fma + ;; CHECK-BIN: (func $f32x4.relaxed_madd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.relaxed_madd ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) ;; CHECK-BIN-NEXT: (local.get $2) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $f32x4.relaxed_fma (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (f32x4.relaxed_fma + (func $f32x4.relaxed_madd (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + (f32x4.relaxed_madd (local.get $0) (local.get $1) (local.get $2) ) ) - ;; CHECK-TEXT: (func $f32x4.relaxed_fms (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-TEXT-NEXT: (f32x4.relaxed_fms + ;; CHECK-TEXT: (func $f32x4.relaxed_nmadd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f32x4.relaxed_nmadd ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: (local.get $2) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f32x4.relaxed_fms (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-BIN-NEXT: (f32x4.relaxed_fms + ;; CHECK-BIN: (func $f32x4.relaxed_nmadd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-BIN-NEXT: (f32x4.relaxed_nmadd ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) ;; CHECK-BIN-NEXT: (local.get $2) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $f32x4.relaxed_fms (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (f32x4.relaxed_fms + (func $f32x4.relaxed_nmadd (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + (f32x4.relaxed_nmadd (local.get $0) (local.get $1) (local.get $2) ) ) - ;; CHECK-TEXT: (func $f64x2.relaxed_fma (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-TEXT-NEXT: (f64x2.relaxed_fma + ;; CHECK-TEXT: (func $f64x2.relaxed_madd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.relaxed_madd ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: (local.get $2) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f64x2.relaxed_fma (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-BIN-NEXT: (f64x2.relaxed_fma + ;; CHECK-BIN: (func $f64x2.relaxed_madd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.relaxed_madd ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) ;; CHECK-BIN-NEXT: (local.get $2) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $f64x2.relaxed_fma (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (f64x2.relaxed_fma + (func $f64x2.relaxed_madd (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + (f64x2.relaxed_madd (local.get $0) (local.get $1) (local.get $2) ) ) - ;; CHECK-TEXT: (func $f64x2.relaxed_fms (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-TEXT-NEXT: (f64x2.relaxed_fms + ;; CHECK-TEXT: (func $f64x2.relaxed_nmadd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-TEXT-NEXT: (f64x2.relaxed_nmadd ;; CHECK-TEXT-NEXT: (local.get $0) ;; CHECK-TEXT-NEXT: (local.get $1) ;; CHECK-TEXT-NEXT: (local.get $2) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $f64x2.relaxed_fms (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - ;; CHECK-BIN-NEXT: (f64x2.relaxed_fms + ;; CHECK-BIN: (func $f64x2.relaxed_nmadd (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK-BIN-NEXT: (f64x2.relaxed_nmadd ;; CHECK-BIN-NEXT: (local.get $0) ;; CHECK-BIN-NEXT: (local.get $1) ;; CHECK-BIN-NEXT: (local.get $2) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) - (func $f64x2.relaxed_fms (param $0 v128) (param $1 v128) (param $2 v128) (result v128) - (f64x2.relaxed_fms + (func $f64x2.relaxed_nmadd (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + (f64x2.relaxed_nmadd (local.get $0) (local.get $1) (local.get $2) @@ -463,7 +463,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $5 (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) -;; CHECK-BIN-NODEBUG-NEXT: (f32x4.relaxed_fma +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.relaxed_madd ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) @@ -471,7 +471,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $6 (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) -;; CHECK-BIN-NODEBUG-NEXT: (f32x4.relaxed_fms +;; CHECK-BIN-NODEBUG-NEXT: (f32x4.relaxed_nmadd ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) @@ -479,7 +479,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $7 (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) -;; CHECK-BIN-NODEBUG-NEXT: (f64x2.relaxed_fma +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.relaxed_madd ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) @@ -487,7 +487,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $8 (type $0) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) -;; CHECK-BIN-NODEBUG-NEXT: (f64x2.relaxed_fms +;; CHECK-BIN-NODEBUG-NEXT: (f64x2.relaxed_nmadd ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: (local.get $2) From 95ddd057424b996a0a2a54f282c6c567246d8cc9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 28 Aug 2024 09:13:33 -0700 Subject: [PATCH 548/553] [NFC] Refactor LocalGraph's core getSets API (#6877) Before we just had a map that people would access with localGraph.getSetses[get], while now it is a call localGraph.getSets(get), which more nicely hides the internal implementation details. Also rename getSetses => getSetsMap. This will allow a later PR to optimize the internals of this API. This is performance-neutral as far as I can measure. (We do replace a direct read from a data structure with a call, but the call is in a header and should always get inlined.) --- .../reaching-definitions-transfer-function.h | 10 ++-- src/ir/LocalGraph.cpp | 26 +++++----- src/ir/local-graph.h | 47 ++++++++++++------- src/ir/possible-contents.cpp | 9 +++- src/passes/AvoidReinterprets.cpp | 2 +- src/passes/Heap2Local.cpp | 4 +- src/passes/LoopInvariantCodeMotion.cpp | 2 +- src/passes/MergeLocals.cpp | 14 +++--- src/passes/OptimizeAddedConstants.cpp | 2 +- src/passes/Precompute.cpp | 2 +- src/passes/SSAify.cpp | 4 +- src/tools/wasm-fuzz-lattices.cpp | 4 +- src/wasm/wasm-stack-opts.cpp | 2 +- test/gtest/cfg.cpp | 24 +++++----- 14 files changed, 84 insertions(+), 68 deletions(-) diff --git a/src/analysis/reaching-definitions-transfer-function.h b/src/analysis/reaching-definitions-transfer-function.h index dcf04e377b2..7a4fe1afcbe 100644 --- a/src/analysis/reaching-definitions-transfer-function.h +++ b/src/analysis/reaching-definitions-transfer-function.h @@ -42,7 +42,7 @@ class ReachingDefinitionsTransferFunction std::unordered_map> indexSetses; // LocalGraph members we need to update. - LocalGraph::GetSetses& getSetses; + LocalGraph::GetSetsMap& getSetsMap; // Fictitious LocalSet objects to reprsent a local index obtaining its value // from its default initial value or parameter value. @@ -86,9 +86,9 @@ class ReachingDefinitionsTransferFunction // are working with doesn't contain the correct Expression**s, but this is // left in for future improvements. TODO. ReachingDefinitionsTransferFunction(Function* func, - LocalGraph::GetSetses& getSetses, + LocalGraph::GetSetsMap& getSetsMap, LocalGraph::Locations& locations) - : numLocals(func->getNumLocals()), getSetses(getSetses), + : numLocals(func->getNumLocals()), getSetsMap(getSetsMap), lattice(listLocalSets(func, fakeInitialValueSets, fakeSetPtrs)) { // Map every local index to a set of all the local sets which affect it. @@ -129,9 +129,9 @@ class ReachingDefinitionsTransferFunction if (lattice.exists(currState, setInstance)) { // If a pointer to a real LocalSet, add it, otherwise add a nullptr. if (fakeSetPtrs.find(setInstance) == fakeSetPtrs.end()) { - getSetses[curr].insert(setInstance); + getSetsMap[curr].insert(setInstance); } else { - getSetses[curr].insert(nullptr); + getSetsMap[curr].insert(nullptr); } } } diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp index beef635b1c2..e1876f6d2c3 100644 --- a/src/ir/LocalGraph.cpp +++ b/src/ir/LocalGraph.cpp @@ -40,14 +40,14 @@ struct Info { // flow helper class. flows the gets to their sets struct Flower : public CFGWalker, Info> { - LocalGraph::GetSetses& getSetses; + LocalGraph::GetSetsMap& getSetsMap; LocalGraph::Locations& locations; - Flower(LocalGraph::GetSetses& getSetses, + Flower(LocalGraph::GetSetsMap& getSetsMap, LocalGraph::Locations& locations, Function* func, Module* module) - : getSetses(getSetses), locations(locations) { + : getSetsMap(getSetsMap), locations(locations) { setFunction(func); setModule(module); // create the CFG by walking the IR @@ -183,7 +183,7 @@ struct Flower : public CFGWalker, Info> { auto* set = action->cast(); auto& gets = allGets[set->index]; for (auto* get : gets) { - getSetses[get].insert(set); + getSetsMap[get].insert(set); } gets.clear(); } @@ -206,7 +206,7 @@ struct Flower : public CFGWalker, Info> { // confusing when debugging, but it does not have any downside for // optimization (since unreachable code should be removed anyhow). for (auto* get : gets) { - getSetses[get].insert(nullptr); + getSetsMap[get].insert(nullptr); } continue; } @@ -222,7 +222,7 @@ struct Flower : public CFGWalker, Info> { if (curr == entryFlowBlock) { // These receive a param or zero init value. for (auto* get : gets) { - getSetses[get].insert(nullptr); + getSetsMap[get].insert(nullptr); } } } else { @@ -241,7 +241,7 @@ struct Flower : public CFGWalker, Info> { if (lastSet != pred->lastSets.end()) { // There is a set here, apply it, and stop the flow. for (auto* get : gets) { - getSetses[get].insert(lastSet->second); + getSetsMap[get].insert(lastSet->second); } } else { // Keep on flowing. @@ -261,11 +261,11 @@ struct Flower : public CFGWalker, Info> { // LocalGraph implementation LocalGraph::LocalGraph(Function* func, Module* module) : func(func) { - LocalGraphInternal::Flower flower(getSetses, locations, func, module); + LocalGraphInternal::Flower flower(getSetsMap, locations, func, module); #ifdef LOCAL_GRAPH_DEBUG std::cout << "LocalGraph::dump\n"; - for (auto& [get, sets] : getSetses) { + for (auto& [get, sets] : getSetsMap) { std::cout << "GET\n" << get << " is influenced by\n"; for (auto* set : sets) { std::cout << set << '\n'; @@ -276,8 +276,8 @@ LocalGraph::LocalGraph(Function* func, Module* module) : func(func) { } bool LocalGraph::equivalent(LocalGet* a, LocalGet* b) { - auto& aSets = getSetses[a]; - auto& bSets = getSetses[b]; + auto& aSets = getSetsMap[a]; + auto& bSets = getSetsMap[b]; // The simple case of one set dominating two gets easily proves that they must // have the same value. (Note that we can infer dominance from the fact that // there is a single set: if the set did not dominate one of the gets then @@ -315,7 +315,7 @@ bool LocalGraph::equivalent(LocalGet* a, LocalGet* b) { void LocalGraph::computeSetInfluences() { for (auto& [curr, _] : locations) { if (auto* get = curr->dynCast()) { - for (auto* set : getSetses[get]) { + for (auto* set : getSetsMap[get]) { setInfluences[set].insert(get); } } @@ -335,7 +335,7 @@ void LocalGraph::computeGetInfluences() { void LocalGraph::computeSSAIndexes() { std::unordered_map> indexSets; - for (auto& [get, sets] : getSetses) { + for (auto& [get, sets] : getSetsMap) { for (auto* set : sets) { indexSets[get->index].insert(set); } diff --git a/src/ir/local-graph.h b/src/ir/local-graph.h index fd9306d5c0c..1a674de8672 100644 --- a/src/ir/local-graph.h +++ b/src/ir/local-graph.h @@ -39,37 +39,42 @@ namespace wasm { // code will be removed anyhow). // struct LocalGraph { - // main API - - // The constructor computes getSetses, the sets affecting each get. - // // If a module is passed in, it is used to find which features are needed in // the computation (for example, if exception handling is disabled, then we // can generate a simpler CFG, as calls cannot throw). LocalGraph(Function* func, Module* module = nullptr); - // The local.sets relevant for an index or a get. The most common case is to - // have a single set; after that, to be a phi of 2 items, so we use a small - // set of size 2 to avoid allocations there. + // Get the sets relevant for a local.get. + // + // A nullptr set means there is no local.set for that value, which means it is + // the initial value from the function entry: 0 for a var, the received value + // for a param. + // + // Often there is a single set, or a phi or two items, so we use a small set. using Sets = SmallSet; + const Sets& getSets(LocalGet* get) const { + // When we return an empty result, use a canonical constant empty set to + // avoid allocation. + static const Sets empty; + auto iter = getSetsMap.find(get); + if (iter == getSetsMap.end()) { + return empty; + } + return iter->second; + } - using GetSetses = std::unordered_map; - + // Where each get and set is. We compute this while doing the main computation + // and make it accessible for users, for easy replacing of things without + // extra work. using Locations = std::map; - - // externally useful information - GetSetses getSetses; // the sets affecting each get. a nullptr set means the - // initial value (0 for a var, the received value for a - // param) - Locations locations; // where each get and set is (for easy replacing) + Locations locations; // Checks if two gets are equivalent, that is, definitely have the same // value. bool equivalent(LocalGet* a, LocalGet* b); - // Optional: compute the influence graphs between sets and gets - // (useful for algorithms that propagate changes). - + // Optional: compute the influence graphs between sets and gets (useful for + // algorithms that propagate changes). void computeSetInfluences(); void computeGetInfluences(); @@ -109,9 +114,15 @@ struct LocalGraph { bool isSSA(Index x); + // Defined publicly as other utilities need similar data layouts. + using GetSetsMap = std::unordered_map; + private: Function* func; std::set SSAIndexes; + + // A map of each get to the sets relevant to it. + GetSetsMap getSetsMap; }; } // namespace wasm diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index e5e6cf659a7..aa656465307 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1245,7 +1245,12 @@ struct InfoCollector // the type must be the same for all gets of that local.) LocalGraph localGraph(func, getModule()); - for (auto& [get, setsForGet] : localGraph.getSetses) { + for (auto& [curr, _] : localGraph.locations) { + auto* get = curr->dynCast(); + if (!get) { + continue; + } + auto index = get->index; auto type = func->getLocalType(index); if (!isRelevant(type)) { @@ -1253,7 +1258,7 @@ struct InfoCollector } // Each get reads from its relevant sets. - for (auto* set : setsForGet) { + for (auto* set : localGraph.getSets(get)) { for (Index i = 0; i < type.size(); i++) { Location source; if (set) { diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp index 3f4795303d8..94ae42b61a1 100644 --- a/src/passes/AvoidReinterprets.cpp +++ b/src/passes/AvoidReinterprets.cpp @@ -44,7 +44,7 @@ static Load* getSingleLoad(LocalGraph* localGraph, std::set seen; seen.insert(get); while (1) { - auto& sets = localGraph->getSetses[get]; + auto& sets = localGraph->getSets(get); if (sets.size() != 1) { return nullptr; } diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 0531ebf9a2d..270741e6c80 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -517,9 +517,7 @@ struct EscapeAnalyzer { // Check that the gets can only read from the specific known sets. for (auto* get : gets) { - auto iter = localGraph.getSetses.find(get); - assert(iter != localGraph.getSetses.end()); - for (auto* set : iter->second) { + for (auto* set : localGraph.getSets(get)) { if (sets.count(set) == 0) { return false; } diff --git a/src/passes/LoopInvariantCodeMotion.cpp b/src/passes/LoopInvariantCodeMotion.cpp index 4239e39c37a..321267e8e81 100644 --- a/src/passes/LoopInvariantCodeMotion.cpp +++ b/src/passes/LoopInvariantCodeMotion.cpp @@ -228,7 +228,7 @@ struct LoopInvariantCodeMotion bool hasGetDependingOnLoopSet(Expression* curr, LoopSets& loopSets) { FindAll gets(curr); for (auto* get : gets.list) { - auto& sets = localGraph->getSetses[get]; + auto& sets = localGraph->getSets(get); for (auto* set : sets) { // nullptr means a parameter or zero-init value; // no danger to us. diff --git a/src/passes/MergeLocals.cpp b/src/passes/MergeLocals.cpp index c43ec85345c..b04215d73ee 100644 --- a/src/passes/MergeLocals.cpp +++ b/src/passes/MergeLocals.cpp @@ -123,9 +123,10 @@ struct MergeLocals // however, it may depend on other writes too, if there is a // merge/phi, and in that case we can't do anything assert(influencedGet->index == trivial->index); - if (preGraph.getSetses[influencedGet].size() == 1) { + auto& sets = preGraph.getSets(influencedGet); + if (sets.size() == 1) { // this is ok - assert(*preGraph.getSetses[influencedGet].begin() == trivial); + assert(*sets.begin() == trivial); // If local types are different (when one is a subtype of the // other), don't optimize if (func->getLocalType(copy->index) != influencedGet->type) { @@ -161,9 +162,10 @@ struct MergeLocals for (auto* influencedGet : copyInfluences) { // as above, avoid merges/phis assert(influencedGet->index == copy->index); - if (preGraph.getSetses[influencedGet].size() == 1) { + auto& sets = preGraph.getSets(influencedGet); + if (sets.size() == 1) { // this is ok - assert(*preGraph.getSetses[influencedGet].begin() == copy); + assert(*sets.begin() == copy); // If local types are different (when one is a subtype of the // other), don't optimize if (func->getLocalType(trivial->index) != influencedGet->type) { @@ -199,7 +201,7 @@ struct MergeLocals auto& trivialInfluences = preGraph.setInfluences[trivial]; for (auto* influencedGet : trivialInfluences) { // verify the set - auto& sets = postGraph.getSetses[influencedGet]; + auto& sets = postGraph.getSets(influencedGet); if (sets.size() != 1 || *sets.begin() != copy) { // not good, undo all the changes for this copy for (auto* undo : trivialInfluences) { @@ -213,7 +215,7 @@ struct MergeLocals auto& copyInfluences = preGraph.setInfluences[copy]; for (auto* influencedGet : copyInfluences) { // verify the set - auto& sets = postGraph.getSetses[influencedGet]; + auto& sets = postGraph.getSets(influencedGet); if (sets.size() != 1 || *sets.begin() != trivial) { // not good, undo all the changes for this copy for (auto* undo : copyInfluences) { diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp index 934fe8be8ad..af5d48be792 100644 --- a/src/passes/OptimizeAddedConstants.cpp +++ b/src/passes/OptimizeAddedConstants.cpp @@ -79,7 +79,7 @@ template class MemoryAccessOptimizer { // // This is only valid if y does not change in the middle! if (auto* get = curr->ptr->template dynCast()) { - auto& sets = localGraph->getSetses[get]; + auto& sets = localGraph->getSets(get); if (sets.size() == 1) { auto* set = *sets.begin(); // May be a zero-init (in which case, we can ignore it). Must also be diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index 6e0d7535f98..61220ece80f 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -814,7 +814,7 @@ struct Precompute // for this get to have constant value, all sets must agree Literals values; bool first = true; - for (auto* set : localGraph.getSetses[get]) { + for (auto* set : localGraph.getSets(get)) { Literals curr; if (set == nullptr) { if (getFunction()->isVar(get->index)) { diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp index 547b9cb5374..0a9c6891d3c 100644 --- a/src/passes/SSAify.cpp +++ b/src/passes/SSAify.cpp @@ -121,7 +121,7 @@ struct SSAify : public Pass { bool hasMerges(LocalSet* set, LocalGraph& graph) { for (auto* get : graph.setInfluences[set]) { - if (graph.getSetses[get].size() > 1) { + if (graph.getSets(get).size() > 1) { return true; } } @@ -131,7 +131,7 @@ struct SSAify : public Pass { void computeGetsAndPhis(LocalGraph& graph) { FindAll gets(func->body); for (auto* get : gets.list) { - auto& sets = graph.getSetses[get]; + auto& sets = graph.getSets(get); if (sets.size() == 0) { continue; // unreachable, ignore } diff --git a/src/tools/wasm-fuzz-lattices.cpp b/src/tools/wasm-fuzz-lattices.cpp index 551ddbaf1eb..a6231cd42ea 100644 --- a/src/tools/wasm-fuzz-lattices.cpp +++ b/src/tools/wasm-fuzz-lattices.cpp @@ -829,7 +829,7 @@ struct LivenessChecker { // Struct to set up and check reaching definitions analysis lattice and transfer // function. struct ReachingDefinitionsChecker { - LocalGraph::GetSetses getSetses; + LocalGraph::GetSetsMap getSetsMap; LocalGraph::Locations locations; ReachingDefinitionsTransferFunction txfn; AnalysisChecker, @@ -838,7 +838,7 @@ struct ReachingDefinitionsChecker { ReachingDefinitionsChecker(Function* func, uint64_t latticeElementSeed, Name funcName) - : txfn(func, getSetses, locations), + : txfn(func, getSetsMap, locations), checker(txfn.lattice, txfn, "FinitePowersetLattice", diff --git a/src/wasm/wasm-stack-opts.cpp b/src/wasm/wasm-stack-opts.cpp index cf4c094b534..5902b40a5a9 100644 --- a/src/wasm/wasm-stack-opts.cpp +++ b/src/wasm/wasm-stack-opts.cpp @@ -225,7 +225,7 @@ void StackIROptimizer::local2Stack() { if (set->index == get->index) { // This might be a proper set-get pair, where the set is // used by this get and nothing else, check that. - auto& sets = localGraph.getSetses[get]; + auto& sets = localGraph.getSets(get); if (sets.size() == 1 && *sets.begin() == set) { auto& setInfluences = localGraph.setInfluences[set]; // If this has the proper value of 1, also do the potentially- diff --git a/test/gtest/cfg.cpp b/test/gtest/cfg.cpp index e72341b321b..b8d26caa4b6 100644 --- a/test/gtest/cfg.cpp +++ b/test/gtest/cfg.cpp @@ -298,10 +298,10 @@ TEST_F(CFGTest, LinearReachingDefinitions) { Function* func = wasm.getFunction("bar"); CFG cfg = CFG::fromFunction(func); - LocalGraph::GetSetses getSetses; + LocalGraph::GetSetsMap getSetsMap; LocalGraph::Locations locations; ReachingDefinitionsTransferFunction transferFunction( - func, getSetses, locations); + func, getSetsMap, locations); MonotoneCFGAnalyzer, ReachingDefinitionsTransferFunction> @@ -320,12 +320,12 @@ TEST_F(CFGTest, LinearReachingDefinitions) { LocalGet* getC = foundGets.list[2]; LocalSet* setA1 = foundSets.list[0]; - LocalGraph::GetSetses expectedResult; + LocalGraph::GetSetsMap expectedResult; expectedResult[getA1].insert(setA1); expectedResult[getA2].insert(setA1); expectedResult[getC].insert(nullptr); - EXPECT_EQ(expectedResult, getSetses); + EXPECT_EQ(expectedResult, getSetsMap); } TEST_F(CFGTest, ReachingDefinitionsIf) { @@ -369,10 +369,10 @@ TEST_F(CFGTest, ReachingDefinitionsIf) { Function* func = wasm.getFunction("bar"); CFG cfg = CFG::fromFunction(func); - LocalGraph::GetSetses getSetses; + LocalGraph::GetSetsMap getSetsMap; LocalGraph::Locations locations; ReachingDefinitionsTransferFunction transferFunction( - func, getSetses, locations); + func, getSetsMap, locations); MonotoneCFGAnalyzer, ReachingDefinitionsTransferFunction> @@ -390,14 +390,14 @@ TEST_F(CFGTest, ReachingDefinitionsIf) { LocalSet* setB = foundSets.list[1]; LocalSet* setA2 = foundSets.list[2]; - LocalGraph::GetSetses expectedResult; + LocalGraph::GetSetsMap expectedResult; expectedResult[getA1].insert(setA1); expectedResult[getB].insert(nullptr); expectedResult[getB].insert(setB); expectedResult[getA2].insert(setA1); expectedResult[getA2].insert(setA2); - EXPECT_EQ(expectedResult, getSetses); + EXPECT_EQ(expectedResult, getSetsMap); } TEST_F(CFGTest, ReachingDefinitionsLoop) { @@ -437,10 +437,10 @@ TEST_F(CFGTest, ReachingDefinitionsLoop) { Function* func = wasm.getFunction("bar"); CFG cfg = CFG::fromFunction(func); - LocalGraph::GetSetses getSetses; + LocalGraph::GetSetsMap getSetsMap; LocalGraph::Locations locations; ReachingDefinitionsTransferFunction transferFunction( - func, getSetses, locations); + func, getSetsMap, locations); MonotoneCFGAnalyzer, ReachingDefinitionsTransferFunction> @@ -458,7 +458,7 @@ TEST_F(CFGTest, ReachingDefinitionsLoop) { LocalGet* getA4 = foundGets.list[4]; LocalSet* setA = foundSets.list[0]; - LocalGraph::GetSetses expectedResult; + LocalGraph::GetSetsMap expectedResult; expectedResult[getA1].insert(nullptr); expectedResult[getA1].insert(setA); expectedResult[getA2].insert(nullptr); @@ -467,5 +467,5 @@ TEST_F(CFGTest, ReachingDefinitionsLoop) { expectedResult[getB].insert(nullptr); expectedResult[getA4].insert(setA); - EXPECT_EQ(expectedResult, getSetses); + EXPECT_EQ(expectedResult, getSetsMap); } From 992468376b0cce76410be55bf3fbcacad141b7db Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 29 Aug 2024 08:48:20 -0700 Subject: [PATCH 549/553] Ignore fp16 in the fuzzer (#6881) Add the feature flag in V8 invocations, but also disable the feature as it isn't quite ready yet. --- scripts/fuzz_opt.py | 3 ++- scripts/test/shared.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index e06e13b72d8..665ae7cbd11 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -49,7 +49,8 @@ # parameters # feature options that are always passed to the tools. -CONSTANT_FEATURE_OPTS = ['--all-features'] +# XXX fp16 is not yet stable, remove from here when it is +CONSTANT_FEATURE_OPTS = ['--all-features', '--disable-fp16'] INPUT_SIZE_MIN = 1024 INPUT_SIZE_MEAN = 40 * 1024 diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 4ca065d0358..624a2f19a2d 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -257,6 +257,7 @@ def has_shell_timeout(): '--experimental-wasm-compilation-hints', '--experimental-wasm-memory64', '--experimental-wasm-stringref', + '--experimental-wasm-fp16', ] # external tools From aa7569809f37ae3fea83385b0acb2513b4a2f6ce Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 29 Aug 2024 14:30:06 -0700 Subject: [PATCH 550/553] Move lit test temporary files to out/test/ (#6887) Previously for in-tree builds, they were put directly into test/, which unnecessarily pollutes the tree. --- test/lit/lit.cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lit/lit.cfg.py b/test/lit/lit.cfg.py index 79d9f641b49..b337bddcd9f 100644 --- a/test/lit/lit.cfg.py +++ b/test/lit/lit.cfg.py @@ -7,7 +7,7 @@ config.suffixes = ['.wat', '.wast', '.test'] config.test_source_root = os.path.dirname(__file__) -config.test_exec_root = os.path.join(config.binaryen_build_root, 'test') +config.test_exec_root = os.path.join(config.binaryen_build_root, 'out', 'test') config.environment = dict(os.environ) From b63aeadb09a4450f55041dfb3fb7260807e91dfc Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 29 Aug 2024 15:07:35 -0700 Subject: [PATCH 551/553] Add a utility for finding minimal topological sorts (#6884) Reuse the code implementing Kahn's topological sort algorithm with a new configuration that uses a min-heap to always choose the best available element. Also add wrapper utilities that can find topological sorts of graphs with arbitrary element types, not just indices. --- src/support/topological_orders.cpp | 38 +++++++++++-- src/support/topological_orders.h | 86 ++++++++++++++++++++++++++++-- test/gtest/topological-orders.cpp | 55 +++++++++++++++++++ 3 files changed, 170 insertions(+), 9 deletions(-) diff --git a/src/support/topological_orders.cpp b/src/support/topological_orders.cpp index 145ba30043d..0536d4ed983 100644 --- a/src/support/topological_orders.cpp +++ b/src/support/topological_orders.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include "topological_orders.h" @@ -21,9 +22,13 @@ namespace wasm { TopologicalOrders::Selector -TopologicalOrders::Selector::select(TopologicalOrders& ctx) { +TopologicalOrders::Selector::select(TopologicalOrders& ctx, + SelectionMethod method = InPlace) { assert(count >= 1); assert(start + count <= ctx.buf.size()); + if (method == MinHeap) { + ctx.buf[start] = ctx.popChoice(); + } auto selection = ctx.buf[start]; // The next selector will select the next index and will not be able to choose // the vertex we just selected. @@ -33,7 +38,12 @@ TopologicalOrders::Selector::select(TopologicalOrders& ctx) { for (auto child : ctx.graph[selection]) { assert(ctx.indegrees[child] > 0); if (--ctx.indegrees[child] == 0) { - ctx.buf[next.start + next.count++] = child; + if (method == MinHeap) { + ctx.pushChoice(child); + } else { + ctx.buf[next.start + next.count] = child; + } + ++next.count; } } return next; @@ -69,7 +79,7 @@ TopologicalOrders::Selector::advance(TopologicalOrders& ctx) { } TopologicalOrders::TopologicalOrders( - const std::vector>& graph) + const std::vector>& graph, SelectionMethod method) : graph(graph), indegrees(graph.size()), buf(graph.size()) { if (graph.size() == 0) { return; @@ -86,13 +96,19 @@ TopologicalOrders::TopologicalOrders( auto& first = selectors.back(); for (size_t i = 0; i < graph.size(); ++i) { if (indegrees[i] == 0) { - buf[first.count++] = i; + if (method == MinHeap) { + pushChoice(i); + } else { + buf[first.count] = i; + } + ++first.count; } } // Initialize the full stack of selectors. while (selectors.size() < graph.size()) { - selectors.push_back(selectors.back().select(*this)); + selectors.push_back(selectors.back().select(*this, method)); } + selectors.back().select(*this, method); } TopologicalOrders& TopologicalOrders::operator++() { @@ -117,4 +133,16 @@ TopologicalOrders& TopologicalOrders::operator++() { return *this; } +void TopologicalOrders::pushChoice(size_t choice) { + choiceHeap.push_back(choice); + std::push_heap(choiceHeap.begin(), choiceHeap.end(), std::greater{}); +} + +size_t TopologicalOrders::popChoice() { + std::pop_heap(choiceHeap.begin(), choiceHeap.end(), std::greater{}); + auto choice = choiceHeap.back(); + choiceHeap.pop_back(); + return choice; +} + } // namespace wasm diff --git a/src/support/topological_orders.h b/src/support/topological_orders.h index 48941c02133..4332f7a915f 100644 --- a/src/support/topological_orders.h +++ b/src/support/topological_orders.h @@ -17,8 +17,10 @@ #ifndef wasm_support_topological_orders_h #define wasm_support_topological_orders_h +#include #include #include +#include #include namespace wasm { @@ -36,7 +38,8 @@ struct TopologicalOrders { // Takes an adjacency list, where the list for each vertex is a sorted list of // the indices of its children, which will appear after it in the order. - TopologicalOrders(const std::vector>& graph); + TopologicalOrders(const std::vector>& graph) + : TopologicalOrders(graph, InPlace) {} TopologicalOrders begin() { return TopologicalOrders(graph); } TopologicalOrders end() { return TopologicalOrders({}); } @@ -47,11 +50,16 @@ struct TopologicalOrders { bool operator!=(const TopologicalOrders& other) const { return !(*this == other); } - const std::vector& operator*() { return buf; } - const std::vector* operator->() { return &buf; } + const std::vector& operator*() const { return buf; } + const std::vector* operator->() const { return &buf; } TopologicalOrders& operator++(); TopologicalOrders operator++(int) { return ++(*this); } +protected: + enum SelectionMethod { InPlace, MinHeap }; + TopologicalOrders(const std::vector>& graph, + SelectionMethod method); + private: // The input graph given as an adjacency list with edges from vertices to // their dependent children. @@ -64,6 +72,9 @@ struct TopologicalOrders { // sequence of selected vertices followed by a sequence of possible choices // for the next vertex. std::vector buf; + // When we are finding the minimal topological order, store the possible + // choices in this separate min-heap instead of directly in `buf`. + std::vector choiceHeap; // The state for tracking the possible choices for a single vertex in the // output order. @@ -78,7 +89,7 @@ struct TopologicalOrders { // Select the next available vertex, decrement in-degrees, and update the // sequence of available vertices. Return the Selector for the next vertex. - Selector select(TopologicalOrders& ctx); + Selector select(TopologicalOrders& ctx, SelectionMethod method); // Undo the current selection, move the next selection into the first // position and return the new selector for the next position. Returns @@ -86,11 +97,78 @@ struct TopologicalOrders { std::optional advance(TopologicalOrders& ctx); }; + void pushChoice(size_t); + size_t popChoice(); + // A stack of selectors, one for each vertex in a complete topological order. // Empty if we've already seen every possible ordering. std::vector selectors; }; +// A utility for finding a single topological order of a graph. +struct TopologicalSort : private TopologicalOrders { + TopologicalSort(const std::vector>& graph) + : TopologicalOrders(graph) {} + + const std::vector& operator*() const { + return TopologicalOrders::operator*(); + } +}; + +// A utility for finding the topological order that is as close as possible to +// the original order of elements. Internally uses a min-heap to choose the best +// available next element. +struct MinTopologicalSort : private TopologicalOrders { + MinTopologicalSort(const std::vector>& graph) + : TopologicalOrders(graph, MinHeap) {} + + const std::vector& operator*() const { + return TopologicalOrders::operator*(); + } +}; + +// A utility that finds a topological sort of a graph with arbitrary element +// types. +template +struct TopologicalSortOf { + std::vector order; + + // The value of the iterators must be a pair of an element and an iterable of + // its children. + template TopologicalSortOf(It begin, It end) { + std::unordered_map indices; + std::vector elements; + // Assign indices to each element. + for (auto it = begin; it != end; ++it) { + auto inserted = indices.insert({it->first, elements.size()}); + assert(inserted.second && "unexpected repeat element"); + elements.push_back(inserted.first->first); + } + // Collect the graph in terms of indices. + std::vector> indexGraph; + indexGraph.reserve(elements.size()); + for (auto it = begin; it != end; ++it) { + indexGraph.emplace_back(); + for (const auto& child : it->second) { + indexGraph.back().push_back(indices.at(child)); + } + } + // Compute the topological order and convert back to original elements. + order.reserve(elements.size()); + auto indexOrder = *TopoSort(indexGraph); + for (auto i : indexOrder) { + order.emplace_back(std::move(elements[i])); + } + } + + const std::vector& operator*() const { return order; } +}; + +// A utility that finds the minimum topological sort of a graph with arbitrary +// element types. +template +using MinTopologicalSortOf = TopologicalSortOf; + } // namespace wasm #endif // wasm_support_topological_orders_h diff --git a/test/gtest/topological-orders.cpp b/test/gtest/topological-orders.cpp index 7eeb8fdc237..ba370123d7a 100644 --- a/test/gtest/topological-orders.cpp +++ b/test/gtest/topological-orders.cpp @@ -99,3 +99,58 @@ TEST(TopologicalOrdersTest, Diamond) { }; EXPECT_EQ(results, expected); } + +TEST(MinTopologicalSortTest, Empty) { + Graph graph(0); + EXPECT_EQ(*MinTopologicalSort(graph), std::vector{}); +} + +TEST(MinTopologicalSortTest, Unconstrained) { + Graph graph(3); + MinTopologicalSort order(graph); + std::vector expected{0, 1, 2}; + EXPECT_EQ(*MinTopologicalSort(graph), expected); +} + +TEST(MinTopologicalSortTest, Reversed) { + Graph graph(3); + graph[2].push_back(1); + graph[1].push_back(0); + std::vector expected{2, 1, 0}; + EXPECT_EQ(*MinTopologicalSort(graph), expected); +} + +TEST(MinTopologicalSortTest, OneBeforeZero) { + Graph graph(3); + graph[1].push_back(0); + // 2 last because it is greater than 1 and 0 + std::vector expected{1, 0, 2}; + EXPECT_EQ(*MinTopologicalSort(graph), expected); +} + +TEST(MinTopologicalSortTest, TwoBeforeOne) { + Graph graph(3); + graph[2].push_back(1); + // 0 first because it is less than 2 and 1 + std::vector expected{0, 2, 1}; + EXPECT_EQ(*MinTopologicalSort(graph), expected); +} + +TEST(MinTopologicalSortTest, TwoBeforeZero) { + Graph graph(3); + graph[2].push_back(0); + // 1 first because it is less than 2 and zero is not eligible. + std::vector expected{1, 2, 0}; + EXPECT_EQ(*MinTopologicalSort(graph), expected); +} + +TEST(MinTopologicalSortTest, Strings) { + std::map> graph{ + {"animal", {"mammal"}}, + {"cat", {}}, + {"dog", {}}, + {"mammal", {"cat", "dog"}}}; + std::vector expected{"animal", "mammal", "cat", "dog"}; + EXPECT_EQ(*MinTopologicalSortOf(graph.begin(), graph.end()), + expected); +} From 871ff0d4f910b565c15f82e8f3c9aa769b01d286 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 29 Aug 2024 15:08:00 -0700 Subject: [PATCH 552/553] Simplify ReorderGlobals using new topological sort utils (#6885) Use the new TopologicalSort and MinTopologicalSortOf utilities instead of the old CRTP topological sort utility and a bespoke heap-based topological sort in ReorderGlobals. Since there is no longer a heap to pop from, the direction of the custom comparator is now much more intuitive. Further simplify the code by switching from tracking the new order of globals using a sequence of new indices to tracking the order using a sequence of old indices. This change also makes the pass about 20% faster on a large real-world module. --- src/passes/ReorderGlobals.cpp | 203 +++++++++++----------------------- 1 file changed, 62 insertions(+), 141 deletions(-) diff --git a/src/passes/ReorderGlobals.cpp b/src/passes/ReorderGlobals.cpp index 4602f328496..d17bb86cc82 100644 --- a/src/passes/ReorderGlobals.cpp +++ b/src/passes/ReorderGlobals.cpp @@ -35,7 +35,7 @@ #include "ir/find_all.h" #include "pass.h" -#include "support/topological_sort.h" +#include "support/topological_orders.h" #include "wasm.h" namespace wasm { @@ -75,8 +75,8 @@ struct ReorderGlobals : public Pass { // For efficiency we will use global indices rather than names. That is, we // use the index of the global in the original ordering to identify each - // global. A different ordering is then a vector of new indices, saying where - // each one moves, which is logically a mapping between indices. + // global. A different ordering is then a vector of old indices, saying where + // each element comes from, which is logically a mapping between indices. using IndexIndexMap = std::vector; // We will also track counts of uses for each global. We use floating-point @@ -190,26 +190,16 @@ struct ReorderGlobals : public Pass { double const EXPONENTIAL_FACTOR = 0.095; IndexCountMap sumCounts(globals.size()), exponentialCounts(globals.size()); - struct Sort : public TopologicalSort { - const Dependencies& deps; - - Sort(Index numGlobals, const Dependencies& deps) : deps(deps) { - for (Index i = 0; i < numGlobals; i++) { - push(i); + std::vector> dependenceGraph(globals.size()); + for (size_t i = 0; i < globals.size(); ++i) { + if (auto it = deps.dependsOn.find(i); it != deps.dependsOn.end()) { + for (auto dep : it->second) { + dependenceGraph[i].push_back(dep); } } + } - void pushPredecessors(Index global) { - auto iter = deps.dependedUpon.find(global); - if (iter == deps.dependedUpon.end()) { - return; - } - for (auto dep : iter->second) { - push(dep); - } - } - } sort(globals.size(), deps); - + auto sort = *TopologicalSort(dependenceGraph); for (auto global : sort) { // We can compute this global's count as in the sorted order all the // values it cares about are resolved. Start with the self-count, then @@ -236,160 +226,91 @@ struct ReorderGlobals : public Pass { } // Apply the indices we computed. - std::vector> old(std::move(globals)); + auto old = std::move(globals); globals.resize(old.size()); for (Index i = 0; i < old.size(); i++) { - globals[(*best)[i]] = std::move(old[i]); + globals[i] = std::move(old[(*best)[i]]); } module->updateMaps(); } IndexIndexMap doSort(const IndexCountMap& counts, - const Dependencies& originalDeps, + const Dependencies& deps, Module* module) { auto& globals = module->globals; - // Copy the deps as we will operate on them as we go. - auto deps = originalDeps; - // To sort the globals we do a simple greedy approach of always picking the // global with the highest count at every point in time, subject to the // constraint that we can only emit globals that have all of their - // dependencies already emitted. To do so we keep a list of the "available" - // globals, which are those with no remaining dependencies. Then by keeping - // the list of available globals in heap form we can simply pop the largest - // from the heap each time, and add new available ones as they become so. + // dependencies already emitted. // - // Other approaches here could be to do a topological sort, but the optimal - // order may not require strict ordering by topological depth, e.g.: - /* - // $c - $a - // / - // $e - // \ - // $d - $b - */ - // Here $e depends on $c and $d, $c depends on $a, and $d on $b. This is a - // partial order, as $d can be before or after $a, for example. As a result, - // if we sorted topologically by sub-trees here then we'd keep $c and $a - // together, and $d and $b, but a better order might interleave them. A good - // order also may not keep topological depths separated, e.g. we may want to - // put $a in between $c and $d despite it having a greater depth. + // The greedy approach here may also be suboptimal, however. Consider that + // we might see that the best available global is $a, but if we instead + // selected some other global $b, that would allow us to select a third + // global $c that depends on $b, and $c might have a much higher use count + // than $a. For that reason we try several variations of this with different + // counts, see earlier. // - // The greedy approach here may also be unoptimal, however. Consider that we - // might see that the best available global is $a, but if we popped $b - // instead that could unlock $c which depends on $b, and $c may have a much - // higher use count than $a. For that reason we try several variations of - // this with different counts, see earlier. - std::vector availableHeap; - - // Comparison function. Given a and b, returns if a should be before b. This - // is used in a heap, where "highest" means "popped first", so see the notes - // below on how we order. - auto cmp = [&](Index a, Index b) { - // Imports always go first. The binary writer takes care of this itself - // anyhow, but it is better to do it here in the IR so we can actually - // see what the final layout will be. - auto aImported = globals[a]->imported(); - auto bImported = globals[b]->imported(); - // The highest items will be popped first off the heap, so we want imports - // to be at higher indexes, that is, - // - // unimported, unimported, imported, imported. - // - // Then the imports are popped first. - if (aImported != bImported) { - return bImported; - } - - // Sort by the counts. We want higher counts at higher indexes so they are - // popped first, that is, - // - // 10, 20, 30, 40 - // - auto aCount = counts[a]; - auto bCount = counts[b]; - if (aCount != bCount) { - return aCount < bCount; - } - - // Break ties using the original order, which means just using the - // indices we have. We need lower indexes at the top so they are popped - // first, that is, - // - // 3, 2, 1, 0 - // - return a > b; - }; - - // Push an item that just became available to the available heap. - auto push = [&](Index global) { - availableHeap.push_back(global); - std::push_heap(availableHeap.begin(), availableHeap.end(), cmp); - }; - - // The initially available globals are those with no dependencies. - for (Index i = 0; i < globals.size(); i++) { - if (deps.dependsOn[i].empty()) { - push(i); - } + // Sort the globals into the optimal order based on the counts, ignoring + // dependencies for now. + std::vector sortedGlobals; + sortedGlobals.resize(globals.size()); + for (Index i = 0; i < globals.size(); ++i) { + sortedGlobals[i] = i; } + std::sort( + sortedGlobals.begin(), sortedGlobals.end(), [&](Index a, Index b) { + // Imports always go first. The binary writer takes care of this itself + // anyhow, but it is better to do it here in the IR so we can actually + // see what the final layout will be. + auto aImported = globals[a]->imported(); + auto bImported = globals[b]->imported(); + if (aImported != bImported) { + return aImported; + } - // Pop off the heap: Emit the global and its final, sorted index. Keep - // doing that until we finish processing all the globals. - IndexIndexMap sortedindices(globals.size()); - Index numSortedindices = 0; - while (!availableHeap.empty()) { - std::pop_heap(availableHeap.begin(), availableHeap.end(), cmp); - auto global = availableHeap.back(); - sortedindices[global] = numSortedindices++; - availableHeap.pop_back(); - - // Each time we pop we emit the global, which means anything that only - // depended on it becomes available to be popped as well. - for (auto other : deps.dependedUpon[global]) { - assert(deps.dependsOn[other].count(global)); - deps.dependsOn[other].erase(global); - if (deps.dependsOn[other].empty()) { - push(other); + // Sort by the counts. Higher counts come first. + auto aCount = counts[a]; + auto bCount = counts[b]; + if (aCount != bCount) { + return aCount > bCount; } + + // Break ties using the original order, which means just using the + // indices we have. + return a < b; + }); + + // Now use that optimal order to create an ordered graph that includes the + // dependencies. The final order will be the minimum topological sort of + // this graph. + std::vector>> graph; + graph.reserve(globals.size()); + for (auto i : sortedGlobals) { + std::vector children; + if (auto it = deps.dependedUpon.find(i); it != deps.dependedUpon.end()) { + children = std::vector(it->second.begin(), it->second.end()); } + graph.emplace_back(i, std::move(children)); } - // All globals must have been handled. Cycles would prevent this, but they - // cannot exist in valid IR. - assert(numSortedindices == globals.size()); - - return sortedindices; + return *MinTopologicalSortOf(graph.begin(), graph.end()); } // Given an indexing of the globals and the counts of how many times each is // used, estimate the size of relevant parts of the wasm binary (that is, of // LEBs in global.gets). double computeSize(IndexIndexMap& indices, IndexCountMap& counts) { - // |indices| maps each old index to its new position in the sort. We need - // the reverse map here, which at index 0 has the old index of the global - // that will be first, and so forth. - IndexIndexMap actualOrder(indices.size()); - for (Index i = 0; i < indices.size(); i++) { - // Each global has a unique index, so we only replace 0's here, and they - // must be in bounds. - assert(indices[i] < indices.size()); - assert(actualOrder[indices[i]] == 0); - - actualOrder[indices[i]] = i; - } - if (always) { // In this mode we gradually increase the cost of later globals, in an // unrealistic but smooth manner. double total = 0; - for (Index i = 0; i < actualOrder.size(); i++) { + for (Index i = 0; i < indices.size(); i++) { // Multiply the count for this global by a smoothed LEB factor, which // starts at 1 (for 1 byte) at index 0, and then increases linearly with // i, so that after 128 globals we reach 2 (which is the true index at // which the LEB size normally jumps from 1 to 2), and so forth. - total += counts[actualOrder[i]] * (1.0 + (i / 128.0)); + total += counts[indices[i]] * (1.0 + (i / 128.0)); } return total; } @@ -401,7 +322,7 @@ struct ReorderGlobals : public Pass { // forth. size_t sizeInBits = 0; size_t nextSizeIncrease = 0; - for (Index i = 0; i < actualOrder.size(); i++) { + for (Index i = 0; i < indices.size(); i++) { if (i == nextSizeIncrease) { sizeInBits++; // At the current size we have 7 * sizeInBits bits to use. For example, @@ -410,7 +331,7 @@ struct ReorderGlobals : public Pass { // larger LEB. nextSizeIncrease = 1 << (7 * sizeInBits); } - total += counts[actualOrder[i]] * sizeInBits; + total += counts[indices[i]] * sizeInBits; } return total; } From bc55a3eb149042fea3597af87d40f53f78130f34 Mon Sep 17 00:00:00 2001 From: Goktug Gokdogan Date: Fri, 30 Aug 2024 20:20:26 -0700 Subject: [PATCH 553/553] Only generate string.consts custom section if it is needed. --- src/passes/StringLowering.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp index 92e3268dc22..594c05550b4 100644 --- a/src/passes/StringLowering.cpp +++ b/src/passes/StringLowering.cpp @@ -235,7 +235,6 @@ struct StringLowering : public StringGathering { void makeImports(Module* module) { Index jsonImportIndex = 0; std::stringstream json; - json << '['; bool first = true; for (auto& global : module->globals) { if (global->init) { @@ -267,12 +266,15 @@ struct StringLowering : public StringGathering { } } - // Add a custom section with the JSON. - json << ']'; - auto str = json.str(); - auto vec = std::vector(str.begin(), str.end()); - module->customSections.emplace_back( - CustomSection{"string.consts", std::move(vec)}); + if (json) { + // If we are asserting UTF8, then we shouldn't be generating any JSON. + assert(!assertUTF8); + // Add a custom section with the JSON. + auto str = '[' + json.str() + ']'; + auto vec = std::vector(str.begin(), str.end()); + module->customSections.emplace_back( + CustomSection{"string.consts", std::move(vec)}); + } } // Common types used in imports.