diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-02-19 10:14:59 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-19 10:14:59 -0800 |
commit | 3564b71c25d7691267f5f7d8b95f10fd5929090a (patch) | |
tree | ca81e10e93bc10b8ade61f96ff642152540f9e8f | |
parent | 8b820ed0021ab1a6ad5dad3972cfbf2cecb77e45 (diff) | |
download | binaryen-3564b71c25d7691267f5f7d8b95f10fd5929090a.tar.gz binaryen-3564b71c25d7691267f5f7d8b95f10fd5929090a.tar.bz2 binaryen-3564b71c25d7691267f5f7d8b95f10fd5929090a.zip |
NaN fuzzing improvements (#1913)
* make DE_NAN avoid creating nan literals in the first place
* add a reducer option `--denan` to not introduce nans in destructive reduction
* add a `Literal::isNaN()` method
* also remove the default exception logging from the fuzzer js glue, which is a source of non-useful VM differences (like nan nondeterminism)
* added an option `--no-fuzz-nans` to make it easy to avoid nans when fuzzing (without hacking the source and recompiling).
Background: trying to get fuzzing on jsc working despite this open issue: https://bugs.webkit.org/show_bug.cgi?id=175691
-rw-r--r-- | scripts/fuzz_opt.py | 12 | ||||
-rw-r--r-- | src/literal.h | 2 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 25 | ||||
-rw-r--r-- | src/tools/js-wrapper.h | 2 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 8 | ||||
-rw-r--r-- | src/tools/wasm-reduce.cpp | 30 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 11 | ||||
-rw-r--r-- | test/passes/emit-js-wrapper=a.js.wast.js | 10 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz.txt | 36 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_no-fuzz-nans.txt | 580 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_no-fuzz-nans.wast | 99 |
11 files changed, 764 insertions, 51 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index c8f67b2ae..58751a72e 100644 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -27,9 +27,12 @@ from test.shared import options # parameters -LOG_LIMIT = 125 +FUZZ_OPTS = ['--mvp-features'] # may want to add '--no-fuzz-nans' for cross-VM testing + INPUT_SIZE_LIMIT = 250 * 1024 +LOG_LIMIT = 125 + # utilities @@ -122,9 +125,8 @@ def run_vms(prefix): results = [] # append to this list to add results from VMs results += [fix_output(run_vm([in_bin('wasm-opt'), prefix + 'wasm', '--fuzz-exec-before']))] - results += [fix_output(run_vm([os.path.expanduser('d8'), '--experimental-wasm-sat_f2i_conversions', prefix + 'js', '--', prefix + 'wasm']))] - results += [fix_output(run_vm([os.path.expanduser('d8-debug'), '--experimental-wasm-sat_f2i_conversions', '--wasm-tier-up', prefix + 'js', '--', prefix + 'wasm']))] - results += [fix_output(run_vm([os.path.expanduser('d8-debug'), '--experimental-wasm-sat_f2i_conversions', '--no-wasm-tier-up', prefix + 'js', '--', prefix + 'wasm']))] + results += [fix_output(run_vm([os.path.expanduser('d8'), prefix + 'js', '--', prefix + 'wasm']))] + # results += [fix_output(run_vm([os.path.expanduser('~/.jsvu/jsc'), prefix + 'js', '--', prefix + 'wasm']))] # spec has no mechanism to not halt on a trap. so we just check until the first trap, basically # run(['../spec/interpreter/wasm', prefix + 'wasm']) # results += [fix_spec_output(run_unchecked(['../spec/interpreter/wasm', prefix + 'wasm', '-e', open(prefix + 'wat').read()]))] @@ -146,7 +148,7 @@ def test_one(infile, opts): # fuzz vms # gather VM outputs on input file - run([in_bin('wasm-opt'), infile, '-ttf', '--emit-js-wrapper=a.js', '--emit-spec-wrapper=a.wat', '-o', 'a.wasm', '--mvp-features']) + run([in_bin('wasm-opt'), infile, '-ttf', '--emit-js-wrapper=a.js', '--emit-spec-wrapper=a.wat', '-o', 'a.wasm'] + FUZZ_OPTS) wasm_size = os.stat('a.wasm').st_size bytes += wasm_size print('pre js size :', os.stat('a.js').st_size, ' wasm size:', wasm_size) diff --git a/src/literal.h b/src/literal.h index 2e3f901cc..7646b5d29 100644 --- a/src/literal.h +++ b/src/literal.h @@ -110,6 +110,8 @@ public: bool operator==(const Literal& other) const; bool operator!=(const Literal& other) const; + bool isNaN(); + static uint32_t NaNPayload(float f); static uint64_t NaNPayload(double f); static float setQuietNaN(float f); diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 63e7dca43..90b7d61b1 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -123,8 +123,15 @@ public: std::cout << "shrink level: " << options.passOptions.shrinkLevel << '\n'; } - void build(FeatureSet features_) { + void setFeatures(FeatureSet features_) { features = features_; + } + + void setAllowNaNs(bool allowNaNs_) { + allowNaNs = allowNaNs_; + } + + void build() { setupMemory(); setupTable(); setupGlobals(); @@ -137,7 +144,7 @@ public: if (HANG_LIMIT > 0) { addHangLimitSupport(); } - if (DE_NAN) { + if (!allowNaNs) { addDeNanSupport(); } finalizeTable(); @@ -178,7 +185,7 @@ private: // Optionally remove NaNs, which are a source of nondeterminism (which makes // cross-VM comparisons harder) // TODO: de-NaN SIMD values - static const bool DE_NAN = true; + bool allowNaNs = true; // Features allowed to be emitted FeatureSet features = FeatureSet::All; @@ -361,7 +368,7 @@ private: } Expression* makeDeNanOp(Expression* expr) { - if (!DE_NAN) return expr; + if (allowNaNs) return expr; if (expr->type == f32) { return builder.makeCall("deNan32", { expr }, f32); } else if (expr->type == f64) { @@ -1213,7 +1220,7 @@ private: return store; } - Literal makeLiteral(Type type) { + Literal makeArbitraryLiteral(Type type) { if (type == v128) { // generate each lane individually for random lane interpretation switch (upTo(6)) { @@ -1344,6 +1351,14 @@ private: WASM_UNREACHABLE(); } + Literal makeLiteral(Type type) { + auto ret = makeArbitraryLiteral(type); + if (!allowNaNs && ret.isNaN()) { + ret = Literal::makeFromInt32(0, type); + } + return ret; + } + Expression* makeConst(Type type) { auto* ret = wasm.allocator.alloc<Const>(); ret->value = makeLiteral(type); diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h index 765a638c5..433d6fc5a 100644 --- a/src/tools/js-wrapper.h +++ b/src/tools/js-wrapper.h @@ -103,7 +103,7 @@ static std::string generateJSWrapper(Module& wasm) { } ret += ";\n"; ret += "} catch (e) {\n"; - ret += " console.log('exception: ' + e);\n"; + ret += " console.log('exception!' /* + e */);\n"; ret += "}\n"; } return ret; diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index 61e554276..d2f3d718c 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -71,6 +71,7 @@ int main(int argc, const char* argv[]) { std::string extraFuzzCommand; bool translateToFuzz = false; bool fuzzPasses = false; + bool fuzzNaNs = true; std::string emitJSWrapper; std::string emitSpecWrapper; std::string inputSourceMapFilename; @@ -112,6 +113,9 @@ int main(int argc, const char* argv[]) { .add("--fuzz-passes", "-fp", "Pick a random set of passes to run, useful for fuzzing. this depends 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("--emit-js-wrapper", "-ejw", "Emit a JavaScript wrapper file that can run the wasm with some test values, useful for fuzzing", Options::Arguments::One, [&](Options *o, const std::string& arguments) { emitJSWrapper = arguments; }) @@ -166,7 +170,9 @@ int main(int argc, const char* argv[]) { if (fuzzPasses) { reader.pickPasses(options); } - reader.build(options.getFeatures()); + reader.setFeatures(options.getFeatures()); + reader.setAllowNaNs(fuzzNaNs); + reader.build(); if (options.passOptions.validate) { if (!WasmValidator().validate(wasm, options.getFeatures())) { WasmPrinter::printModule(&wasm); diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index 8b12c0ef1..bd5a0c1b8 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -221,11 +221,12 @@ static std::unordered_set<Name> functionsWeTriedToRemove; struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor<Reducer>>> { std::string command, test, working; - bool binary, verbose, debugInfo; + bool binary, deNan, verbose, debugInfo; // test is the file we write to that the command will operate on // working is the current temporary state, the reduction so far - Reducer(std::string command, std::string test, std::string working, bool binary, bool verbose, bool debugInfo) : command(command), test(test), working(working), binary(binary), verbose(verbose), debugInfo(debugInfo) {} + Reducer(std::string command, std::string test, std::string working, bool binary, bool deNan, bool verbose, bool debugInfo) : + command(command), test(test), working(working), binary(binary), deNan(deNan), verbose(verbose), debugInfo(debugInfo) {} // runs passes in order to reduce, until we can't reduce any more // the criterion here is wasm binary size @@ -360,8 +361,22 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor< return (counter % factor) <= bonus; } + bool isOkReplacement(Expression* with) { + if (deNan) { + if (auto* c = with->dynCast<Const>()) { + if (c->value.isNaN()) { + return false; + } + } + } + return true; + } + // tests a reduction on the current traversal node, and undos if it failed bool tryToReplaceCurrent(Expression* with) { + if (!isOkReplacement(with)) { + return false; + } auto* curr = getCurrent(); //std::cerr << "try " << curr << " => " << with << '\n'; if (curr->type != with->type) return false; @@ -383,6 +398,9 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor< // tests a reduction on an arbitrary child bool tryToReplaceChild(Expression*& child, Expression* with) { + if (!isOkReplacement(with)) { + return false; + } if (child->type != with->type) return false; if (!shouldTryToReduce()) return false; auto* before = child; @@ -865,6 +883,7 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor< int main(int argc, const char* argv[]) { std::string input, test, working, command; bool binary = true, + deNan = false, verbose = false, debugInfo = false, force = false; @@ -899,6 +918,11 @@ int main(int argc, const char* argv[]) { [&](Options* o, const std::string& argument) { binary = false; }) + .add("--denan", "", "Avoid nans when reducing", + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { + deNan = true; + }) .add("--verbose", "-v", "Verbose output mode", Options::Arguments::Zero, [&](Options* o, const std::string& argument) { @@ -997,7 +1021,7 @@ int main(int argc, const char* argv[]) { bool stopping = false; while (1) { - Reducer reducer(command, test, working, binary, verbose, debugInfo); + Reducer reducer(command, test, working, binary, deNan, verbose, debugInfo); // run binaryen optimization passes to reduce. passes are fast to run // and can often reduce large amounts of code efficiently, as opposed diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 5f358fa6b..4ec256aae 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -144,6 +144,17 @@ bool Literal::operator!=(const Literal& other) const { return !(*this == other); } +bool Literal::isNaN() { + if (type == Type::f32 && std::isnan(getf32())) { + return true; + } + if (type == Type::f64 && std::isnan(getf64())) { + return true; + } + // TODO: SIMD? + return false; +} + uint32_t Literal::NaNPayload(float f) { assert(std::isnan(f) && "expected a NaN"); // SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF diff --git a/test/passes/emit-js-wrapper=a.js.wast.js b/test/passes/emit-js-wrapper=a.js.wast.js index 9e8578781..2e127d189 100644 --- a/test/passes/emit-js-wrapper=a.js.wast.js +++ b/test/passes/emit-js-wrapper=a.js.wast.js @@ -51,33 +51,33 @@ try { console.log('[fuzz-exec] calling $add'); console.log('[fuzz-exec] note result: $add => ' + literal(instance.exports.add(0, 0), 'i32')); } catch (e) { - console.log('exception: ' + e); + console.log('exception!' /* + e */); } if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); try { console.log('[fuzz-exec] calling $no_return'); instance.exports.no_return(0); } catch (e) { - console.log('exception: ' + e); + console.log('exception!' /* + e */); } if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); try { console.log('[fuzz-exec] calling $types'); instance.exports.types(0, 0, 0, 0, 0); } catch (e) { - console.log('exception: ' + e); + console.log('exception!' /* + e */); } if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); try { console.log('[fuzz-exec] calling $types2'); instance.exports.types2(0, 0, 0); } catch (e) { - console.log('exception: ' + e); + console.log('exception!' /* + e */); } if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); try { console.log('[fuzz-exec] calling $types3'); console.log('[fuzz-exec] note result: $types3 => ' + literal(instance.exports.types3(0, 0, 0), 'i32')); } catch (e) { - console.log('exception: ' + e); + console.log('exception!' /* + e */); } diff --git a/test/passes/translate-to-fuzz.txt b/test/passes/translate-to-fuzz.txt index aefe33cb6..914703050 100644 --- a/test/passes/translate-to-fuzz.txt +++ b/test/passes/translate-to-fuzz.txt @@ -17,8 +17,8 @@ (import "fuzzing-support" "log-f64" (func $log-f64 (param f64))) (memory $0 (shared 1 1)) (data (i32.const 0) "n\00\05E\00\00\00\00") - (table $0 6 6 funcref) - (elem (i32.const 0) $func_6 $func_12 $func_12 $func_12 $func_15 $func_16) + (table $0 10 10 funcref) + (elem (i32.const 0) $func_6 $func_12 $func_12 $func_12 $func_15 $func_16 $func_17 $func_17 $func_17 $func_17) (global $global$0 (mut f32) (f32.const 536870912)) (global $global$1 (mut f32) (f32.const 2147483648)) (global $global$2 (mut f64) (f64.const -1048576)) @@ -526,7 +526,7 @@ (global.get $hangLimit) ) (return - (f32.const 865309568) + (f32.const 185009408) ) ) (global.set $hangLimit @@ -537,15 +537,9 @@ ) ) (if (result f32) - (i32.eqz - (if (result i32) - (i32.const 709182789) - (i32.const -4) - (i32.const 873467920) - ) - ) + (i32.const 1230459474) (block $label$5 (result f32) - (f32.const 59953536565248) + (f32.const 121) ) (block $label$6 (result f32) (f32.const 1) @@ -557,24 +551,4 @@ (i32.const 10) ) ) - (func $deNan32 (; 19 ;) (param $0 f32) (result f32) - (if (result f32) - (f32.eq - (local.get $0) - (local.get $0) - ) - (local.get $0) - (f32.const 0) - ) - ) - (func $deNan64 (; 20 ;) (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.txt b/test/passes/translate-to-fuzz_no-fuzz-nans.txt new file mode 100644 index 000000000..e35e68315 --- /dev/null +++ b/test/passes/translate-to-fuzz_no-fuzz-nans.txt @@ -0,0 +1,580 @@ +(module + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$vj (func (param i64))) + (type $FUNCSIG$vf (func (param f32))) + (type $FUNCSIG$vd (func (param f64))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$jddfiV (func (param f64 f64 f32 i32 v128) (result i64))) + (type $FUNCSIG$viViVjV (func (param i32 v128 i32 v128 i64 v128))) + (type $FUNCSIG$VVVVVii (func (param v128 v128 v128 v128 i32 i32) (result v128))) + (type $FUNCSIG$fddffj (func (param f64 f64 f32 f32 i64) (result f32))) + (type $FUNCSIG$j (func (result i64))) + (type $FUNCSIG$i (func (result i32))) + (type $FUNCSIG$f (func (result f32))) + (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))) + (memory $0 (shared 1 1)) + (data (i32.const 0) "n\00\05E\00\00\00\00") + (table $0 6 6 funcref) + (elem (i32.const 0) $func_6 $func_12 $func_12 $func_12 $func_15 $func_16) + (global $global$0 (mut f32) (f32.const 536870912)) + (global $global$1 (mut f32) (f32.const 2147483648)) + (global $global$2 (mut f64) (f64.const -1048576)) + (global $global$3 (mut f64) (f64.const 23643)) + (global $hangLimit (mut i32) (i32.const 10)) + (export "func_4" (func $func_4)) + (export "func_5" (func $func_5)) + (export "func_6_invoker" (func $func_6_invoker)) + (export "func_8" (func $func_8)) + (export "func_8_invoker" (func $func_8_invoker)) + (export "func_10" (func $func_10)) + (export "func_10_invoker" (func $func_10_invoker)) + (export "func_12" (func $func_12)) + (export "func_13" (func $func_13)) + (export "func_14" (func $func_14)) + (export "func_16" (func $func_16)) + (export "func_17" (func $func_17)) + (export "hangLimitInitializer" (func $hangLimitInitializer)) + (func $func_4 (; 4 ;) (type $FUNCSIG$v) + (local $0 f64) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (call $log-i32 + (loop $label$22 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (call $log-i32 + (i32.const -16777216) + ) + (br_if $label$22 + (i32.const 520883468) + ) + (i32.const 925912624) + ) + ) + ) + (local.set $0 + (local.tee $0 + (local.get $0) + ) + ) + ) + ) + (func $func_5 (; 5 ;) (type $FUNCSIG$jddfiV) (param $0 f64) (param $1 f64) (param $2 f32) (param $3 i32) (param $4 v128) (result i64) + (local $5 i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (i64.const 1) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (nop) + (return + (i64.const -16777216) + ) + ) + ) + (func $func_6 (; 6 ;) (param $0 i32) (result i64) + (local $1 v128) + (local $2 f64) + (local $3 i32) + (local $4 v128) + (local $5 f64) + (local $6 f32) + (local $7 i64) + (local $8 i64) + (local $9 f64) + (local $10 i64) + (local $11 i64) + (local $12 v128) + (local $13 f32) + (local $14 i32) + (local $15 f64) + (local $16 f32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (local.get $7) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (i64.const 18014398509481984) + ) + (func $func_6_invoker (; 7 ;) (type $FUNCSIG$v) + (drop + (call $func_6 + (i32.const 225118223) + ) + ) + ) + (func $func_8 (; 8 ;) (type $FUNCSIG$viViVjV) (param $0 i32) (param $1 v128) (param $2 i32) (param $3 v128) (param $4 i64) (param $5 v128) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (local.set $5 + (local.tee $5 + (loop $label$1 (result v128) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result v128) + (drop + (if (result i32) + (i32.eqz + (loop $label$25 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block + (block $label$26 + (if + (local.get $0) + (nop) + (block $label$27 + (nop) + (nop) + ) + ) + (block $label$28 + (nop) + ) + (local.set $4 + (block $label$29 (result i64) + (call $log-f64 + (f64.const 72) + ) + (local.tee $4 + (local.tee $4 + (local.tee $4 + (br_if $label$29 + (block $label$30 (result i64) + (br_if $label$25 + (local.get $2) + ) + (i64.const 4294967229) + ) + (i32.eqz + (i32.const 0) + ) + ) + ) + ) + ) + ) + ) + ) + (br_if $label$25 + (i32.eqz + (local.tee $0 + (local.tee $2 + (local.tee $0 + (local.tee $0 + (local.tee $0 + (local.tee $0 + (local.tee $2 + (local.tee $0 + (i32.const 1215581264) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (local.tee $0 + (loop $label$31 + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$32 + (local.set $2 + (i32.const -127) + ) + (br $label$25) + ) + ) + ) + ) + ) + ) + (i32.const 9282) + (block $label$33 (result i32) + (local.get $0) + ) + ) + ) + (br_if $label$1 + (i32.const -1) + ) + (v128.const i32 0xb2 0xc0 0x0 0xb 0x0 0x2 0x1 0x1f 0x1 0xff 0x0 0xff 0x0 0xed 0xf 0xff) + ) + ) + ) + ) + (local.set $5 + (v128.const i32 0x0 0x0 0x19 0x80 0x1b 0x2 0x0 0xeb 0x4a 0x1a 0x0 0x7f 0x80 0x12 0x5d 0x0) + ) + ) + ) + (func $func_8_invoker (; 9 ;) (type $FUNCSIG$v) + (call $func_8 + (i32.const 68) + (v128.const i32 0x70 0x38 0x37 0x25 0x3d 0x79 0x3c 0x31 0x2 0x9 0xc 0x15 0xa 0x3 0x4c 0x1f) + (i32.const 420088586) + (v128.const i32 0x9 0x1b 0xfe 0xff 0x0 0x0 0xfe 0xff 0x15 0x16 0xb 0x5f 0xe6 0xff 0x3d 0x46) + (i64.const 2055) + (v128.const i32 0x0 0x0 0x0 0x0 0x0 0x0 0xe0 0x43 0x0 0x0 0x0 0x0 0x0 0x60 0x6c 0x40) + ) + ) + (func $func_10 (; 10 ;) (type $FUNCSIG$vd) (param $0 f64) + (local $1 i32) + (local $2 i64) + (local $3 f64) + (local $4 f64) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (nop) + (br_if $label$0 + (local.get $1) + ) + ) + ) + (func $func_10_invoker (; 11 ;) (type $FUNCSIG$v) + (call $func_10 + (f64.const 0) + ) + (call $func_10 + (f64.const -81) + ) + (call $func_10 + (f64.const -91) + ) + ) + (func $func_12 (; 12 ;) (type $FUNCSIG$VVVVVii) (param $0 v128) (param $1 v128) (param $2 v128) (param $3 v128) (param $4 i32) (param $5 i32) (result v128) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (v128.const i32 0x0 0x0 0x4 0xff 0x46 0x1d 0x37 0xff 0x2 0x0 0x0 0x6f 0x18 0x43 0x0 0x0) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (call $log-i64 + (i64.const -17179869184) + ) + (return + (local.get $0) + ) + ) + ) + (func $func_13 (; 13 ;) (type $FUNCSIG$fddffj) (param $0 f64) (param $1 f64) (param $2 f32) (param $3 f32) (param $4 i64) (result f32) + (local $5 f32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (local.get $3) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (nop) + (return + (f32.const -562949953421312) + ) + ) + ) + (func $func_14 (; 14 ;) (type $FUNCSIG$j) (result i64) + (local $0 v128) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (i64.const -4294967295) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (call $log-f64 + (f64.const 3.0085765013203267e-46) + ) + (return + (i64.const 117901063) + ) + ) + ) + (func $func_15 (; 15 ;) + (local $0 v128) + (local $1 i64) + (local $2 i32) + (local $3 f64) + (local $4 f64) + (local $5 v128) + (local $6 i64) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block $label$0 + (local.set $5 + (v128.const i32 0x4e 0x5d 0x1b 0x5d 0x54 0x1b 0x48 0x48 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xf8) + ) + (nop) + ) + ) + (func $func_16 (; 16 ;) (type $FUNCSIG$i) (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (i32.const 0) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (loop $label$0 (result i32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (i32.const 32767) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (block (result i32) + (block $label$1 + (block $label$2 + (block $label$3 + (nop) + (nop) + ) + (nop) + ) + (nop) + (nop) + ) + (br_if $label$0 + (i32.const 1147035403) + ) + (i32.const 1024) + ) + ) + ) + (func $func_17 (; 17 ;) (type $FUNCSIG$f) (result f32) + (block + (if + (i32.eqz + (global.get $hangLimit) + ) + (return + (f32.const 865309568) + ) + ) + (global.set $hangLimit + (i32.sub + (global.get $hangLimit) + (i32.const 1) + ) + ) + ) + (if (result f32) + (i32.eqz + (if (result i32) + (i32.const 709182789) + (i32.const -4) + (i32.const 873467920) + ) + ) + (block $label$5 (result f32) + (f32.const 59953536565248) + ) + (block $label$6 (result f32) + (f32.const 1) + ) + ) + ) + (func $hangLimitInitializer (; 18 ;) + (global.set $hangLimit + (i32.const 10) + ) + ) + (func $deNan32 (; 19 ;) (param $0 f32) (result f32) + (if (result f32) + (f32.eq + (local.get $0) + (local.get $0) + ) + (local.get $0) + (f32.const 0) + ) + ) + (func $deNan64 (; 20 ;) (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.wast b/test/passes/translate-to-fuzz_no-fuzz-nans.wast new file mode 100644 index 000000000..cbf25fde1 --- /dev/null +++ b/test/passes/translate-to-fuzz_no-fuzz-nans.wast @@ -0,0 +1,99 @@ +(module # fake module here, for test harness, but it's 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 |