summaryrefslogtreecommitdiff
path: root/src/tools/fuzzing.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-10-21 09:03:56 -0700
committerGitHub <noreply@github.com>2020-10-21 09:03:56 -0700
commitb7c452ea1bf0ebce9f8da19e8124c20b4373a009 (patch)
tree575bc5ede60ffdad8fc3c71cda5c1478ae74279b /src/tools/fuzzing.h
parentfd4cfd180db4d8c9b2b99dca18e31763399b4702 (diff)
downloadbinaryen-b7c452ea1bf0ebce9f8da19e8124c20b4373a009.tar.gz
binaryen-b7c452ea1bf0ebce9f8da19e8124c20b4373a009.tar.bz2
binaryen-b7c452ea1bf0ebce9f8da19e8124c20b4373a009.zip
Fuzzer: Tweak constants during mutation as well (#3272)
Move the tweak function to an outer location, and call it from mutate() with some probability.
Diffstat (limited to 'src/tools/fuzzing.h')
-rw-r--r--src/tools/fuzzing.h80
1 files changed, 47 insertions, 33 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index d2cdb7a7f..36cf1fb42 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -675,7 +675,16 @@ private:
void visitExpression(Expression* curr) {
if (parent.oneIn(10)) {
- // Replace it!
+ // For constants, perform only a small tweaking in some cases.
+ if (auto* c = curr->dynCast<Const>()) {
+ if (parent.oneIn(2)) {
+ c->value = parent.tweak(c->value);
+ return;
+ }
+ }
+ // TODO: more minor tweaks to immediates, like making a load atomic or
+ // not, changing an offset, etc.
+ // Perform a general replacement.
// (This is not always valid due to nesting of labels, but
// we'll fix that up later.)
replaceCurrent(parent.make(curr->type));
@@ -1536,6 +1545,43 @@ private:
return store;
}
+ // Makes a small change to a constant value.
+ Literal tweak(Literal value) {
+ auto type = value.type;
+ if (type.isVector()) {
+ // TODO: tweak each lane?
+ return value;
+ }
+ // +- 1
+ switch (upTo(5)) {
+ case 0:
+ value = value.add(Literal::makeNegOne(type));
+ break;
+ case 1:
+ value = value.add(Literal::makeOne(type));
+ break;
+ default: {
+ }
+ }
+ // For floats, optionally add a non-integer adjustment in +- [-1, 1]
+ if (type.isFloat() && oneIn(2)) {
+ const int RANGE = 1000;
+ auto RANGE_LITERAL = Literal::makeFromInt32(RANGE, type);
+ // adjustment -> [0, 2 * RANGE]
+ auto adjustment = Literal::makeFromInt32(upTo(2 * RANGE + 1), type);
+ // adjustment -> [-RANGE, RANGE]
+ adjustment = adjustment.sub(RANGE_LITERAL);
+ // adjustment -> [-1, 1]
+ adjustment = adjustment.div(RANGE_LITERAL);
+ value = value.add(adjustment);
+ }
+ // Flip sign.
+ if (oneIn(2)) {
+ value = value.mul(Literal::makeNegOne(type));
+ }
+ return value;
+ }
+
Literal makeLiteral(Type type) {
if (type == Type::v128) {
// generate each lane individually for random lane interpretation
@@ -1587,38 +1633,6 @@ private:
}
}
- // Optional tweaking of the value by a small adjustment.
- auto tweak = [this, type](Literal value) {
- // +- 1
- switch (upTo(5)) {
- case 0:
- value = value.add(Literal::makeNegOne(type));
- break;
- case 1:
- value = value.add(Literal::makeOne(type));
- break;
- default: {
- }
- }
- // For floats, optionally add a non-integer adjustment in +- [-1, 1]
- if (type.isFloat() && oneIn(2)) {
- const int RANGE = 1000;
- auto RANGE_LITERAL = Literal::makeFromInt32(RANGE, type);
- // adjustment -> [0, 2 * RANGE]
- auto adjustment = Literal::makeFromInt32(upTo(2 * RANGE + 1), type);
- // adjustment -> [-RANGE, RANGE]
- adjustment = adjustment.sub(RANGE_LITERAL);
- // adjustment -> [-1, 1]
- adjustment = adjustment.div(RANGE_LITERAL);
- value = value.add(adjustment);
- }
- // Flip sign.
- if (oneIn(2)) {
- value = value.mul(Literal::makeNegOne(type));
- }
- return value;
- };
-
switch (upTo(4)) {
case 0: {
// totally random, entire range