diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-08-27 16:40:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-27 16:40:59 -0700 |
commit | cb0b31a2d185f18662814c9f3c9158b2eea74760 (patch) | |
tree | 4fe23ff2abb08af7a804f6e6755b07454f79f45d | |
parent | f070e8c10a15a02735fbd9b88c4c569a8c786933 (diff) | |
download | binaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.tar.gz binaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.tar.bz2 binaryen-cb0b31a2d185f18662814c9f3c9158b2eea74760.zip |
Add atomic.fence instruction (#2307)
This adds `atomic.fence` instruction:
https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#fence-operator
This also fix bugs in `atomic.wait` and `atomic.notify` instructions in
binaryen.js and adds tests for them.
45 files changed, 1558 insertions, 817 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f3dd2dd6..b904af9f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ full changeset diff at the end of each section. Current Trunk ------------- +- Binaryen.js instruction API changes: + - `notify` -> `atomic.notify` + - `i32.wait` / `i64.wait` -> `i32.atomic.wait` / `i64.atomic.wait` +- Binaryen.js: `flags` argument in `setMemory` function is removed. +- `atomic.fence` instruction support is added. - wasm-emscripten-finalize: Don't realy on name section being present in the input. Use the exported names for things instead. diff --git a/build-js.sh b/build-js.sh index 861aceefd..d05304bca 100755 --- a/build-js.sh +++ b/build-js.sh @@ -219,6 +219,7 @@ export_function "_BinaryenAtomicCmpxchgId" export_function "_BinaryenAtomicRMWId" export_function "_BinaryenAtomicWaitId" export_function "_BinaryenAtomicNotifyId" +export_function "_BinaryenAtomicFenceId" export_function "_BinaryenSIMDExtractId" export_function "_BinaryenSIMDReplaceId" export_function "_BinaryenSIMDShuffleId" @@ -575,6 +576,7 @@ export_function "_BinaryenAtomicRMW" export_function "_BinaryenAtomicCmpxchg" export_function "_BinaryenAtomicWait" export_function "_BinaryenAtomicNotify" +export_function "_BinaryenAtomicFence" export_function "_BinaryenSIMDExtract" export_function "_BinaryenSIMDReplace" export_function "_BinaryenSIMDShuffle" @@ -721,6 +723,9 @@ export_function "_BinaryenAtomicWaitGetExpectedType" export_function "_BinaryenAtomicNotifyGetPtr" export_function "_BinaryenAtomicNotifyGetNotifyCount" +# 'AtomicFence' expression operations +export_function "_BinaryenAtomicFenceGetOrder" + # 'SIMDExtract' expression operations export_function "_BinaryenSIMDExtractGetOp" export_function "_BinaryenSIMDExtractGetVec" diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index d6653e112..29f822f50 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -211,6 +211,7 @@ instructions = [ ("atomic.notify", "makeAtomicNotify(s)"), ("i32.atomic.wait", "makeAtomicWait(s, i32)"), ("i64.atomic.wait", "makeAtomicWait(s, i64)"), + ("atomic.fence", "makeAtomicFence(s)"), ("i32.atomic.load8_u", "makeLoad(s, i32, /*isAtomic=*/true)"), ("i32.atomic.load16_u", "makeLoad(s, i32, /*isAtomic=*/true)"), ("i32.atomic.load", "makeLoad(s, i32, /*isAtomic=*/true)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index d8f8163c4..a06e32d87 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -331,6 +331,9 @@ BinaryenExpressionId BinaryenAtomicWaitId(void) { BinaryenExpressionId BinaryenAtomicNotifyId(void) { return Expression::Id::AtomicNotifyId; } +BinaryenExpressionId BinaryenAtomicFenceId(void) { + return Expression::Id::AtomicFenceId; +} BinaryenExpressionId BinaryenSIMDExtractId(void) { return Expression::Id::SIMDExtractId; } @@ -1466,6 +1469,15 @@ BinaryenExpressionRef BinaryenAtomicNotify(BinaryenModuleRef module, return static_cast<Expression*>(ret); } +BinaryenExpressionRef BinaryenAtomicFence(BinaryenModuleRef module) { + auto* ret = Builder(*(Module*)module).makeAtomicFence(); + + if (tracing) { + traceExpression(ret, "BinaryenAtomicFence"); + } + + return static_cast<Expression*>(ret); +} BinaryenExpressionRef BinaryenSIMDExtract(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef vec, @@ -2520,6 +2532,17 @@ BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr) { assert(expression->is<AtomicNotify>()); return static_cast<AtomicNotify*>(expression)->notifyCount; } +// AtomicFence +uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr) { + if (tracing) { + std::cout << " BinaryenAtomicFenceGetOrder(expressions[" + << expressions[expr] << "]);\n"; + } + + auto* expression = (Expression*)expr; + assert(expression->is<AtomicFence>()); + return static_cast<AtomicFence*>(expression)->order; +} // SIMDExtract BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr) { if (tracing) { diff --git a/src/binaryen-c.h b/src/binaryen-c.h index b7c99ed1a..0637b65b0 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -119,6 +119,7 @@ BinaryenExpressionId BinaryenAtomicCmpxchgId(void); BinaryenExpressionId BinaryenAtomicRMWId(void); BinaryenExpressionId BinaryenAtomicWaitId(void); BinaryenExpressionId BinaryenAtomicNotifyId(void); +BinaryenExpressionId BinaryenAtomicFenceId(void); BinaryenExpressionId BinaryenSIMDExtractId(void); BinaryenExpressionId BinaryenSIMDReplaceId(void); BinaryenExpressionId BinaryenSIMDShuffleId(void); @@ -670,6 +671,7 @@ BinaryenExpressionRef BinaryenAtomicWait(BinaryenModuleRef module, BinaryenExpressionRef BinaryenAtomicNotify(BinaryenModuleRef module, BinaryenExpressionRef ptr, BinaryenExpressionRef notifyCount); +BinaryenExpressionRef BinaryenAtomicFence(BinaryenModuleRef module); BinaryenExpressionRef BinaryenSIMDExtract(BinaryenModuleRef module, BinaryenOp op, BinaryenExpressionRef vec, @@ -837,6 +839,8 @@ BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr); BinaryenExpressionRef BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr); +uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr); + BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr); BinaryenExpressionRef BinaryenSIMDExtractGetVec(BinaryenExpressionRef expr); uint8_t BinaryenSIMDExtractGetIndex(BinaryenExpressionRef expr); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 15a73cdf2..68a8140a6 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -7,9 +7,17 @@ char op[27] = {'\0'}; strncpy(op, s[0]->c_str(), 26); switch (op[0]) { - case 'a': - if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); } - goto parse_error; + case 'a': { + switch (op[7]) { + case 'f': + if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); } + goto parse_error; + case 'n': + if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); } + goto parse_error; + default: goto parse_error; + } + } case 'b': { switch (op[1]) { case 'l': diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index f8f96d5c8..a52d7af90 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -180,6 +180,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) { void visitAtomicNotify(AtomicNotify* curr) { visitor.visitAddress(curr->offset); } + void visitAtomicFence(AtomicFence* curr) { visitor.visitInt(curr->order); } void visitSIMDExtract(SIMDExtract* curr) { visitor.visitInt(curr->op); visitor.visitInt(curr->index); diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp index e650f40a7..7b0ee29d7 100644 --- a/src/ir/ExpressionManipulator.cpp +++ b/src/ir/ExpressionManipulator.cpp @@ -157,6 +157,9 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { return builder.makeAtomicNotify( copy(curr->ptr), copy(curr->notifyCount), curr->offset); } + Expression* visitAtomicFence(AtomicFence* curr) { + return builder.makeAtomicFence(); + } Expression* visitSIMDExtract(SIMDExtract* curr) { return builder.makeSIMDExtract(curr->op, copy(curr->vec), curr->index); } diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 05abb76e1..49b70684b 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -141,6 +141,7 @@ void ReFinalize::visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); } void ReFinalize::visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void ReFinalize::visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void ReFinalize::visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); } +void ReFinalize::visitAtomicFence(AtomicFence* curr) { curr->finalize(); } void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); } void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); } void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } diff --git a/src/ir/effects.h b/src/ir/effects.h index e3997f5d2..c175bed85 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -294,7 +294,14 @@ struct EffectAnalyzer if (!ignoreImplicitTraps) { implicitTrap = true; } - }; + } + void visitAtomicFence(AtomicFence* curr) { + // AtomicFence should not be reordered with any memory operations, so we set + // these to true. + readsMemory = true; + writesMemory = true; + isAtomic = true; + } void visitSIMDExtract(SIMDExtract* curr) {} void visitSIMDReplace(SIMDReplace* curr) {} void visitSIMDShuffle(SIMDShuffle* curr) {} diff --git a/src/ir/utils.h b/src/ir/utils.h index 5c6a09290..43ba2fdde 100644 --- a/src/ir/utils.h +++ b/src/ir/utils.h @@ -128,6 +128,7 @@ struct ReFinalize void visitAtomicCmpxchg(AtomicCmpxchg* curr); void visitAtomicWait(AtomicWait* curr); void visitAtomicNotify(AtomicNotify* curr); + void visitAtomicFence(AtomicFence* curr); void visitSIMDExtract(SIMDExtract* curr); void visitSIMDReplace(SIMDReplace* curr); void visitSIMDShuffle(SIMDShuffle* curr); @@ -191,6 +192,7 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> { void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); } void visitAtomicWait(AtomicWait* curr) { curr->finalize(); } void visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); } + void visitAtomicFence(AtomicFence* curr) { curr->finalize(); } void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); } void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); } void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); } diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 635a10577..799cb30e4 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -70,6 +70,7 @@ Module['AtomicCmpxchgId'] = Module['_BinaryenAtomicCmpxchgId'](); Module['AtomicRMWId'] = Module['_BinaryenAtomicRMWId'](); Module['AtomicWaitId'] = Module['_BinaryenAtomicWaitId'](); Module['AtomicNotifyId'] = Module['_BinaryenAtomicNotifyId'](); +Module['AtomicFenceId'] = Module['_BinaryenAtomicFenceId'](); Module['SIMDExtractId'] = Module['_BinaryenSIMDExtractId'](); Module['SIMDReplaceId'] = Module['_BinaryenSIMDReplaceId'](); Module['SIMDShuffleId'] = Module['_BinaryenSIMDShuffleId'](); @@ -676,7 +677,7 @@ function wrapModule(module, self) { 'ge_u': function(left, right) { return Module['_BinaryenBinary'](module, Module['GeUInt32'], left, right); }, - 'atomic':{ + 'atomic': { 'load': function(offset, ptr) { return Module['_BinaryenAtomicLoad'](module, 4, offset, Module['i32'], ptr); }, @@ -764,9 +765,9 @@ function wrapModule(module, self) { return Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i32']) }, }, - }, - 'wait': function(ptr, expected, timeout) { - return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']); + 'wait': function(ptr, expected, timeout) { + return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']); + } }, 'pop': function() { return Module['_BinaryenPop'](module, Module['i32']); @@ -951,7 +952,7 @@ function wrapModule(module, self) { 'ge_u': function(left, right) { return Module['_BinaryenBinary'](module, Module['GeUInt64'], left, right); }, - 'atomic':{ + 'atomic': { 'load': function(offset, ptr) { return Module['_BinaryenAtomicLoad'](module, 8, offset, Module['i64'], ptr); }, @@ -1068,9 +1069,9 @@ function wrapModule(module, self) { return Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i64']) }, }, - }, - 'wait': function(ptr, expected, timeout) { - return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']); + 'wait': function(ptr, expected, timeout) { + return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']); + } }, 'pop': function() { return Module['_BinaryenPop'](module, Module['i64']); @@ -1773,9 +1774,16 @@ function wrapModule(module, self) { self['unreachable'] = function() { return Module['_BinaryenUnreachable'](module); }; - self['notify'] = function(ptr, notifyCount) { - return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount); + + self['atomic'] = { + 'notify': function(ptr, notifyCount) { + return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount); + }, + 'fence': function() { + return Module['_BinaryenAtomicFence'](module); + } }; + self['try'] = function(body, catchBody) { return Module['_BinaryenTry'](module, body, catchBody); }; @@ -1925,7 +1933,7 @@ function wrapModule(module, self) { ); }); }; - self['setMemory'] = function(initial, maximum, exportName, segments, flags, shared) { + self['setMemory'] = function(initial, maximum, exportName, segments, shared) { // segments are assumed to be { passive: bool, offset: expression ref, data: array of 8-bit data } if (!segments) segments = []; return preserveStack(function() { @@ -2321,6 +2329,12 @@ Module['getExpressionInfo'] = function(expr) { 'ptr': Module['_BinaryenAtomicNotifyGetPtr'](expr), 'notifyCount': Module['_BinaryenAtomicNotifyGetNotifyCount'](expr) }; + case Module['AtomicFenceId']: + return { + 'id': id, + 'type': type, + 'order': Module['_BinaryenAtomicFenceGetOrder'](expr) + }; case Module['SIMDExtractId']: return { 'id': id, diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index f913c5a93..464451763 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -298,6 +298,8 @@ struct DeadCodeElimination DELEGATE(AtomicWait); case Expression::Id::AtomicNotifyId: DELEGATE(AtomicNotify); + case Expression::Id::AtomicFenceId: + DELEGATE(AtomicFence); case Expression::Id::SIMDExtractId: DELEGATE(SIMDExtract); case Expression::Id::SIMDReplaceId: diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 0bf61e784..b1e1240ae 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -268,6 +268,7 @@ struct PrintExpressionContents o << " offset=" << curr->offset; } } + void visitAtomicFence(AtomicFence* curr) { printMedium(o, "atomic.fence"); } void visitSIMDExtract(SIMDExtract* curr) { prepareColor(o); switch (curr->op) { @@ -1505,6 +1506,11 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { printFullLine(curr->notifyCount); decIndent(); } + void visitAtomicFence(AtomicFence* curr) { + o << '('; + PrintExpressionContents(currFunction, o).visit(curr); + o << ')'; + } void visitSIMDExtract(SIMDExtract* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr); diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index 20c30d271..d4c6d5a5d 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -106,6 +106,7 @@ struct ReachabilityAnalyzer : public PostWalker<ReachabilityAnalyzer> { void visitAtomicRMW(AtomicRMW* curr) { usesMemory = true; } void visitAtomicWait(AtomicWait* curr) { usesMemory = true; } void visitAtomicNotify(AtomicNotify* curr) { usesMemory = true; } + void visitAtomicFence(AtomicFence* curr) { usesMemory = true; } void visitMemoryInit(MemoryInit* curr) { usesMemory = true; } void visitDataDrop(DataDrop* curr) { usesMemory = true; } void visitMemoryCopy(MemoryCopy* curr) { usesMemory = true; } diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index baf42336d..dde8a0de7 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -953,7 +953,8 @@ private: &Self::makeDrop, &Self::makeNop, &Self::makeGlobalSet) - .add(FeatureSet::BulkMemory, &Self::makeBulkMemory); + .add(FeatureSet::BulkMemory, &Self::makeBulkMemory) + .add(FeatureSet::Atomics, &Self::makeAtomic); return (this->*pick(options))(none); } @@ -2240,6 +2241,9 @@ private: return makeTrivial(type); } wasm.memory.shared = true; + if (type == none) { + return builder.makeAtomicFence(); + } if (type == i32 && oneIn(2)) { if (ATOMIC_WAITS && oneIn(2)) { auto* ptr = makePointer(); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index d01502e9b..b3ac336ee 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -627,6 +627,7 @@ enum ASTNodes { AtomicNotify = 0x00, I32AtomicWait = 0x01, I64AtomicWait = 0x02, + AtomicFence = 0x03, I32AtomicLoad = 0x10, I64AtomicLoad = 0x11, @@ -1232,6 +1233,7 @@ public: bool maybeVisitAtomicCmpxchg(Expression*& out, uint8_t code); bool maybeVisitAtomicWait(Expression*& out, uint8_t code); bool maybeVisitAtomicNotify(Expression*& out, uint8_t code); + bool maybeVisitAtomicFence(Expression*& out, uint8_t code); bool maybeVisitConst(Expression*& out, uint8_t code); bool maybeVisitUnary(Expression*& out, uint8_t code); bool maybeVisitBinary(Expression*& out, uint8_t code); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 4258b9336..3e61b1a36 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -309,6 +309,7 @@ public: notify->finalize(); return notify; } + AtomicFence* makeAtomicFence() { return allocator.alloc<AtomicFence>(); } Store* makeStore(unsigned bytes, uint32_t offset, unsigned align, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 05d00ed10..d854b20d3 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1029,6 +1029,12 @@ public: return Literal(uint64_t(val)); } } + Flow visitAtomicFence(AtomicFence*) { + // Wasm currently supports only sequentially consistent atomics, in which + // case atomic_fence can be lowered to nothing. + NOTE_ENTER("AtomicFence"); + return Flow(); + } Flow visitCall(Call*) { WASM_UNREACHABLE(); } Flow visitCallIndirect(CallIndirect*) { WASM_UNREACHABLE(); } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index d6ec89319..b6ef320d5 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -194,6 +194,7 @@ private: makeAtomicCmpxchg(Element& s, Type type, uint8_t bytes, const char* extra); Expression* makeAtomicWait(Element& s, Type type); Expression* makeAtomicNotify(Element& s); + Expression* makeAtomicFence(Element& s); Expression* makeSIMDExtract(Element& s, SIMDExtractOp op, size_t lanes); Expression* makeSIMDReplace(Element& s, SIMDReplaceOp op, size_t lanes); Expression* makeSIMDShuffle(Element& s); diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 562a00684..3a7d7c38e 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -103,6 +103,7 @@ public: void visitAtomicCmpxchg(AtomicCmpxchg* curr); void visitAtomicWait(AtomicWait* curr); void visitAtomicNotify(AtomicNotify* curr); + void visitAtomicFence(AtomicFence* curr); void visitSIMDExtract(SIMDExtract* curr); void visitSIMDReplace(SIMDReplace* curr); void visitSIMDShuffle(SIMDShuffle* curr); @@ -178,6 +179,7 @@ public: void visitAtomicCmpxchg(AtomicCmpxchg* curr); void visitAtomicWait(AtomicWait* curr); void visitAtomicNotify(AtomicNotify* curr); + void visitAtomicFence(AtomicFence* curr); void visitSIMDExtract(SIMDExtract* curr); void visitSIMDReplace(SIMDReplace* curr); void visitSIMDShuffle(SIMDShuffle* curr); @@ -526,6 +528,11 @@ void BinaryenIRWriter<SubType>::visitAtomicNotify(AtomicNotify* curr) { } template<typename SubType> +void BinaryenIRWriter<SubType>::visitAtomicFence(AtomicFence* curr) { + emit(curr); +} + +template<typename SubType> void BinaryenIRWriter<SubType>::visitSIMDExtract(SIMDExtract* curr) { visit(curr->vec); if (curr->type == unreachable) { diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 5e9925b63..202d136c8 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -54,6 +54,7 @@ template<typename SubType, typename ReturnType = void> struct Visitor { ReturnType visitAtomicCmpxchg(AtomicCmpxchg* curr) { return ReturnType(); } ReturnType visitAtomicWait(AtomicWait* curr) { return ReturnType(); } ReturnType visitAtomicNotify(AtomicNotify* curr) { return ReturnType(); } + ReturnType visitAtomicFence(AtomicFence* curr) { return ReturnType(); } ReturnType visitSIMDExtract(SIMDExtract* curr) { return ReturnType(); } ReturnType visitSIMDReplace(SIMDReplace* curr) { return ReturnType(); } ReturnType visitSIMDShuffle(SIMDShuffle* curr) { return ReturnType(); } @@ -130,6 +131,8 @@ template<typename SubType, typename ReturnType = void> struct Visitor { DELEGATE(AtomicWait); case Expression::Id::AtomicNotifyId: DELEGATE(AtomicNotify); + case Expression::Id::AtomicFenceId: + DELEGATE(AtomicFence); case Expression::Id::SIMDExtractId: DELEGATE(SIMDExtract); case Expression::Id::SIMDReplaceId: @@ -218,6 +221,7 @@ struct OverriddenVisitor { UNIMPLEMENTED(AtomicCmpxchg); UNIMPLEMENTED(AtomicWait); UNIMPLEMENTED(AtomicNotify); + UNIMPLEMENTED(AtomicFence); UNIMPLEMENTED(SIMDExtract); UNIMPLEMENTED(SIMDReplace); UNIMPLEMENTED(SIMDShuffle); @@ -295,6 +299,8 @@ struct OverriddenVisitor { DELEGATE(AtomicWait); case Expression::Id::AtomicNotifyId: DELEGATE(AtomicNotify); + case Expression::Id::AtomicFenceId: + DELEGATE(AtomicFence); case Expression::Id::SIMDExtractId: DELEGATE(SIMDExtract); case Expression::Id::SIMDReplaceId: @@ -412,6 +418,9 @@ struct UnifiedExpressionVisitor : public Visitor<SubType, ReturnType> { ReturnType visitAtomicNotify(AtomicNotify* curr) { return static_cast<SubType*>(this)->visitExpression(curr); } + ReturnType visitAtomicFence(AtomicFence* curr) { + return static_cast<SubType*>(this)->visitExpression(curr); + } ReturnType visitSIMDExtract(SIMDExtract* curr) { return static_cast<SubType*>(this)->visitExpression(curr); } @@ -711,6 +720,9 @@ struct Walker : public VisitorType { static void doVisitAtomicNotify(SubType* self, Expression** currp) { self->visitAtomicNotify((*currp)->cast<AtomicNotify>()); } + static void doVisitAtomicFence(SubType* self, Expression** currp) { + self->visitAtomicFence((*currp)->cast<AtomicFence>()); + } static void doVisitSIMDExtract(SubType* self, Expression** currp) { self->visitSIMDExtract((*currp)->cast<SIMDExtract>()); } @@ -913,6 +925,10 @@ struct PostWalker : public Walker<SubType, VisitorType> { self->pushTask(SubType::scan, &curr->cast<AtomicNotify>()->ptr); break; } + case Expression::Id::AtomicFenceId: { + self->pushTask(SubType::doVisitAtomicFence, currp); + break; + } case Expression::Id::SIMDExtractId: { self->pushTask(SubType::doVisitSIMDExtract, currp); self->pushTask(SubType::scan, &curr->cast<SIMDExtract>()->vec); diff --git a/src/wasm.h b/src/wasm.h index d4441259e..e7d83ace3 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -468,6 +468,7 @@ public: AtomicCmpxchgId, AtomicWaitId, AtomicNotifyId, + AtomicFenceId, SIMDExtractId, SIMDReplaceId, SIMDShuffleId, @@ -785,6 +786,17 @@ public: void finalize(); }; +class AtomicFence : public SpecificExpression<Expression::AtomicFenceId> { +public: + AtomicFence() = default; + AtomicFence(MixedArena& allocator) : AtomicFence() {} + + // Current wasm threads only supports sequentialy consistent atomics, but + // other orderings may be added in the future. This field is reserved for + // that, and currently set to 0. + uint8_t order = 0; +}; + class SIMDExtract : public SpecificExpression<Expression::SIMDExtractId> { public: SIMDExtract() = default; @@ -1243,7 +1255,7 @@ class Event : public Importable { public: Name name; // Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible. - uint32_t attribute; + uint32_t attribute = WASM_EVENT_ATTRIBUTE_EXCEPTION; // Type string in the format of function type. Return type is considered as a // void type. So if you have an event whose type is (i32, i32), the type // string will be "vii". diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index d75973ab0..b7daeda5a 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2302,6 +2302,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitAtomicNotify(curr, code)) { break; } + if (maybeVisitAtomicFence(curr, code)) { + break; + } throwError("invalid code after atomic prefix: " + std::to_string(code)); break; } @@ -3172,6 +3175,20 @@ bool WasmBinaryBuilder::maybeVisitAtomicNotify(Expression*& out, uint8_t code) { return true; } +bool WasmBinaryBuilder::maybeVisitAtomicFence(Expression*& out, uint8_t code) { + if (code != BinaryConsts::AtomicFence) { + return false; + } + auto* curr = allocator.alloc<AtomicFence>(); + if (debug) { + std::cerr << "zz node: AtomicFence" << std::endl; + } + curr->order = getU32LEB(); + curr->finalize(); + out = curr; + return true; +} + bool WasmBinaryBuilder::maybeVisitConst(Expression*& out, uint8_t code) { Const* curr; if (debug) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 39f6b0a9f..3a1e0db09 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1421,6 +1421,10 @@ Expression* SExpressionWasmBuilder::makeAtomicNotify(Element& s) { return ret; } +Expression* SExpressionWasmBuilder::makeAtomicFence(Element& s) { + return allocator.alloc<AtomicFence>(); +} + static uint8_t parseLaneIndex(const Element* s, size_t lanes) { const char* str = s->c_str(); char* end; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index cb60c50f9..faa06330b 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -422,6 +422,11 @@ void BinaryInstWriter::visitAtomicNotify(AtomicNotify* curr) { emitMemoryAccess(4, 4, 0); } +void BinaryInstWriter::visitAtomicFence(AtomicFence* curr) { + o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicFence) + << int8_t(curr->order); +} + void BinaryInstWriter::visitSIMDExtract(SIMDExtract* curr) { o << int8_t(BinaryConsts::SIMDPrefix); switch (curr->op) { diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 339ad6f68..9b1220371 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -270,6 +270,7 @@ public: void visitAtomicCmpxchg(AtomicCmpxchg* curr); void visitAtomicWait(AtomicWait* curr); void visitAtomicNotify(AtomicNotify* curr); + void visitAtomicFence(AtomicFence* curr); void visitSIMDExtract(SIMDExtract* curr); void visitSIMDReplace(SIMDReplace* curr); void visitSIMDShuffle(SIMDShuffle* curr); @@ -917,6 +918,21 @@ void FunctionValidator::visitAtomicNotify(AtomicNotify* curr) { "AtomicNotify notifyCount type must be i32"); } +void FunctionValidator::visitAtomicFence(AtomicFence* curr) { + shouldBeTrue( + getModule()->memory.exists, curr, "Memory operations require a memory"); + shouldBeTrue(getModule()->features.hasAtomics(), + curr, + "Atomic operation (atomics are disabled)"); + shouldBeFalse(!getModule()->memory.shared, + curr, + "Atomic operation with non-shared memory"); + shouldBeTrue(curr->order == 0, + curr, + "Currently only sequentially consistent atomics are supported, " + "so AtomicFence's order should be 0"); +} + void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) { shouldBeTrue( getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)"); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index f8791286c..b13797c89 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -147,6 +147,8 @@ const char* getExpressionName(Expression* curr) { return "atomic_wait"; case Expression::Id::AtomicNotifyId: return "atomic_notify"; + case Expression::Id::AtomicFenceId: + return "atomic_fence"; case Expression::Id::SIMDExtractId: return "simd_extract"; case Expression::Id::SIMDReplaceId: diff --git a/src/wasm2js.h b/src/wasm2js.h index 624847f7d..54a06578f 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1816,6 +1816,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, unimplemented(curr); WASM_UNREACHABLE(); } + Ref visitAtomicFence(AtomicFence* curr) { + // Sequentially consistent fences can be lowered to no operation + return ValueBuilder::makeToplevel(); + } Ref visitSIMDExtract(SIMDExtract* curr) { unimplemented(curr); WASM_UNREACHABLE(); diff --git a/test/atomics.wast b/test/atomics.wast index 2dcad6459..8ba9906c5 100644 --- a/test/atomics.wast +++ b/test/atomics.wast @@ -158,4 +158,7 @@ ) ) ) + (func $atomic-fence (type $0) + (atomic.fence) + ) ) diff --git a/test/atomics.wast.from-wast b/test/atomics.wast.from-wast index 2869d5da4..c3fdd375d 100644 --- a/test/atomics.wast.from-wast +++ b/test/atomics.wast.from-wast @@ -158,4 +158,7 @@ ) ) ) + (func $atomic-fence (; 4 ;) (type $0) + (atomic.fence) + ) ) diff --git a/test/atomics.wast.fromBinary b/test/atomics.wast.fromBinary index dc5cb0145..78d086a0c 100644 --- a/test/atomics.wast.fromBinary +++ b/test/atomics.wast.fromBinary @@ -158,5 +158,8 @@ ) ) ) + (func $atomic-fence (; 4 ;) (type $0) + (atomic.fence) + ) ) diff --git a/test/atomics.wast.fromBinary.noDebugInfo b/test/atomics.wast.fromBinary.noDebugInfo index 77fb51917..86860c907 100644 --- a/test/atomics.wast.fromBinary.noDebugInfo +++ b/test/atomics.wast.fromBinary.noDebugInfo @@ -158,5 +158,8 @@ ) ) ) + (func $4 (; 4 ;) (type $0) + (atomic.fence) + ) ) diff --git a/test/binaryen.js/atomics.js b/test/binaryen.js/atomics.js index a1f8fc842..40c3ea0ab 100644 --- a/test/binaryen.js/atomics.js +++ b/test/binaryen.js/atomics.js @@ -60,7 +60,30 @@ module.addFunction("main", signature, [], module.block("", [ module.i64.atomic.load32_u(0, module.i32.const(0) ) - ) + ), + // wait and notify + module.drop( + module.i32.atomic.wait( + module.i32.const(0), + module.i32.const(0), + module.i64.const(0) + ) + ), + module.drop( + module.i64.atomic.wait( + module.i32.const(0), + module.i64.const(0), + module.i64.const(0) + ) + ), + module.drop( + module.atomic.notify( + module.i32.const(0), + module.i32.const(0) + ) + ), + // fence + module.atomic.fence() ])); module.setFeatures(Binaryen.Features.Atomics); diff --git a/test/binaryen.js/atomics.js.txt b/test/binaryen.js/atomics.js.txt index 177ba34a6..0a8659acf 100644 --- a/test/binaryen.js/atomics.js.txt +++ b/test/binaryen.js/atomics.js.txt @@ -44,6 +44,27 @@ (i32.const 0) ) ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 0) + ) + ) + (drop + (i64.atomic.wait + (i32.const 0) + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) ) ) diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt index cdf45aeaa..463743ff6 100644 --- a/test/binaryen.js/exception-handling.js.txt +++ b/test/binaryen.js/exception-handling.js.txt @@ -26,7 +26,7 @@ ) ) -getExpressionInfo(throw) = {"id":39,"type":8,"event":"e"} -getExpressionInfo(br_on_exn) = {"id":41,"type":7,"name":"l","event":"e"} -getExpressionInfo(rethrow) = {"id":40,"type":8} -getExpressionInfo(try) = {"id":38,"type":0} +getExpressionInfo(throw) = {"id":40,"type":8,"event":"e"} +getExpressionInfo(br_on_exn) = {"id":42,"type":7,"name":"l","event":"e"} +getExpressionInfo(rethrow) = {"id":41,"type":8} +getExpressionInfo(try) = {"id":39,"type":0} diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index f2a78ab34..89e7fdfc6 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -428,6 +428,28 @@ function test_core() { ) ), + // Atomics + module.i32.atomic.store(0, + module.i32.const(0), + module.i32.atomic.load(0, + module.i32.const(0) + ) + ), + module.drop( + module.i32.atomic.wait( + module.i32.const(0), + module.i32.const(0), + module.i64.const(0) + ) + ), + module.drop( + module.atomic.notify( + module.i32.const(0), + module.i32.const(0) + ) + ), + module.atomic.fence(), + // Push and pop module.push(module.i32.pop()), module.push(module.i64.pop()), @@ -492,7 +514,7 @@ function test_core() { offset: null, data: "I am passive".split('').map(function(x) { return x.charCodeAt(0) }) } - ]); + ], true); // Start function. One per module diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index b1f269a30..d4ca83b1c 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -44,21 +44,21 @@ BinaryenAtomicCmpxchgId: 24 BinaryenAtomicRMWId: 23 BinaryenAtomicWaitId: 25 BinaryenAtomicNotifyId: 26 -BinaryenSIMDExtractId: 27 -BinaryenSIMDReplaceId: 28 -BinaryenSIMDShuffleId: 29 -BinaryenSIMDBitselectId: 30 -BinaryenSIMDShiftId: 31 -MemoryInitId: 32 -DataDropId: 33 -MemoryCopyId: 34 -MemoryFillId: 35 -TryId: 38 -ThrowId: 39 -RethrowId: 40 -BrOnExnId: 41 -PushId: 36 -PopId: 37 +BinaryenSIMDExtractId: 28 +BinaryenSIMDReplaceId: 29 +BinaryenSIMDShuffleId: 30 +BinaryenSIMDBitselectId: 31 +BinaryenSIMDShiftId: 32 +MemoryInitId: 33 +DataDropId: 34 +MemoryCopyId: 35 +MemoryFillId: 36 +TryId: 39 +ThrowId: 40 +RethrowId: 41 +BrOnExnId: 42 +PushId: 37 +PopId: 38 getExpressionInfo={"id":15,"type":3,"op":6} (f32.neg (f32.const -33.61199951171875) @@ -77,7 +77,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} (import "module" "base" (global $a-global-imp i32)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) (import "module" "base" (event $a-event-imp (attr 0) (param i32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 funcref) @@ -1456,6 +1456,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 0) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (push (i32.pop) ) @@ -1496,7 +1516,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} (import "module" "base" (global $a-global-imp i32)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) (import "module" "base" (event $a-event-imp (attr 0) (param i32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 funcref) @@ -2875,6 +2895,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 0) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (push (i32.pop) ) @@ -4775,20 +4815,34 @@ int main() { expressions[665] = BinaryenBlock(the_module, NULL, children, 2, 0); } expressions[666] = BinaryenTry(the_module, expressions[657], expressions[665]); - expressions[667] = BinaryenPop(the_module, 1); - expressions[668] = BinaryenPush(the_module, expressions[667]); - expressions[669] = BinaryenPop(the_module, 2); - expressions[670] = BinaryenPush(the_module, expressions[669]); - expressions[671] = BinaryenPop(the_module, 3); - expressions[672] = BinaryenPush(the_module, expressions[671]); - expressions[673] = BinaryenPop(the_module, 4); - expressions[674] = BinaryenPush(the_module, expressions[673]); - expressions[675] = BinaryenPop(the_module, 5); - expressions[676] = BinaryenPush(the_module, expressions[675]); - expressions[677] = BinaryenPop(the_module, 7); - expressions[678] = BinaryenPush(the_module, expressions[677]); - expressions[679] = BinaryenNop(the_module); - expressions[680] = BinaryenUnreachable(the_module); + expressions[667] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[668] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[669] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[668]); + expressions[670] = BinaryenAtomicStore(the_module, 4, 0, expressions[667], expressions[669], 1); + expressions[671] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[673] = BinaryenConst(the_module, BinaryenLiteralInt64(0)); + expressions[674] = BinaryenAtomicWait(the_module, expressions[671], expressions[672], expressions[673], 1); + expressions[675] = BinaryenDrop(the_module, expressions[674]); + expressions[676] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[677] = BinaryenConst(the_module, BinaryenLiteralInt32(0)); + expressions[678] = BinaryenAtomicNotify(the_module, expressions[676], expressions[677]); + expressions[679] = BinaryenDrop(the_module, expressions[678]); + expressions[680] = BinaryenAtomicFence(the_module); + expressions[681] = BinaryenPop(the_module, 1); + expressions[682] = BinaryenPush(the_module, expressions[681]); + expressions[683] = BinaryenPop(the_module, 2); + expressions[684] = BinaryenPush(the_module, expressions[683]); + expressions[685] = BinaryenPop(the_module, 3); + expressions[686] = BinaryenPush(the_module, expressions[685]); + expressions[687] = BinaryenPop(the_module, 4); + expressions[688] = BinaryenPush(the_module, expressions[687]); + expressions[689] = BinaryenPop(the_module, 5); + expressions[690] = BinaryenPush(the_module, expressions[689]); + expressions[691] = BinaryenPop(the_module, 7); + expressions[692] = BinaryenPush(the_module, expressions[691]); + expressions[693] = BinaryenNop(the_module); + expressions[694] = BinaryenUnreachable(the_module); BinaryenExpressionGetId(expressions[30]); BinaryenExpressionGetType(expressions[30]); BinaryenUnaryGetOp(expressions[30]); @@ -4799,26 +4853,26 @@ getExpressionInfo={"id":15,"type":3,"op":6} (f32.const -33.61199951171875) ) - expressions[681] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); - BinaryenExpressionGetId(expressions[681]); - BinaryenExpressionGetType(expressions[681]); - BinaryenConstGetValueI32(expressions[681]); + expressions[695] = BinaryenConst(the_module, BinaryenLiteralInt32(5)); + BinaryenExpressionGetId(expressions[695]); + BinaryenExpressionGetType(expressions[695]); + BinaryenConstGetValueI32(expressions[695]); getExpressionInfo(i32.const)={"id":14,"type":1,"value":5} - expressions[682] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078)); - BinaryenExpressionGetId(expressions[682]); - BinaryenExpressionGetType(expressions[682]); - BinaryenConstGetValueI64Low(expressions[682]); - BinaryenConstGetValueI64High(expressions[682]); + expressions[696] = BinaryenConst(the_module, BinaryenLiteralInt64(30064771078)); + BinaryenExpressionGetId(expressions[696]); + BinaryenExpressionGetType(expressions[696]); + BinaryenConstGetValueI64Low(expressions[696]); + BinaryenConstGetValueI64High(expressions[696]); getExpressionInfo(i64.const)={"id":14,"type":2,"value":{"low":6,"high":7}} - expressions[683] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5)); - BinaryenExpressionGetId(expressions[683]); - BinaryenExpressionGetType(expressions[683]); - BinaryenConstGetValueF32(expressions[683]); + expressions[697] = BinaryenConst(the_module, BinaryenLiteralFloat32(8.5)); + BinaryenExpressionGetId(expressions[697]); + BinaryenExpressionGetType(expressions[697]); + BinaryenConstGetValueF32(expressions[697]); getExpressionInfo(f32.const)={"id":14,"type":3,"value":8.5} - expressions[684] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5)); - BinaryenExpressionGetId(expressions[684]); - BinaryenExpressionGetType(expressions[684]); - BinaryenConstGetValueF64(expressions[684]); + expressions[698] = BinaryenConst(the_module, BinaryenLiteralFloat64(9.5)); + BinaryenExpressionGetId(expressions[698]); + BinaryenExpressionGetType(expressions[698]); + BinaryenConstGetValueF64(expressions[698]); getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} { BinaryenExpressionRef children[] = { expressions[24], expressions[26], expressions[28], expressions[30], expressions[32], @@ -4862,26 +4916,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} expressions[606], expressions[612], expressions[617], expressions[624], expressions[626], expressions[628], expressions[631], expressions[633], expressions[635], expressions[637], expressions[639], expressions[640], expressions[641], expressions[642], expressions[644], expressions[649], expressions[655], expressions[666], - expressions[668], expressions[670], expressions[672], expressions[674], expressions[676], expressions[678], - expressions[679], expressions[680] }; - expressions[685] = BinaryenBlock(the_module, "the-value", children, 253, 0); + expressions[670], expressions[675], expressions[679], expressions[680], expressions[682], expressions[684], + expressions[686], expressions[688], expressions[690], expressions[692], expressions[693], expressions[694] }; + expressions[699] = BinaryenBlock(the_module, "the-value", children, 257, 0); } - expressions[686] = BinaryenDrop(the_module, expressions[685]); + expressions[700] = BinaryenDrop(the_module, expressions[699]); { - BinaryenExpressionRef children[] = { expressions[686] }; - expressions[687] = BinaryenBlock(the_module, "the-nothing", children, 1, 0); + BinaryenExpressionRef children[] = { expressions[700] }; + expressions[701] = BinaryenBlock(the_module, "the-nothing", children, 1, 0); } - expressions[688] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[702] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); { - BinaryenExpressionRef children[] = { expressions[687], expressions[688] }; - expressions[689] = BinaryenBlock(the_module, "the-body", children, 2, 0); + BinaryenExpressionRef children[] = { expressions[701], expressions[702] }; + expressions[703] = BinaryenBlock(the_module, "the-body", children, 2, 0); } { BinaryenType varTypes[] = { 1, 7 }; - functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[689]); + functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[1], varTypes, 2, expressions[703]); } - expressions[690] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); - globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[690]); + expressions[704] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); + globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[704]); { BinaryenType paramTypes[] = { 1, 4 }; functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2); @@ -4910,24 +4964,24 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} const char* funcNames[] = { "kitchen()sinker" }; BinaryenSetFunctionTable(the_module, 1, 4294967295, funcNames, 1); } - expressions[691] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[705] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[691], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[705], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; - BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0); + BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } { BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[692] = BinaryenNop(the_module); + expressions[706] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[692]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[706]); } BinaryenSetStart(the_module, functions[1]); { @@ -4947,7 +5001,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} (import "module" "base" (global $a-global-imp i32)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) (import "module" "base" (event $a-event-imp (attr 0) (param i32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 funcref) @@ -6326,6 +6380,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 0) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (push (i32.pop) ) @@ -6368,7 +6442,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} (import "module" "base" (global $a-global-imp i32)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) (import "module" "base" (event $a-event-imp (attr 0) (param i32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 funcref) @@ -7747,6 +7821,26 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 0) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (push (i32.pop) ) diff --git a/test/binaryen.js/push-pop.js.txt b/test/binaryen.js/push-pop.js.txt index c9689831f..80166906a 100644 --- a/test/binaryen.js/push-pop.js.txt +++ b/test/binaryen.js/push-pop.js.txt @@ -22,10 +22,10 @@ ) ) -getExpressionInfo(i32.pop) = {"id":37,"type":1} -getExpressionInfo(i64.pop) = {"id":37,"type":2} -getExpressionInfo(f32.pop) = {"id":37,"type":3} -getExpressionInfo(f64.pop) = {"id":37,"type":4} -getExpressionInfo(v128.pop) = {"id":37,"type":5} -getExpressionInfo(exnref.pop) = {"id":37,"type":7} -getExpressionInfo(push) = {"id":36} +getExpressionInfo(i32.pop) = {"id":38,"type":1} +getExpressionInfo(i64.pop) = {"id":38,"type":2} +getExpressionInfo(f32.pop) = {"id":38,"type":3} +getExpressionInfo(f64.pop) = {"id":38,"type":4} +getExpressionInfo(v128.pop) = {"id":38,"type":5} +getExpressionInfo(exnref.pop) = {"id":38,"type":7} +getExpressionInfo(push) = {"id":37} diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 3d9d42fa1..77349529b 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -520,6 +520,16 @@ void test_core() { module, makeInt32(module, 2449), callOperands4b, 4, "iiIfF"), // Exception handling BinaryenTry(module, tryBody, catchBody), + // Atomics + BinaryenAtomicStore(module, 4, 0, temp6, + BinaryenAtomicLoad(module, 4, 0, BinaryenTypeInt32(), temp6), + BinaryenTypeInt32() + ), + BinaryenDrop(module, + BinaryenAtomicWait(module, temp6, temp6, temp16, BinaryenTypeInt32()) + ), + BinaryenDrop(module, BinaryenAtomicNotify(module, temp6, temp6)), + BinaryenAtomicFence(module), // TODO: Host BinaryenNop(module), @@ -565,7 +575,7 @@ void test_core() { int8_t segmentPassive[] = { 0, 1 }; BinaryenExpressionRef segmentOffsets[] = { BinaryenConst(module, BinaryenLiteralInt32(10)), NULL }; BinaryenIndex segmentSizes[] = { 12, 12 }; - BinaryenSetMemory(module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0); + BinaryenSetMemory(module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); // Start function. One per module diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index a46190fb4..a5c300653 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -27,7 +27,7 @@ BinaryenFeatureAll: 511 (type $v (func)) (type $4 (func)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 1 funcref) @@ -1414,6 +1414,26 @@ BinaryenFeatureAll: 511 ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 111) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (nop) (unreachable) ) @@ -3310,8 +3330,15 @@ int main() { expressions[658] = BinaryenReturnCallIndirect(the_module, expressions[657], operands, 4, "iiIfF"); } expressions[659] = BinaryenTry(the_module, expressions[35], expressions[43]); - expressions[660] = BinaryenNop(the_module); - expressions[661] = BinaryenUnreachable(the_module); + expressions[660] = BinaryenAtomicLoad(the_module, 4, 0, 1, expressions[23]); + expressions[661] = BinaryenAtomicStore(the_module, 4, 0, expressions[23], expressions[660], 1); + expressions[662] = BinaryenAtomicWait(the_module, expressions[23], expressions[23], expressions[33], 1); + expressions[663] = BinaryenDrop(the_module, expressions[662]); + expressions[664] = BinaryenAtomicNotify(the_module, expressions[23], expressions[23]); + expressions[665] = BinaryenDrop(the_module, expressions[664]); + expressions[666] = BinaryenAtomicFence(the_module); + expressions[667] = BinaryenNop(the_module); + expressions[668] = BinaryenUnreachable(the_module); BinaryenExpressionPrint(expressions[51]); (f32.neg (f32.const -33.61199951171875) @@ -3358,27 +3385,27 @@ int main() { expressions[627], expressions[629], expressions[632], expressions[635], expressions[637], expressions[639], expressions[642], expressions[644], expressions[646], expressions[648], expressions[650], expressions[651], expressions[652], expressions[653], expressions[655], expressions[656], expressions[658], expressions[659], - expressions[660], expressions[661] }; - expressions[662] = BinaryenBlock(the_module, "the-value", children, 247, BinaryenTypeAuto()); + expressions[661], expressions[663], expressions[665], expressions[666], expressions[667], expressions[668] }; + expressions[669] = BinaryenBlock(the_module, "the-value", children, 251, BinaryenTypeAuto()); } - expressions[663] = BinaryenDrop(the_module, expressions[662]); + expressions[670] = BinaryenDrop(the_module, expressions[669]); { - BinaryenExpressionRef children[] = { expressions[663] }; - expressions[664] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto()); + BinaryenExpressionRef children[] = { expressions[670] }; + expressions[671] = BinaryenBlock(the_module, "the-nothing", children, 1, BinaryenTypeAuto()); } - expressions[665] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); + expressions[672] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); { - BinaryenExpressionRef children[] = { expressions[664], expressions[665] }; - expressions[666] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto()); + BinaryenExpressionRef children[] = { expressions[671], expressions[672] }; + expressions[673] = BinaryenBlock(the_module, "the-body", children, 2, BinaryenTypeAuto()); } { BinaryenType varTypes[] = { 1, 7 }; - functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[666]); + functions[0] = BinaryenAddFunction(the_module, "kitchen()sinker", functionTypes[0], varTypes, 2, expressions[673]); } - expressions[667] = BinaryenConst(the_module, BinaryenLiteralInt32(7)); - globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[667]); - expressions[668] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5)); - globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[668]); + expressions[674] = BinaryenConst(the_module, BinaryenLiteralInt32(7)); + globals[0] = BinaryenAddGlobal(the_module, "a-global", 1, 0, expressions[674]); + expressions[675] = BinaryenConst(the_module, BinaryenLiteralFloat32(7.5)); + globals[1] = BinaryenAddGlobal(the_module, "a-mutable-global", 3, 1, expressions[675]); { BinaryenType paramTypes[] = { 1, 4 }; functionTypes[2] = BinaryenAddFunctionType(the_module, "fiF", 3, paramTypes, 2); @@ -3390,24 +3417,24 @@ int main() { const char* funcNames[] = { "kitchen()sinker" }; BinaryenSetFunctionTable(the_module, 1, 1, funcNames, 1); } - expressions[669] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); + expressions[676] = BinaryenConst(the_module, BinaryenLiteralInt32(10)); { const char segment0[] = { 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100 }; const char segment1[] = { 73, 32, 97, 109, 32, 112, 97, 115, 115, 105, 118, 101 }; const char* segments[] = { segment0, segment1 }; int8_t segmentPassive[] = { 0, 1 }; - BinaryenExpressionRef segmentOffsets[] = { expressions[669], expressions[0] }; + BinaryenExpressionRef segmentOffsets[] = { expressions[676], expressions[0] }; BinaryenIndex segmentSizes[] = { 12, 12 }; - BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 0); + BinaryenSetMemory(the_module, 1, 256, "mem", segments, segmentPassive, segmentOffsets, segmentSizes, 2, 1); } { BinaryenType paramTypes[] = { 0 }; functionTypes[3] = BinaryenAddFunctionType(the_module, "v", 0, paramTypes, 0); } - expressions[670] = BinaryenNop(the_module); + expressions[677] = BinaryenNop(the_module); { BinaryenType varTypes[] = { 0 }; - functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[670]); + functions[1] = BinaryenAddFunction(the_module, "starter", functionTypes[3], varTypes, 0, expressions[677]); } BinaryenSetStart(the_module, functions[1]); { @@ -3426,7 +3453,7 @@ int main() { (type $v (func)) (type $4 (func)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 1 funcref) @@ -4813,6 +4840,26 @@ int main() { ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 111) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (nop) (unreachable) ) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index 181b16718..792656d96 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -8,7 +8,7 @@ (type $v (func)) (type $4 (func)) (import "module" "base" (func $an-imported (param i32 f64) (result f32))) - (memory $0 1 256) + (memory $0 (shared 1 256)) (data (i32.const 10) "hello, world") (data passive "I am passive") (table $0 1 1 funcref) @@ -1395,6 +1395,26 @@ ) ) ) + (i32.atomic.store + (i32.const 0) + (i32.atomic.load + (i32.const 0) + ) + ) + (drop + (i32.atomic.wait + (i32.const 0) + (i32.const 0) + (i64.const 111) + ) + ) + (drop + (atomic.notify + (i32.const 0) + (i32.const 0) + ) + ) + (atomic.fence) (nop) (unreachable) ) diff --git a/test/passes/translate-to-fuzz_all-features.txt b/test/passes/translate-to-fuzz_all-features.txt index efbe0c232..a0481ba60 100644 --- a/test/passes/translate-to-fuzz_all-features.txt +++ b/test/passes/translate-to-fuzz_all-features.txt @@ -9,10 +9,9 @@ (import "fuzzing-support" "log-i64" (func $log-i64 (param i64))) (import "fuzzing-support" "log-f32" (func $log-f32 (param f32))) (import "fuzzing-support" "log-f64" (func $log-f64 (param f64))) - (memory $0 (shared 1 1)) + (memory $0 1 1) (data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3") - (table $0 3 3 funcref) - (elem (i32.const 0) $func_5 $func_5 $func_5) + (table $0 0 funcref) (global $global$0 (mut i32) (i32.const 975663930)) (global $global$1 (mut i32) (i32.const 2066300474)) (global $global$2 (mut i64) (i64.const 20510)) @@ -276,341 +275,20 @@ ) (block $label$0 (br_if $label$0 - (i32.const 1376786182) - ) - (local.set $4 - (v128.const i32x4 0x0e0a0e0d 0x0709060c 0x764b6f6f 0x00040000) - ) - (local.set $4 - (if (result v128) - (i32.eqz - (if (result i32) - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (if - (i32.const 1329942351) - (local.tee $2 - (local.tee $2 - (loop $label$38 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (if - (i32.eqz - (local.get $2) - ) - (block $label$39 - (nop) - (br $label$0) - ) - (block $label$40 - (local.set $4 - (v128.const i32x4 0x05050505 0x46190000 0xc6800000 0x4a031a19) - ) - (br $label$0) - ) - ) - ) - ) - ) - (block $label$41 - (nop) - (br $label$0) - ) - ) - ) - (local.get $2) - (local.get $2) - ) - ) - (block $label$47 - (local.set $2 - (local.get $2) - ) - (br $label$0) - ) - (block $label$48 (result i32) - (loop $label$49 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (local.set $5 - (f32.const 9.625223197211503e-38) - ) - (br_if $label$49 - (if (result i32) - (block $label$57 - (local.set $5 - (local.tee $5 - (block $label$58 (result f32) - (local.set $4 - (local.get $4) - ) - (local.get $5) - ) - ) - ) - (br $label$0) - ) - (if (result i32) - (i32.const 1376786182) - (block $label$60 - (if - (block $label$61 (result i32) - (i32.const 925442358) - ) - (block $label$62 - (br_if $label$62 - (i32.const 256) - ) - ) - (block $label$63 - (if - (local.get $2) - (local.set $1 - (local.get $1) - ) - (block $label$67 - (if - (i32.eqz - (i32.const 0) - ) - (block $label$68 - (local.set $1 - (local.get $1) - ) - (block $label$69 - (nop) - (local.set $4 - (local.get $4) - ) - ) - ) - (if - (i32.eqz - (br_if $label$48 - (i32.const 32768) - (local.get $2) - ) - ) - (local.set $4 - (v128.const i32x4 0xffffff81 0xffffffeb 0x80000000 0x74273131) - ) - (local.set $2 - (local.get $2) - ) - ) - ) - (local.set $0 - (i64.const -2097152) - ) - ) - ) - (local.set $1 - (local.get $1) - ) - ) - ) - (br $label$0) - ) - (block $label$70 (result i32) - (loop $label$71 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (loop $label$72 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.set $4 - (local.tee $4 - (local.get $4) - ) - ) - ) - (br_if $label$71 - (i32.eqz - (loop $label$73 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$74 - (local.set $4 - (v128.const i32x4 0xf8f8ff00 0x000000a5 0x0000000e 0xffff00ff) - ) - (br $label$73) - ) - ) - ) - ) - (i32.const -131072) - ) - ) - ) - ) - (if (result i32) - (local.get $2) - (block $label$75 - (call $log-i32 - (local.tee $2 - (i32.const 5) - ) - ) - (br $label$49) - ) - (block $label$76 (result i32) - (nop) - (local.tee $2 - (i32.const 1276448839) - ) - ) - ) - ) - ) - (local.set $2 - (local.get $2) - ) - ) - ) - (loop $label$90 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (local.set $1 - (local.get $1) - ) - (br_if $label$90 - (i32.eqz - (local.tee $2 - (i32.const -93) - ) - ) - ) - (nop) - ) - ) - (local.get $2) - ) - ) - (block $label$91 (result i32) - (local.set $5 - (block $label$92 (result f32) - (local.set $1 - (loop $label$19 (result f64) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result f64) - (nop) - (br_if $label$19 - (i32.eqz - (i32.const -129) - ) - ) - (local.tee $1 - (f64.const -nan:0xffffffffffff0) - ) - ) - ) - ) - (local.get $5) - ) - ) - (local.get $2) - ) - (block $label$95 (result i32) - (local.get $2) + (i32.eqz + (local.tee $2 + (local.tee $2 + (local.tee $2 + (i32.const 512) ) ) ) - (local.get $4) - (block $label$96 (result v128) - (v128.const i32x4 0x80800000 0xdf800000 0xcf000000 0x4f800000) - ) ) ) + (local.set $4 + (v128.const i32x4 0x0e0a0e0d 0x0709060c 0x764b6f6f 0x00040000) + ) + (nop) ) ) (func $hangLimitInitializer (; 6 ;) diff --git a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt b/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt index ba8dec2d4..91ed6ceca 100644 --- a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt +++ b/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt @@ -9,7 +9,7 @@ (import "fuzzing-support" "log-i64" (func $log-i64 (param i64))) (import "fuzzing-support" "log-f32" (func $log-f32 (param f32))) (import "fuzzing-support" "log-f64" (func $log-f64 (param f64))) - (memory $0 (shared 1 1)) + (memory $0 1 1) (data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3") (table $0 0 funcref) (global $global$0 (mut i32) (i32.const 975663930)) @@ -20,6 +20,7 @@ (event $event$0 (attr 0) (param i32 f32 i32 f64 i32)) (export "hashMemory" (func $hashMemory)) (export "memory" (memory $0)) + (export "func_5" (func $func_5)) (export "hangLimitInitializer" (func $hangLimitInitializer)) (func $hashMemory (; 4 ;) (type $FUNCSIG$i) (result i32) (local $0 i32) @@ -252,7 +253,7 @@ ) (local.get $0) ) - (func $func_5 (; 5 ;) (param $0 i64) + (func $func_5 (; 5 ;) (type $FUNCSIG$vj) (param $0 i64) (local $1 f64) (local $2 i32) (local $3 i64) @@ -293,235 +294,306 @@ (if (result v128) (i32.eqz (if (result i32) - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (if - (i32.eqz - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (if (result i32) - (local.get $2) - (loop $label$1 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (i32.eqz + (if (result i32) + (i32.eqz + (if (result i32) + (if (result i32) + (if (result i32) + (i32.eqz + (if + (i32.eqz + (if (result i32) + (local.get $2) + (loop $label$1 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) + (return) ) - (block (result i32) - (block $label$2 - (local.set $3 - (i64.const 15662) - ) - (local.set $2 - (local.get $2) - ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) ) - (br_if $label$1 - (local.get $2) + ) + ) + (block (result i32) + (block $label$2 + (local.set $3 + (i64.const 15662) ) - (if (result i32) - (i32.eqz - (local.get $2) + (local.set $2 + (local.tee $2 + (i32.const 1010006831) ) - (local.get $2) + ) + ) + (br_if $label$1 + (local.get $2) + ) + (if (result i32) + (i32.eqz (local.get $2) ) + (local.get $2) + (local.get $2) ) ) - (block $label$3 (result i32) - (local.tee $2 - (i32.const 286267661) - ) + ) + (block $label$3 (result i32) + (local.tee $2 + (i32.const 286267661) ) ) ) - (block $label$4 - (loop $label$5 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + ) + (block $label$4 + (loop $label$5 + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) ) ) - (block - (block $label$6 - (if - (i32.eqz - (loop $label$7 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + ) + (block + (block $label$6 + (if + (i32.eqz + (loop $label$7 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) ) ) - (i32.const 6506) ) - ) - (block $label$8 - (local.set $2 - (local.tee $2 - (local.get $2) + (block (result i32) + (local.set $1 + (f64.const -131072) + ) + (br_if $label$7 + (i32.const 387334656) ) + (local.get $2) ) - (local.set $5 - (local.get $5) + ) + ) + (block $label$8 + (local.set $2 + (local.tee $2 + (local.get $2) ) ) - (block $label$9 - (if - (local.tee $2 - (if (result i32) - (local.get $2) - (local.get $2) - (loop $label$10 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + (local.set $5 + (local.get $5) + ) + ) + (block $label$9 + (if + (local.tee $2 + (if (result i32) + (i32.const 1899592761) + (local.get $2) + (loop $label$10 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) ) ) - (block (result i32) - (nop) - (br_if $label$10 - (i32.eqz - (i32.const 64) - ) + ) + (block (result i32) + (nop) + (br_if $label$10 + (i32.eqz + (i32.const 64) ) - (local.tee $2 - (loop $label$11 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + ) + (local.tee $2 + (loop $label$11 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) ) ) - (i32.const 512) ) + (i32.const 512) ) ) ) ) ) - (local.set $3 - (local.get $3) - ) - (loop $label$12 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + ) + (local.set $3 + (local.get $3) + ) + (loop $label$12 + (block + (if + (i32.eqz + (global.get $hangLimit) ) + (return) ) - (local.set $1 - (local.get $1) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) ) ) - ) - (local.set $2 - (i32.const 170) + (local.set $1 + (local.get $1) + ) ) ) - ) - (call $log-i32 - (local.get $2) + (local.set $2 + (i32.const 170) + ) ) ) - (br_if $label$5 - (i32.eqz - (i32.const 2376257) - ) + (call $log-i32 + (i32.const 0) ) - (local.set $4 - (local.tee $4 - (v128.const i32x4 0xfff70000 0x007f700e 0x07420400 0x8000007f) - ) + ) + (br_if $label$5 + (i32.eqz + (i32.const 2376257) + ) + ) + (local.set $4 + (local.tee $4 + (v128.const i32x4 0xfff70000 0x007f700e 0x07420400 0x8000007f) ) ) ) - (block $label$13 - (if - (i32.eqz - (block $label$14 (result i32) - (local.set $4 - (v128.const i32x4 0x80000000 0x00000080 0xfffffffc 0x00007fff) - ) - (i32.const -123) + ) + (block $label$13 + (if + (i32.eqz + (block $label$14 (result i32) + (local.set $4 + (v128.const i32x4 0x80000000 0x00000080 0xfffffffc 0x00007fff) ) + (i32.const -123) ) - (local.set $1 - (local.get $1) + ) + (block $label$15 + (local.set $4 + (v128.const i32x4 0x00200000 0xc1e00000 0x00000000 0xc3e00000) ) - (local.set $5 - (local.get $5) + (local.set $4 + (v128.const i32x4 0x01ef00e4 0x7009efff 0x53000c13 0x0000153a) + ) + ) + (block $label$16 + (if + (local.get $2) + (local.set $0 + (local.tee $3 + (local.get $3) + ) + ) + (if + (i32.eqz + (local.get $2) + ) + (local.set $5 + (f32.const 12732744) + ) + (local.set $0 + (local.get $3) + ) + ) ) ) - (br $label$0) ) + (br $label$0) ) - (block $label$17 (result i32) - (i64.atomic.store offset=3 - (i32.const 640629291) - (local.tee $0 - (i64.const -16) - ) + ) + (block $label$17 + (if + (i32.eqz + (local.get $2) ) - (if (result i32) - (block $label$18 - (local.set $1 - (loop $label$19 (result f64) + (block $label$18 + (if + (local.tee $2 + (i32.const 127) + ) + (block $label$19 + (local.set $4 + (v128.const i32x4 0x0000001b 0x00000014 0x161b00bf 0x00402000) + ) + (local.set $1 + (f64.const 0) + ) + ) + (block $label$20 + (local.set $3 + (i64.const -67108864) + ) + (local.set $5 + (local.get $5) + ) + ) + ) + (loop $label$21 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (local.set $4 + (local.get $4) + ) + (br_if $label$21 + (i32.const 85) + ) + (loop $label$22 (block (if (i32.eqz @@ -536,61 +608,113 @@ ) ) ) - (block (result f64) - (nop) - (br_if $label$19 + (block + (local.set $1 + (local.get $1) + ) + (br_if $label$22 (i32.eqz - (local.get $2) + (block $label$23 + (nop) + (br $label$21) + ) ) ) - (local.tee $1 - (f64.const 0) - ) + (nop) ) ) ) - (return) ) - (local.tee $2 - (local.get $2) + ) + (block $label$24 + (loop $label$25 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (local.set $0 + (local.get $0) + ) + (br_if $label$25 + (i32.const -67108864) + ) + (local.set $5 + (local.get $5) + ) + ) ) - (block $label$20 - (loop $label$21 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + (loop $label$26 + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (local.set $3 + (i64.const 128) + ) + (br_if $label$26 + (block $label$27 (result i32) + (local.set $4 + (v128.const i32x4 0x01010101 0x00000000 0x00000059 0x00000000) ) + (local.get $2) ) ) - (local.set $1 - (local.get $1) + (local.set $3 + (loop $label$28 (result i64) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (i64.const 246) + ) ) ) - (return) ) ) ) + (br $label$0) ) ) - (block $label$22 (result i32) - (local.set $5 - (f32.const 10160664) - ) - (if (result i32) + ) + (i32.const -31) + (block $label$29 (result i32) + (local.tee $3 + (if (i32.eqz - (i32.const 0) - ) - (block $label$23 - (local.set $1 - (loop $label$24 (result f64) + (br_if $label$29 + (loop $label$30 (result i32) (block (if (i32.eqz @@ -605,52 +729,133 @@ ) ) ) - (block (result f64) - (local.set $3 - (local.get $0) + (block (result i32) + (local.set $5 + (f32.const 49) ) - (br_if $label$24 - (i32.const -9) + (br_if $label$30 + (local.get $2) ) - (f64.const -18446744073709551615) + (local.get $2) ) ) + (local.tee $2 + (i32.const 342496264) + ) ) - (br $label$0) ) - (block $label$25 (result i32) - (loop $label$26 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) + (block $label$32 + (call $log-i32 + (call $hashMemory) + ) + (block + (block $label$33 + (local.set $3 + (i64.const -65535) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) + (br $label$0) + ) + (drop + (local.get $2) + ) + ) + ) + (if + (i32.const -32768) + (block $label$34 + (br $label$0) + ) + (block $label$35 + (block $label$36 + (local.set $3 + (local.get $3) + ) + (local.set $4 + (local.get $4) ) ) - (block - (local.set $2 - (local.get $2) + (br $label$0) + ) + ) + ) + ) + (local.get $2) + ) + ) + (block $label$37 (result i32) + (loop $label$38 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (block $label$39 + (local.set $5 + (f32.const 1.1754943508222875e-38) + ) + (local.set $2 + (i32.const -65535) + ) + ) + (br_if $label$38 + (loop $label$40 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (br_if $label$26 - (i32.eqz - (if (result i32) - (br_if $label$25 - (i32.const -8) - (local.get $2) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$41 + (local.set $0 + (local.tee $3 + (local.tee $3 + (local.get $0) + ) + ) + ) + (call $log-i32 + (call $hashMemory) + ) + ) + (br_if $label$40 + (loop $label$42 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) ) - (local.get $2) - (block $label$29 (result i32) - (call $log-i32 - (call $hashMemory) - ) - (loop $label$30 (result i32) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$43 + (local.set $4 + (loop $label$44 (result v128) (block (if (i32.eqz @@ -665,67 +870,394 @@ ) ) ) - (local.get $2) + (v128.const i32x4 0x00000000 0x40d1c680 0xffffffff 0xffefffff) + ) + ) + (nop) + ) + (br_if $label$42 + (loop $label$45 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (local.set $5 + (local.get $5) + ) + (br_if $label$45 + (i32.const 101975070) + ) + (block $label$46 + (br $label$45) + ) ) ) ) + (local.tee $2 + (i32.const 32768) + ) ) ) - (local.set $5 + ) + (local.get $2) + ) + ) + ) + (loop $label$47 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (drop + (v128.const i32x4 0x0000007f 0x00000000 0x372e2e2e 0x35373022) + ) + (br_if $label$47 + (i32.eqz + (local.get $2) + ) + ) + (local.set $5 + (local.tee $5 + (if (result f32) + (local.get $2) + (f32.const -8) (local.get $5) ) ) ) - (local.get $2) ) ) ) - (block $label$35 - (local.set $1 - (f64.const 1414944843) - ) - (br $label$0) - ) ) - ) - (local.tee $2 (local.tee $2 - (loop $label$38 - (block - (if - (i32.eqz - (global.get $hangLimit) + (local.tee $2 + (local.tee $2 + (local.tee $2 + (local.tee $2 + (local.get $2) ) - (return) ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) + ) + ) + ) + ) + (block $label$48 + (local.set $5 + (local.tee $5 + (local.tee $5 + (block $label$49 (result f32) + (local.set $4 + (local.get $4) ) + (local.get $5) ) ) - (if + ) + ) + (br $label$0) + ) + ) + (block $label$50 (result i32) + (if + (i32.eqz + (i32.const 2097152) + ) + (if + (i32.eqz + (if (result i32) (i32.eqz - (local.get $2) + (loop $label$51 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$52 + (local.set $5 + (local.tee $5 + (local.get $5) + ) + ) + (local.set $0 + (i64.const 128) + ) + ) + (br_if $label$51 + (i32.const 2) + ) + (i32.const 1667136122) + ) + ) ) - (block $label$39 - (nop) + (block $label$53 + (drop + (if (result f32) + (i32.eqz + (if (result i32) + (i32.eqz + (local.tee $2 + (br_if $label$50 + (local.get $2) + (local.get $2) + ) + ) + ) + (br_if $label$50 + (local.get $2) + (i32.const 8192) + ) + (local.get $2) + ) + ) + (block $label$54 (result f32) + (local.set $4 + (v128.const i32x4 0x040f1919 0x00800000 0x4a000000 0x00000000) + ) + (local.tee $5 + (f32.const 1.1754943508222875e-38) + ) + ) + (if (result f32) + (loop $label$55 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (local.tee $2 + (local.tee $2 + (i32.const 470239259) + ) + ) + ) + (local.get $5) + (f32.const 20288) + ) + ) + ) (br $label$0) ) - (block $label$40 - (local.set $1 - (local.get $1) + (block $label$56 (result i32) + (br_if $label$0 + (i32.eqz + (br_if $label$56 + (i32.const 4096) + (i32.const 1048576) + ) + ) ) (br $label$0) ) ) ) + (block $label$57 + (block $label$58 + (local.set $0 + (local.tee $0 + (local.get $3) + ) + ) + (loop $label$59 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (block $label$60 + (local.set $5 + (f32.const 1.7096404532038735e-33) + ) + (data.drop 0) + ) + (br_if $label$59 + (i32.eqz + (i32.const 235539981) + ) + ) + (local.set $5 + (local.tee $5 + (f32.const 1364283776) + ) + ) + ) + ) + ) + (block $label$61 + (local.set $4 + (v128.const i32x4 0x21474459 0xff7fffff 0x4cc3ca60 0x4b800000) + ) + (local.set $2 + (i32.const 32767) + ) + ) + ) + (block $label$62 + (local.set $2 + (if (result i32) + (loop $label$63 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$64 + (if + (local.get $2) + (nop) + (nop) + ) + (block $label$65 + (local.set $0 + (local.get $0) + ) + (local.set $2 + (local.get $2) + ) + ) + ) + (br_if $label$63 + (br_if $label$50 + (local.get $2) + (i32.eqz + (local.get $2) + ) + ) + ) + (local.get $2) + ) + ) + (br_if $label$50 + (i32.const -86) + (i32.eqz + (if (result i32) + (i32.const -8192) + (i32.const 437327895) + (i32.const 32767) + ) + ) + ) + (block $label$66 + (local.set $4 + (v128.const i32x4 0x00000070 0x31313113 0x0000780c 0xffff8000) + ) + (loop $label$67 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$68 + (local.set $4 + (v128.const i32x4 0x657b077d 0x1113ff82 0x6c650000 0x0000fff8) + ) + (br $label$62) + ) + ) + ) + ) + ) + (local.set $5 + (local.get $5) + ) + ) + ) + (block $label$69 + (local.set $1 + (local.get $1) + ) + (local.set $1 + (local.get $1) + ) + ) + ) + (local.tee $2 + (local.tee $2 + (local.tee $2 + (local.tee $2 + (local.tee $2 + (local.tee $2 + (i32.const 32) + ) + ) + ) + ) ) ) - (block $label$41 - (memory.copy - (loop $label$42 (result i32) + ) + (block $label$70 (result i32) + (if + (i32.eqz + (loop $label$71 (result i32) (block (if (i32.eqz @@ -740,8 +1272,93 @@ ) ) ) - (if (result i32) - (loop $label$43 (result i32) + (block (result i32) + (memory.fill + (i32.and + (if (result i32) + (f32.gt + (local.get $5) + (local.tee $5 + (f32.const 504699424) + ) + ) + (block $label$72 + (local.set $2 + (i32.const -4) + ) + (br $label$0) + ) + (local.tee $2 + (i32.const 825172795) + ) + ) + (i32.const 15) + ) + (i32.and + (local.tee $2 + (i32.const -32768) + ) + (i32.const 15) + ) + (block $label$73 (result i32) + (loop $label$74 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (block $label$75 + (local.set $4 + (local.get $4) + ) + (br_if $label$71 + (i32.const 359954033) + ) + ) + (br_if $label$74 + (i32.eqz + (local.get $2) + ) + ) + (local.set $5 + (local.get $5) + ) + ) + ) + (i32.const -127) + ) + ) + (br_if $label$71 + (i32.eqz + (i32.const 0) + ) + ) + (i32.const 0) + ) + ) + ) + (block $label$76 + (if + (i32.eqz + (block $label$77 + (local.set $5 + (local.get $5) + ) + (br $label$0) + ) + ) + (br_if $label$76 + (loop $label$78 (result i32) (block (if (i32.eqz @@ -756,119 +1373,128 @@ ) ) ) - (block $label$44 (result i32) - (local.set $3 - (i64.const 2097574720517510216) + (block (result i32) + (local.tee $2 + (block $label$79 + (local.set $2 + (local.tee $2 + (i32.const 1196248392) + ) + ) + (br $label$76) + ) ) - (if (result i32) + (br_if $label$78 (i32.eqz - (local.get $2) - ) - (i32.const 1296450369) - (local.tee $2 - (i32.const -14) + (i32.const 0) ) ) + (local.get $2) + ) + ) + ) + (local.set $1 + (local.tee $1 + (f64.const -2147483648) + ) + ) + ) + (local.set $4 + (local.tee $4 + (local.tee $4 + (local.tee $4 + (local.tee $4 + (local.get $4) + ) ) ) - (block $label$45 - (local.set $2 - (i32.const 235407412) + ) + ) + ) + (block $label$80 + (block $label$81 + (local.set $4 + (local.tee $4 + (local.tee $4 + (v128.const i32x4 0x080f185d 0x46aca200 0x41800000 0x4b060a0c) ) - (br $label$0) ) - (block $label$46 (result i32) - (local.set $2 - (local.tee $2 - (local.tee $2 - (local.tee $2 - (i32.const 1179009606) + ) + (block $label$82 + (if + (i32.eqz + (br_if $label$70 + (br_if $label$70 + (i32.const -65536) + (i32.eqz + (i32.const 757217343) ) ) + (i32.const -65535) + ) + ) + (local.set $3 + (local.tee $0 + (local.get $3) ) ) - (i32.const 1073741824) + (block $label$83 + (local.set $0 + (if (result i64) + (local.get $2) + (block $label$84 + (local.set $5 + (f32.const 119) + ) + (br $label$82) + ) + (local.get $0) + ) + ) + (local.set $3 + (block $label$85 (result i64) + (local.set $3 + (i64.const -82) + ) + (local.get $3) + ) + ) + ) + ) + (local.set $5 + (local.get $5) ) ) ) - (local.get $2) - (i32.const 1073741824) + (local.set $5 + (f32.const 10282366454988800) + ) ) - (return) ) - ) - ) - (local.get $2) - (local.get $2) - ) - ) - (block $label$47 - (local.set $2 - (local.get $2) - ) - (br $label$0) - ) - (block $label$48 (result i32) - (loop $label$49 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.set $5 - (local.get $5) - ) - ) - (loop $label$90 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (local.set $1 - (local.get $1) - ) - (local.set $2 (local.get $2) ) - (nop) ) ) (local.get $2) - ) - ) - (block $label$91 (result i32) - (local.set $5 - (block $label$92 (result f32) - (f32.const 6) + (block $label$88 (result i32) + (i32.const -16) ) ) + ) + (block $label$89 (result i32) + (local.get $2) + ) + (block $label$90 (result i32) (local.get $2) ) - (local.get $2) ) ) - (v128.const i32x4 0xffffffc0 0x00001f16 0x00008000 0x505c1a13) - (v128.const i32x4 0xc7007b11 0x721d0901 0x01810043 0x441f1201) + (block $label$91 (result v128) + (v128.const i32x4 0x00000000 0x41600000 0x00000000 0x42400000) + ) + (block $label$92 (result v128) + (v128.const i32x4 0x00000001 0x00001d6e 0x4f0affed 0x00020054) + ) ) ) ) diff --git a/test/spec/atomics.wast b/test/spec/atomics.wast new file mode 100644 index 000000000..4e6dd3563 --- /dev/null +++ b/test/spec/atomics.wast @@ -0,0 +1,8 @@ +(module + (memory $0 (shared 23 256)) + (func (export "atomic-fence") + (atomic.fence) + ) +) + +(assert_return (invoke "atomic-fence")) |