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 /src/tools/wasm-reduce.cpp | |
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
Diffstat (limited to 'src/tools/wasm-reduce.cpp')
-rw-r--r-- | src/tools/wasm-reduce.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
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 |