Skip to content

Commit 6733a05

Browse files
authored
Better const fuzzing (WebAssembly#2972)
Tweak floating-point numbers with not just a +-1 integer, but also a float in [-1, 1]. Apply a tweak to powers of 2 as well. This found bugs in various codebases, see WebAssembly/spec#1224
1 parent f8cd0ad commit 6733a05

3 files changed

Lines changed: 376 additions & 419 deletions

File tree

src/tools/fuzzing.h

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,38 @@ class TranslateToFuzzReader {
15461546
}
15471547
}
15481548

1549+
// Optional tweaking of the value by a small adjustment.
1550+
auto tweak = [this, type](Literal value) {
1551+
// +- 1
1552+
switch (upTo(5)) {
1553+
case 0:
1554+
value = value.add(Literal::makeFromInt32(-1, type));
1555+
break;
1556+
case 1:
1557+
value = value.add(Literal::makeFromInt32(1, type));
1558+
break;
1559+
default: {
1560+
}
1561+
}
1562+
// For floats, optionally add a non-integer adjustment in +- [-1, 1]
1563+
if (type.isFloat() && oneIn(2)) {
1564+
const int RANGE = 1000;
1565+
auto RANGE_LITERAL = Literal::makeFromInt32(RANGE, type);
1566+
// adjustment -> [0, 2 * RANGE]
1567+
auto adjustment = Literal::makeFromInt32(upTo(2 * RANGE + 1), type);
1568+
// adjustment -> [-RANGE, RANGE]
1569+
adjustment = adjustment.sub(RANGE_LITERAL);
1570+
// adjustment -> [-1, 1]
1571+
adjustment = adjustment.div(RANGE_LITERAL);
1572+
value = value.add(adjustment);
1573+
}
1574+
// Flip sign.
1575+
if (oneIn(2)) {
1576+
value = value.mul(Literal::makeFromInt32(-1, type));
1577+
}
1578+
return value;
1579+
};
1580+
15491581
switch (upTo(4)) {
15501582
case 0: {
15511583
// totally random, entire range
@@ -1680,14 +1712,7 @@ class TranslateToFuzzReader {
16801712
case Type::unreachable:
16811713
WASM_UNREACHABLE("unexpected type");
16821714
}
1683-
// tweak around special values
1684-
if (oneIn(3)) { // +- 1
1685-
value = value.add(Literal::makeFromInt32(upTo(3) - 1, type));
1686-
}
1687-
if (oneIn(2)) { // flip sign
1688-
value = value.mul(Literal::makeFromInt32(-1, type));
1689-
}
1690-
return value;
1715+
return tweak(value);
16911716
}
16921717
case 3: {
16931718
// powers of 2
@@ -1714,14 +1739,10 @@ class TranslateToFuzzReader {
17141739
case Type::unreachable:
17151740
WASM_UNREACHABLE("unexpected type");
17161741
}
1717-
// maybe negative
1718-
if (oneIn(2)) {
1719-
value = value.mul(Literal::makeFromInt32(-1, type));
1720-
}
1721-
return value;
1742+
return tweak(value);
17221743
}
17231744
}
1724-
WASM_UNREACHABLE("invalide value");
1745+
WASM_UNREACHABLE("invalid value");
17251746
}
17261747

17271748
Expression* makeConst(Type type) {
Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
total
22
[events] : 0
3-
[exports] : 31
4-
[funcs] : 45
3+
[exports] : 35
4+
[funcs] : 57
55
[globals] : 7
66
[imports] : 4
77
[memory-data] : 4
8-
[table-data] : 16
9-
[total] : 5788
10-
[vars] : 115
11-
binary : 453
12-
block : 823
13-
break : 242
14-
call : 208
15-
call_indirect : 47
16-
const : 997
17-
drop : 46
18-
global.get : 473
19-
global.set : 208
20-
if : 323
21-
load : 99
22-
local.get : 491
23-
local.set : 364
24-
loop : 148
25-
nop : 109
26-
return : 228
27-
select : 46
28-
store : 55
29-
switch : 3
30-
unary : 422
31-
unreachable : 3
8+
[table-data] : 30
9+
[total] : 2111
10+
[vars] : 153
11+
binary : 184
12+
block : 311
13+
break : 56
14+
call : 110
15+
call_indirect : 10
16+
const : 362
17+
drop : 29
18+
global.get : 187
19+
global.set : 80
20+
if : 114
21+
load : 46
22+
local.get : 153
23+
local.set : 112
24+
loop : 36
25+
nop : 46
26+
return : 105
27+
select : 13
28+
store : 11
29+
unary : 146

0 commit comments

Comments
 (0)