Skip to content

Commit fbcd71c

Browse files
authored
Fuzzer: Simplify and improve emitting of unreachable code (#7295)
In the earlier days of the fuzzer we would call makeUnary with unreachable sometimes, and then emit an unreachable i32.eqz for example. Later we added mutate() which randomly emits unreachable into places, which gives even better coverage - no need to manually handle unreachability in every single instruction. This PR removes the old form. Also remove the "Important" label from makeUnreachable. The unreachable instruction is now one of many that have that type, and we have no reason to prefer it to others. These changes have the effect of improving the chance to emit interesting instructions with unreachable type, like throw, throw_ref.
1 parent 7664807 commit fbcd71c

4 files changed

Lines changed: 91 additions & 109 deletions

File tree

src/tools/fuzzing/fuzzing.cpp

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,22 +2000,19 @@ Expression* TranslateToFuzzReader::_makeunreachable() {
20002000
using Self = TranslateToFuzzReader;
20012001
auto options = FeatureOptions<Expression* (Self::*)(Type)>();
20022002
using WeightedOption = decltype(options)::WeightedOption;
2003+
// Many instructions can become unreachable if a child is unreachable. We
2004+
// create such code in mutate() (see |allowUnreachable| there). The list of
2005+
// instructions here are those that necessarily have unreachable type, and are
2006+
// only created here (though they might have other variations that are
2007+
// reachable, like br has br_if that is created elsewhere, and we have call
2008+
// here because of return calls, etc.).
20032009
options
20042010
.add(FeatureSet::MVP,
2005-
WeightedOption{&Self::makeLocalSet, VeryImportant},
2006-
WeightedOption{&Self::makeBlock, Important},
2007-
WeightedOption{&Self::makeIf, Important},
2008-
WeightedOption{&Self::makeLoop, Important},
20092011
WeightedOption{&Self::makeBreak, Important},
2010-
WeightedOption{&Self::makeStore, Important},
2011-
WeightedOption{&Self::makeUnary, Important},
2012-
WeightedOption{&Self::makeBinary, Important},
2013-
WeightedOption{&Self::makeUnreachable, Important},
2012+
&Self::makeUnreachable,
20142013
&Self::makeCall,
20152014
&Self::makeCallIndirect,
2016-
&Self::makeSelect,
20172015
&Self::makeSwitch,
2018-
&Self::makeDrop,
20192016
&Self::makeReturn)
20202017
.add(FeatureSet::ExceptionHandling, &Self::makeThrow, &Self::makeThrowRef)
20212018
.add(FeatureSet::ReferenceTypes | FeatureSet::GC, &Self::makeCallRef);
@@ -3568,13 +3565,6 @@ Expression* TranslateToFuzzReader::buildUnary(const UnaryArgs& args) {
35683565

35693566
Expression* TranslateToFuzzReader::makeUnary(Type type) {
35703567
assert(!type.isTuple());
3571-
if (type == Type::unreachable) {
3572-
if (auto* unary = makeUnary(getSingleConcreteType())->dynCast<Unary>()) {
3573-
return builder.makeUnary(unary->op, make(Type::unreachable));
3574-
}
3575-
// give up
3576-
return makeTrivial(type);
3577-
}
35783568
// There are no unary ops for reference types.
35793569
// TODO: not quite true if you count struct.new and array.new.
35803570
if (type.isRef()) {
@@ -3789,14 +3779,6 @@ Expression* TranslateToFuzzReader::buildBinary(const BinaryArgs& args) {
37893779

37903780
Expression* TranslateToFuzzReader::makeBinary(Type type) {
37913781
assert(!type.isTuple());
3792-
if (type == Type::unreachable) {
3793-
if (auto* binary = makeBinary(getSingleConcreteType())->dynCast<Binary>()) {
3794-
return buildBinary(
3795-
{binary->op, make(Type::unreachable), make(Type::unreachable)});
3796-
}
3797-
// give up
3798-
return makeTrivial(type);
3799-
}
38003782
// There are no binary ops for reference types.
38013783
// TODO: Use struct.new
38023784
if (type.isRef()) {
@@ -4077,8 +4059,7 @@ Expression* TranslateToFuzzReader::makeSwitch(Type type) {
40774059
}
40784060

40794061
Expression* TranslateToFuzzReader::makeDrop(Type type) {
4080-
return builder.makeDrop(
4081-
make(type == Type::unreachable ? type : getConcreteType()));
4062+
return builder.makeDrop(make(getConcreteType()));
40824063
}
40834064

40844065
Expression* TranslateToFuzzReader::makeReturn(Type type) {
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
Metrics
22
total
3-
[exports] : 65
4-
[funcs] : 85
3+
[exports] : 84
4+
[funcs] : 115
55
[globals] : 18
66
[imports] : 4
77
[memories] : 1
88
[memory-data] : 24
9-
[table-data] : 24
9+
[table-data] : 49
1010
[tables] : 1
1111
[tags] : 0
12-
[total] : 8396
13-
[vars] : 239
14-
Binary : 573
15-
Block : 1420
16-
Break : 276
17-
Call : 382
18-
CallIndirect : 56
19-
Const : 1258
20-
Drop : 124
21-
GlobalGet : 731
22-
GlobalSet : 531
23-
If : 468
24-
Load : 129
25-
LocalGet : 578
26-
LocalSet : 422
27-
Loop : 173
28-
Nop : 134
29-
RefFunc : 24
30-
Return : 122
31-
Select : 58
32-
Store : 57
33-
Switch : 6
34-
Unary : 605
35-
Unreachable : 269
12+
[total] : 10300
13+
[vars] : 325
14+
Binary : 679
15+
Block : 1736
16+
Break : 323
17+
Call : 340
18+
CallIndirect : 93
19+
Const : 1686
20+
Drop : 129
21+
GlobalGet : 882
22+
GlobalSet : 665
23+
If : 581
24+
Load : 146
25+
LocalGet : 738
26+
LocalSet : 614
27+
Loop : 211
28+
Nop : 156
29+
RefFunc : 49
30+
Return : 111
31+
Select : 67
32+
Store : 83
33+
Switch : 1
34+
Unary : 680
35+
Unreachable : 330
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
Metrics
22
total
3-
[exports] : 84
4-
[funcs] : 112
3+
[exports] : 46
4+
[funcs] : 62
55
[globals] : 17
66
[imports] : 4
77
[memories] : 1
88
[memory-data] : 11
9-
[table-data] : 36
9+
[table-data] : 11
1010
[tables] : 1
1111
[tags] : 0
12-
[total] : 7833
13-
[vars] : 292
14-
Binary : 578
15-
Block : 1340
16-
Break : 204
17-
Call : 414
18-
CallIndirect : 35
19-
Const : 1256
20-
Drop : 107
21-
GlobalGet : 698
22-
GlobalSet : 535
23-
If : 418
24-
Load : 134
25-
LocalGet : 502
26-
LocalSet : 331
27-
Loop : 149
28-
Nop : 87
29-
RefFunc : 36
30-
Return : 103
31-
Select : 49
32-
Store : 70
33-
Switch : 6
34-
Unary : 508
35-
Unreachable : 273
12+
[total] : 4599
13+
[vars] : 195
14+
Binary : 353
15+
Block : 753
16+
Break : 106
17+
Call : 195
18+
CallIndirect : 39
19+
Const : 776
20+
Drop : 77
21+
GlobalGet : 381
22+
GlobalSet : 299
23+
If : 220
24+
Load : 83
25+
LocalGet : 346
26+
LocalSet : 266
27+
Loop : 83
28+
Nop : 46
29+
RefFunc : 11
30+
Return : 67
31+
Select : 20
32+
Store : 33
33+
Switch : 2
34+
Unary : 299
35+
Unreachable : 144
Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,46 @@
11
Metrics
22
total
3-
[exports] : 14
4-
[funcs] : 18
3+
[exports] : 13
4+
[funcs] : 14
55
[globals] : 4
66
[imports] : 12
77
[memories] : 1
88
[memory-data] : 112
9-
[table-data] : 3
9+
[table-data] : 2
1010
[tables] : 1
1111
[tags] : 0
12-
[total] : 626
13-
[vars] : 49
14-
ArrayNew : 1
15-
ArrayNewFixed : 5
16-
ArraySet : 1
17-
AtomicCmpxchg : 1
18-
AtomicFence : 1
12+
[total] : 654
13+
[vars] : 15
14+
ArrayGet : 1
15+
ArrayLen : 1
16+
ArrayNew : 6
17+
ArrayNewFixed : 11
1918
Binary : 74
20-
Block : 79
21-
Call : 40
22-
Const : 138
23-
Drop : 9
24-
GlobalGet : 42
25-
GlobalSet : 38
26-
If : 20
27-
Load : 16
28-
LocalGet : 46
29-
LocalSet : 22
30-
Loop : 2
31-
Nop : 4
19+
Block : 64
20+
Call : 43
21+
CallIndirect : 1
22+
Const : 170
23+
Drop : 7
24+
GlobalGet : 38
25+
GlobalSet : 32
26+
If : 18
27+
Load : 17
28+
LocalGet : 42
29+
LocalSet : 23
30+
Loop : 3
31+
Nop : 3
3232
RefAs : 2
33-
RefFunc : 8
34-
RefNull : 4
33+
RefFunc : 7
34+
RefNull : 7
3535
Return : 3
3636
Select : 1
3737
Store : 1
38-
StringConst : 3
39-
StructNew : 18
38+
StringConst : 1
39+
StringEncode : 1
40+
StructNew : 37
4041
StructSet : 1
4142
Throw : 1
4243
TryTable : 2
4344
TupleMake : 3
44-
Unary : 21
45-
Unreachable : 19
45+
Unary : 17
46+
Unreachable : 16

0 commit comments

Comments
 (0)