diff options
-rwxr-xr-x | scripts/fuzz_opt.py | 2 | ||||
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/DeNaN.cpp | 96 | ||||
-rw-r--r-- | src/passes/pass.cpp | 3 | ||||
-rw-r--r-- | src/passes/passes.h | 1 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 158 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 8 | ||||
-rw-r--r-- | test/passes/denan.txt | 44 | ||||
-rw-r--r-- | test/passes/denan.wast | 10 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt | 1342 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_no-fuzz-nans_all-features.wast | 99 |
11 files changed, 211 insertions, 1553 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index c6a424eb3..e16c6c320 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -127,7 +127,7 @@ def randomize_fuzz_settings(): NANS = True else: NANS = False - FUZZ_OPTS += ['--no-fuzz-nans'] + FUZZ_OPTS += ['--denan'] if random.random() < 0.5: OOB = True else: diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 6de16a5b2..654c1c797 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -18,6 +18,7 @@ set(passes_SOURCES DataFlowOpts.cpp DeadArgumentElimination.cpp DeadCodeElimination.cpp + DeNaN.cpp Directize.cpp DuplicateImportElimination.cpp DuplicateFunctionElimination.cpp diff --git a/src/passes/DeNaN.cpp b/src/passes/DeNaN.cpp new file mode 100644 index 000000000..044c13c86 --- /dev/null +++ b/src/passes/DeNaN.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2020 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. + */ + +// +// Instrument the wasm to convert NaN values at runtime into 0s. That is, every +// operation that might produce a NaN will go through a helper function which +// filters out NaNs (replacing them with 0). This ensures that NaNs are never +// consumed by any instructions, which is useful when fuzzing between VMs that +// differ on wasm's nondeterminism around NaNs. +// + +#include "pass.h" +#include "wasm-builder.h" +#include "wasm.h" + +namespace wasm { + +struct DeNaN : public WalkerPass< + ControlFlowWalker<DeNaN, UnifiedExpressionVisitor<DeNaN>>> { + void visitExpression(Expression* expr) { + // If the expression returns a floating-point value, ensure it is not a + // NaN. If we can do this at compile time, do it now, which is useful for + // initializations of global (which we can't do a function call in). + Builder builder(*getModule()); + Expression* replacement = nullptr; + auto* c = expr->dynCast<Const>(); + if (expr->type == Type::f32) { + if (c && c->value.isNaN()) { + replacement = builder.makeConst(Literal(float(0))); + } else { + replacement = builder.makeCall("deNan32", {expr}, Type::f32); + } + } else if (expr->type == Type::f64) { + if (c && c->value.isNaN()) { + replacement = builder.makeConst(Literal(double(0))); + } else { + replacement = builder.makeCall("deNan64", {expr}, Type::f64); + } + } + if (replacement) { + // We can't do this outside of a function, like in a global initializer, + // where a call would be illegal. + if (replacement->is<Const>() || getFunction()) { + replaceCurrent(replacement); + } else { + std::cerr << "warning: cannot de-nan outside of function context\n"; + } + } + } + + void visitModule(Module* module) { + // Add helper functions. + Builder builder(*module); + auto add = [&](Name name, Type type, Literal literal, BinaryOp op) { + auto* func = new Function; + func->name = name; + func->sig = Signature(type, type); + // Compare the value to itself to check if it is a NaN, and return 0 if + // so: + // + // (if (result f*) + // (f*.eq + // (local.get $0) + // (local.get $0) + // ) + // (local.get $0) + // (f*.const 0) + // ) + func->body = builder.makeIf( + builder.makeBinary( + op, builder.makeLocalGet(0, type), builder.makeLocalGet(0, type)), + builder.makeLocalGet(0, type), + builder.makeConst(literal)); + module->addFunction(func); + }; + add("deNan32", Type::f32, Literal(float(0)), EqFloat32); + add("deNan64", Type::f64, Literal(double(0)), EqFloat64); + } +}; + +Pass* createDeNaNPass() { return new DeNaN(); } + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 733b61467..4b023a46e 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -104,6 +104,9 @@ void PassRegistry::registerPasses() { createConstHoistingPass); registerPass( "dce", "removes unreachable code", createDeadCodeEliminationPass); + registerPass("denan", + "instrument the wasm to convert NaNs into 0 at runtime", + createDeNaNPass); registerPass( "directize", "turns indirect calls into direct ones", createDirectizePass); registerPass( diff --git a/src/passes/passes.h b/src/passes/passes.h index 868c5b407..7683bf8c6 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -34,6 +34,7 @@ Pass* createDAEPass(); Pass* createDAEOptimizingPass(); Pass* createDataFlowOptsPass(); Pass* createDeadCodeEliminationPass(); +Pass* createDeNaNPass(); Pass* createDirectizePass(); Pass* createDWARFDumpPass(); Pass* createDuplicateImportEliminationPass(); diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index f4188eb08..9788d9f11 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -183,8 +183,6 @@ public: std::cout << "shrink level: " << options.passOptions.shrinkLevel << '\n'; } - void setAllowNaNs(bool allowNaNs_) { allowNaNs = allowNaNs_; } - void setAllowMemory(bool allowMemory_) { allowMemory = allowMemory_; } void setAllowOOB(bool allowOOB_) { allowOOB = allowOOB_; } @@ -207,9 +205,6 @@ public: if (HANG_LIMIT > 0) { addHangLimitSupport(); } - if (!allowNaNs) { - addDeNanSupport(); - } finalizeTable(); } @@ -253,11 +248,6 @@ private: // no hang protection. static const int HANG_LIMIT = 10; - // Optionally remove NaNs, which are a source of nondeterminism (which makes - // cross-VM comparisons harder) - // TODO: de-NaN SIMD values - bool allowNaNs = true; - // Whether to emit memory operations like loads and stores. bool allowMemory = true; @@ -499,34 +489,6 @@ private: builder.makeConst(Literal(int32_t(1)))))); } - void addDeNanSupport() { - auto add = [&](Name name, Type type, Literal literal, BinaryOp op) { - auto* func = new Function; - func->name = name; - func->sig = Signature(type, type); - func->body = builder.makeIf( - builder.makeBinary( - op, builder.makeLocalGet(0, type), builder.makeLocalGet(0, type)), - builder.makeLocalGet(0, type), - builder.makeConst(literal)); - wasm.addFunction(func); - }; - add("deNan32", Type::f32, Literal(float(0)), EqFloat32); - add("deNan64", Type::f64, Literal(double(0)), EqFloat64); - } - - Expression* makeDeNanOp(Expression* expr) { - if (allowNaNs) { - return expr; - } - if (expr->type == Type::f32) { - return builder.makeCall("deNan32", {expr}, Type::f32); - } else if (expr->type == Type::f64) { - return builder.makeCall("deNan64", {expr}, Type::f64); - } - return expr; // unreachable etc. is fine - } - // function generation state Function* func = nullptr; @@ -1538,7 +1500,7 @@ private: return store; } - Literal makeArbitraryLiteral(Type type) { + Literal makeLiteral(Type type) { if (type == Type::v128) { // generate each lane individually for random lane interpretation switch (upTo(6)) { @@ -1767,14 +1729,6 @@ private: WASM_UNREACHABLE("invalide value"); } - Literal makeLiteral(Type type) { - auto ret = makeArbitraryLiteral(type); - if (!allowNaNs && ret.isNaN()) { - ret = Literal::makeFromInt32(0, type); - } - return ret; - } - Expression* makeConst(Type type) { if (type.isRef()) { assert(wasm.features.hasReferenceTypes()); @@ -1814,8 +1768,7 @@ private: assert(!type.isMulti()); if (type == Type::unreachable) { if (auto* unary = makeUnary(getSingleConcreteType())->dynCast<Unary>()) { - return makeDeNanOp( - builder.makeUnary(unary->op, make(Type::unreachable))); + return builder.makeUnary(unary->op, make(Type::unreachable)); } // give up return makeTrivial(type); @@ -1923,50 +1876,50 @@ private: case Type::f32: { switch (upTo(4)) { case 0: - return makeDeNanOp(buildUnary({pick(NegFloat32, - AbsFloat32, - CeilFloat32, - FloorFloat32, - TruncFloat32, - NearestFloat32, - SqrtFloat32), - make(Type::f32)})); + return buildUnary({pick(NegFloat32, + AbsFloat32, + CeilFloat32, + FloorFloat32, + TruncFloat32, + NearestFloat32, + SqrtFloat32), + make(Type::f32)}); case 1: - return makeDeNanOp(buildUnary({pick(ConvertUInt32ToFloat32, - ConvertSInt32ToFloat32, - ReinterpretInt32), - make(Type::i32)})); + return buildUnary({pick(ConvertUInt32ToFloat32, + ConvertSInt32ToFloat32, + ReinterpretInt32), + make(Type::i32)}); case 2: - return makeDeNanOp( - buildUnary({pick(ConvertUInt64ToFloat32, ConvertSInt64ToFloat32), - make(Type::i64)})); + return buildUnary( + {pick(ConvertUInt64ToFloat32, ConvertSInt64ToFloat32), + make(Type::i64)}); case 3: - return makeDeNanOp(buildUnary({DemoteFloat64, make(Type::f64)})); + return buildUnary({DemoteFloat64, make(Type::f64)}); } WASM_UNREACHABLE("invalid value"); } case Type::f64: { switch (upTo(4)) { case 0: - return makeDeNanOp(buildUnary({pick(NegFloat64, - AbsFloat64, - CeilFloat64, - FloorFloat64, - TruncFloat64, - NearestFloat64, - SqrtFloat64), - make(Type::f64)})); + return buildUnary({pick(NegFloat64, + AbsFloat64, + CeilFloat64, + FloorFloat64, + TruncFloat64, + NearestFloat64, + SqrtFloat64), + make(Type::f64)}); case 1: - return makeDeNanOp( - buildUnary({pick(ConvertUInt32ToFloat64, ConvertSInt32ToFloat64), - make(Type::i32)})); + return buildUnary( + {pick(ConvertUInt32ToFloat64, ConvertSInt32ToFloat64), + make(Type::i32)}); case 2: - return makeDeNanOp(buildUnary({pick(ConvertUInt64ToFloat64, - ConvertSInt64ToFloat64, - ReinterpretInt64), - make(Type::i64)})); + return buildUnary({pick(ConvertUInt64ToFloat64, + ConvertSInt64ToFloat64, + ReinterpretInt64), + make(Type::i64)}); case 3: - return makeDeNanOp(buildUnary({PromoteFloat32, make(Type::f32)})); + return buildUnary({PromoteFloat32, make(Type::f32)}); } WASM_UNREACHABLE("invalid value"); } @@ -2035,8 +1988,8 @@ private: if (type == Type::unreachable) { if (auto* binary = makeBinary(getSingleConcreteType())->dynCast<Binary>()) { - return makeDeNanOp(buildBinary( - {binary->op, make(Type::unreachable), make(Type::unreachable)})); + return buildBinary( + {binary->op, make(Type::unreachable), make(Type::unreachable)}); } // give up return makeTrivial(type); @@ -2131,26 +2084,26 @@ private: make(Type::i64)}); } case Type::f32: { - return makeDeNanOp(buildBinary({pick(AddFloat32, - SubFloat32, - MulFloat32, - DivFloat32, - CopySignFloat32, - MinFloat32, - MaxFloat32), - make(Type::f32), - make(Type::f32)})); + return buildBinary({pick(AddFloat32, + SubFloat32, + MulFloat32, + DivFloat32, + CopySignFloat32, + MinFloat32, + MaxFloat32), + make(Type::f32), + make(Type::f32)}); } case Type::f64: { - return makeDeNanOp(buildBinary({pick(AddFloat64, - SubFloat64, - MulFloat64, - DivFloat64, - CopySignFloat64, - MinFloat64, - MaxFloat64), - make(Type::f64), - make(Type::f64)})); + return buildBinary({pick(AddFloat64, + SubFloat64, + MulFloat64, + DivFloat64, + CopySignFloat64, + MinFloat64, + MaxFloat64), + make(Type::f64), + make(Type::f64)}); } case Type::v128: { assert(wasm.features.hasSIMD()); @@ -2270,8 +2223,7 @@ private: Expression* makeSelect(Type type) { Type subType1 = getSubType(type); Type subType2 = getSubType(type); - return makeDeNanOp( - buildSelect({make(Type::i32), make(subType1), make(subType2)}, type)); + return buildSelect({make(Type::i32), make(subType1), make(subType2)}, type); } Expression* makeSwitch(Type type) { diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index a215aca32..41302eac8 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -82,7 +82,6 @@ int main(int argc, const char* argv[]) { std::string extraFuzzCommand; bool translateToFuzz = false; bool fuzzPasses = false; - bool fuzzNaNs = true; bool fuzzMemory = true; bool fuzzOOB = true; std::string emitJSWrapper; @@ -148,12 +147,6 @@ int main(int argc, const char* argv[]) { "on translate-to-fuzz (it picks the passes from the input)", Options::Arguments::Zero, [&](Options* o, const std::string& arguments) { fuzzPasses = true; }) - .add("--no-fuzz-nans", - "", - "don't emit NaNs when fuzzing, and remove them at runtime as well " - "(helps avoid nondeterminism between VMs)", - Options::Arguments::Zero, - [&](Options* o, const std::string& arguments) { fuzzNaNs = false; }) .add("--no-fuzz-memory", "", "don't emit memory ops when fuzzing", @@ -266,7 +259,6 @@ int main(int argc, const char* argv[]) { if (fuzzPasses) { reader.pickPasses(options); } - reader.setAllowNaNs(fuzzNaNs); reader.setAllowMemory(fuzzMemory); reader.setAllowOOB(fuzzOOB); reader.build(); diff --git a/test/passes/denan.txt b/test/passes/denan.txt new file mode 100644 index 000000000..67f4989e4 --- /dev/null +++ b/test/passes/denan.txt @@ -0,0 +1,44 @@ +(module + (type $f32_=>_f32 (func (param f32) (result f32))) + (type $f64_=>_f64 (func (param f64) (result f64))) + (global $global$1 (mut f32) (f32.const 0)) + (global $global$2 (mut f32) (f32.const 12.34000015258789)) + (func $foo32 (param $x f32) (result f32) + (call $deNan32 + (call $foo32 + (call $deNan32 + (local.get $x) + ) + ) + ) + ) + (func $foo64 (param $x f64) (result f64) + (call $deNan64 + (call $foo64 + (call $deNan64 + (local.get $x) + ) + ) + ) + ) + (func $deNan32 (param $0 f32) (result f32) + (if (result f32) + (f32.eq + (local.get $0) + (local.get $0) + ) + (local.get $0) + (f32.const 0) + ) + ) + (func $deNan64 (param $0 f64) (result f64) + (if (result f64) + (f64.eq + (local.get $0) + (local.get $0) + ) + (local.get $0) + (f64.const 0) + ) + ) +) diff --git a/test/passes/denan.wast b/test/passes/denan.wast new file mode 100644 index 000000000..73c3c8f1c --- /dev/null +++ b/test/passes/denan.wast @@ -0,0 +1,10 @@ +(module + (global $global$1 (mut f32) (f32.const nan)) + (global $global$2 (mut f32) (f32.const 12.34)) + (func $foo32 (param $x f32) (result f32) + (call $foo32 (local.get $x)) + ) + (func $foo64 (param $x f64) (result f64) + (call $foo64 (local.get $x)) + ) +) 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 deleted file mode 100644 index d024a75ed..000000000 --- a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.txt +++ /dev/null @@ -1,1342 +0,0 @@ -(module - (type $none_=>_none (func)) - (type $i64_=>_none (func (param i64))) - (type $i32_=>_none (func (param i32))) - (type $f32_=>_none (func (param f32))) - (type $f64_=>_none (func (param f64))) - (type $v128_=>_none (func (param v128))) - (type $nullref_=>_none (func (param nullref))) - (type $exnref_=>_none (func (param exnref))) - (type $none_=>_i32 (func (result i32))) - (type $f32_=>_f32 (func (param f32) (result f32))) - (type $f64_=>_f64 (func (param f64) (result f64))) - (type $none_=>_anyref (func (result anyref))) - (import "fuzzing-support" "log-i32" (func $log-i32 (param i32))) - (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))) - (import "fuzzing-support" "log-v128" (func $log-v128 (param v128))) - (import "fuzzing-support" "log-nullref" (func $log-nullref (param nullref))) - (import "fuzzing-support" "log-exnref" (func $log-exnref (param exnref))) - (memory $0 (shared 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$5 (mut f32) (f32.const 74)) - (global $global$4 (mut nullref) (ref.null)) - (global $global$3 (mut i32) (i32.const 1263230471)) - (global $global$2 (mut i32) (i32.const -131072)) - (global $global$1 (mut (i64 f64 exnref)) (tuple.make - (i64.const 4294967295) - (f64.const 0) - (ref.null) - )) - (global $hangLimit (mut i32) (i32.const 10)) - (event $event$0 (attr 0) (param i64)) - (event $event$1 (attr 0) (param)) - (export "hashMemory" (func $hashMemory)) - (export "memory" (memory $0)) - (export "hangLimitInitializer" (func $hangLimitInitializer)) - (func $hashMemory (result i32) - (local $0 i32) - (local.set $0 - (i32.const 5381) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=1 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=2 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=3 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=4 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=5 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=6 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=7 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=8 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=9 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=10 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=11 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=12 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=13 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=14 - (i32.const 0) - ) - ) - ) - (local.set $0 - (i32.xor - (i32.add - (i32.shl - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.load8_u offset=15 - (i32.const 0) - ) - ) - ) - (local.get $0) - ) - (func $func_8 (result anyref) - (local $0 i64) - (local $1 exnref) - (local $2 nullref) - (local $3 i32) - (local $4 anyref) - (local $5 nullref) - (local $6 f32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$0 (result anyref) - (loop $label$1 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (block $label$2 - (atomic.fence) - (f64.store offset=3 align=2 - (i32.and - (i32.const 521278814) - (block $label$9 (result i32) - (drop - (tuple.make - (f32.const -16777216) - (ref.null) - (ref.null) - ) - ) - (i32.gt_u - (block $label$12 (result i32) - (if - (local.get $3) - (nop) - (nop) - ) - (local.get $3) - ) - (local.tee $3 - (ref.is_null - (loop $label$13 (result anyref) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.tee $4 - (loop $label$14 (result anyref) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.get $4) - ) - ) - ) - ) - ) - ) - ) - ) - (f64.const 2.0368363672810022e-260) - ) - ) - (br_if $label$1 - (loop $label$3 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$4 - (block $label$5 - (nop) - (drop - (global.get $global$5) - ) - (br_if $label$3 - (i32.eqz - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (select - (block $label$7 (result i32) - (nop) - (local.tee $3 - (block $label$8 (result i32) - (nop) - (local.get $3) - ) - ) - ) - (local.get $3) - (block $label$6 - (return - (local.get $4) - ) - ) - ) - ) - (i32.const -95) - (select - (loop $label$25 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (block $label$26 - (block $label$27 - (local.set $4 - (local.get $4) - ) - (call $log-i64 - (select - (local.tee $0 - (i64.atomic.load32_u offset=22 - (i32.and - (i32.const -4) - (i32.const 15) - ) - ) - ) - (i64.extend_i32_s - (i32.load16_u offset=22 - (i32.and - (i32.extend8_s - (global.get $global$2) - ) - (i32.const 15) - ) - ) - ) - (i32.atomic.load - (i32.and - (loop $label$28 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (block $label$29 - (block $label$30 - (memory.copy - (i32.and - (local.tee $3 - (i64.le_s - (select - (local.get $0) - (i64.const 2147483647) - (local.get $3) - ) - (i64.const 29050) - ) - ) - (i32.const 15) - ) - (i32.and - (local.get $3) - (i32.const 15) - ) - (global.get $global$3) - ) - ) - (f64.store offset=22 align=2 - (i32.and - (i32.const -65535) - (i32.const 15) - ) - (block $label$31 (result f64) - (if - (block $label$32 - (nop) - (br $label$29) - ) - (i64.atomic.store32 offset=4 - (i32.const 1291) - (block $label$33 - (local.set $3 - (i32.const 122572612) - ) - (br $label$27) - ) - ) - (block $label$34 - (atomic.fence) - ) - ) - (f64.load offset=2 align=1 - (i32.and - (local.get $3) - (i32.const 15) - ) - ) - ) - ) - ) - (br_if $label$28 - (i32.const -59) - ) - (local.get $3) - ) - ) - (i32.const 15) - ) - ) - ) - ) - ) - (loop $label$43 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (br_if $label$25 - (i32.eqz - (if (result i32) - (i32.eqz - (atomic.notify offset=22 - (i32.and - (ref.is_null - (ref.func $log-f32) - ) - (i32.const 15) - ) - (local.tee $3 - (local.get $3) - ) - ) - ) - (block $label$44 - (nop) - (br $label$26) - ) - (block $label$45 (result i32) - (loop $label$46 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$47 - (local.set $5 - (block $label$48 (result nullref) - (i64.atomic.store32 offset=4 - (i32.and - (global.get $global$2) - (i32.const 15) - ) - (local.tee $0 - (i64.const -95) - ) - ) - (ref.null) - ) - ) - (call $log-nullref - (block $label$49 - (loop $label$50 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (br_if $label$50 - (i32.eqz - (global.get $global$3) - ) - ) - (br_if $label$50 - (i32.eqz - (local.get $3) - ) - ) - (br_if $label$26 - (i32.eqz - (if (result i32) - (i32.eqz - (local.get $3) - ) - (i32.const -2147483648) - (i32.const 1783516750) - ) - ) - ) - ) - ) - (br $label$46) - ) - ) - ) - ) - (loop $label$51 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (if - (local.get $3) - (loop $label$52 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$53 - (loop $label$54 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (v128.store offset=4 align=4 - (local.get $3) - (v128.const i32x4 0x00000045 0x00000000 0x170e0b00 0x00000000) - ) - (br_if $label$54 - (i32.eqz - (select - (i32.const -1024) - (local.get $3) - (i32.const -69) - ) - ) - ) - (block $label$55 - (if - (global.get $global$3) - (loop $label$56 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (nop) - (br_if $label$56 - (i32.const 20266) - ) - (br_if $label$25 - (i32.eqz - (ref.is_null - (ref.null) - ) - ) - ) - ) - ) - (nop) - ) - (local.set $3 - (i32.le_s - (local.get $3) - (loop $label$57 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.get $3) - ) - ) - ) - ) - ) - ) - (local.set $3 - (block $label$58 (result i32) - (nop) - (local.get $3) - ) - ) - ) - ) - (block $label$59 - (nop) - (if - (i32.eqz - (loop $label$60 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block $label$61 - (local.set $1 - (local.get $1) - ) - (br $label$51) - ) - ) - ) - (loop $label$62 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (loop $label$63 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block - (drop - (ref.null) - ) - (br_if $label$63 - (i32.eqz - (local.get $3) - ) - ) - (if - (i32.eqz - (loop $label$64 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (local.get $3) - ) - ) - (i64.store8 offset=3 - (i32.and - (local.tee $3 - (local.get $3) - ) - (i32.const 15) - ) - (i64.const 4920830541588677956) - ) - (local.set $4 - (local.tee $4 - (local.get $4) - ) - ) - ) - ) - ) - ) - (local.set $3 - (if (result i32) - (i32.eqz - (if (result i32) - (i32.eqz - (local.get $3) - ) - (i32.const -262144) - (br_if $label$45 - (local.get $3) - (i32.const -126) - ) - ) - ) - (if (result i32) - (local.get $3) - (i32.const -4096) - (local.get $3) - ) - (local.get $3) - ) - ) - ) - ) - ) - (br_if $label$51 - (i32.eqz - (if (result i32) - (i32.eqz - (i8x16.extract_lane_u 6 - (if (result v128) - (i32.const 32767) - (if (result v128) - (local.get $3) - (i64x2.splat - (loop $label$65 (result i64) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (i64.const 126) - ) - ) - (v128.const i32x4 0x0100007a 0x1d4cba00 0x00002000 0x00001200) - ) - (block $label$66 - (if - (i32.eqz - (if (result i32) - (i32.eqz - (block $label$67 - (local.set $4 - (ref.null) - ) - (br $label$26) - ) - ) - (local.get $3) - (i32.const 4096) - ) - ) - (nop) - (i64.atomic.store8 offset=4 - (i32.and - (global.get $global$2) - (i32.const 15) - ) - (i64.const -128) - ) - ) - (br $label$51) - ) - ) - ) - ) - (block $label$68 - (nop) - (br $label$51) - ) - (block $label$69 (result i32) - (nop) - (br_if $label$69 - (ref.is_null - (local.tee $4 - (ref.null) - ) - ) - (i32.eqz - (i32.eqz - (local.get $3) - ) - ) - ) - ) - ) - ) - ) - (local.get $3) - ) - ) - ) - ) - ) - ) - (br_if $label$43 - (i32.eqz - (if (result i32) - (i32.eqz - (local.tee $3 - (i16x8.extract_lane_s 6 - (v8x16.shuffle 8 11 19 17 15 16 14 19 17 15 16 14 19 17 15 16 - (loop $label$70 (result v128) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result v128) - (block $label$71 - (memory.fill - (i32.and - (if (result i32) - (local.get $3) - (local.get $3) - (local.get $3) - ) - (i32.const 15) - ) - (i32.and - (i32.const 72) - (i32.const 15) - ) - (if (result i32) - (loop $label$72 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (atomic.notify offset=22 - (i32.and - (i32.const 168631327) - (i32.const 15) - ) - (local.get $3) - ) - ) - (i32.const 102434061) - (local.get $3) - ) - ) - (block $label$73 - (i64.store offset=22 align=4 - (i32.and - (local.get $3) - (i32.const 15) - ) - (local.get $0) - ) - (if - (local.get $3) - (local.set $6 - (f32.const 15197) - ) - (nop) - ) - ) - ) - (br_if $label$70 - (f64.gt - (if (result f64) - (select - (local.get $3) - (i32.const -2147483648) - (i32.const 52367877) - ) - (f64.const -18446744073709551615) - (f64.const 2.0587249864648059e-168) - ) - (f64.const 9.399829295721398e-187) - ) - ) - (v128.const i32x4 0x3423505b 0xffffffff 0x0203e000 0xffff1717) - ) - ) - (v128.const i32x4 0xa0358001 0x5337017f 0xff005bb3 0xffa80100) - ) - ) - ) - ) - (block $label$75 (result i32) - (local.get $3) - ) - (block $label$76 (result i32) - (local.get $3) - ) - ) - ) - ) - (nop) - ) - ) - ) - (br_if $label$25 - (i32.const -4) - ) - (i32.const 127) - ) - ) - (local.get $3) - (i32.load16_u offset=22 align=1 - (i32.and - (i64.ge_s - (local.tee $0 - (local.tee $0 - (local.get $0) - ) - ) - (local.get $0) - ) - (i32.const 15) - ) - ) - ) - ) - ) - (if (result i32) - (i32.eqz - (local.tee $3 - (i32.const -96) - ) - ) - (i64x2.all_true - (f32x4.splat - (call $deNan32 - (f32.convert_i64_u - (i64.const 1394725084389383962) - ) - ) - ) - ) - (loop $label$18 (result i32) - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (local.get $4) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (block (result i32) - (block $label$19 - (loop $label$20 - (block - (if - (i32.eqz - (global.get $hangLimit) - ) - (return - (ref.null) - ) - ) - (global.set $hangLimit - (i32.sub - (global.get $hangLimit) - (i32.const 1) - ) - ) - ) - (nop) - ) - (br_if $label$19 - (i32.eqz - (local.get $3) - ) - ) - ) - (br_if $label$18 - (i32.eqz - (i32.atomic.load offset=3 - (local.get $3) - ) - ) - ) - (local.get $3) - ) - ) - ) - (block $label$21 - (br $label$1) - ) - ) - ) - (local.get $3) - (block $label$22 - (v128.store offset=4 - (i32.and - (i32.and - (global.get $global$3) - (i32.const 15) - ) - (i32.const 15) - ) - (i8x16.narrow_i16x8_u - (if (result v128) - (i32.eqz - (block $label$23 (result i32) - (i32.const -129) - ) - ) - (block $label$24 - (br $label$3) - ) - (v128.const i32x4 0xffffc000 0xffffffe0 0x00007fff 0x737f197a) - ) - (v128.const i32x4 0x10000000 0x00000000 0x00000080 0x00000000) - ) - ) - (br $label$1) - ) - ) - ) - ) - ) - (return - (local.get $4) - ) - ) - ) - ) - (nop) - ) - ) - (nop) - (local.get $4) - ) - ) - (func $hangLimitInitializer - (global.set $hangLimit - (i32.const 10) - ) - ) - (func $deNan32 (param $0 f32) (result f32) - (if (result f32) - (f32.eq - (local.get $0) - (local.get $0) - ) - (local.get $0) - (f32.const 0) - ) - ) - (func $deNan64 (param $0 f64) (result f64) - (if (result f64) - (f64.eq - (local.get $0) - (local.get $0) - ) - (local.get $0) - (f64.const 0) - ) - ) -) diff --git a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.wast b/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.wast deleted file mode 100644 index 3dab8874e..000000000 --- a/test/passes/translate-to-fuzz_no-fuzz-nans_all-features.wast +++ /dev/null @@ -1,99 +0,0 @@ -(module # fake module here, for test harness, but it is really not needed -.. -any -3INPUT -h e r e -*will* -d0 -0.753538467597066 -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -h e r e -*will* -d0 -0.753538467597066 -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$ - -MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________ -<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G - -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$ - -MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________ -<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G - -INPUT -h e r e -*will* -d0 -0.753538467597066 -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -h e r e -*will* -d0 -0.753538467597066 -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$ - -MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________ -<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G - -2.2339337309978227 -................. -lorem ipsum whatever - -through the darkness of future past -the magician longs to see -one [chants|chance] out between two worlds -fire, walk with me - - -(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$ - -) # this isn't really needed either |