Skip to content

Commit ac6c001

Browse files
Fuzz wide arithmetic instructions (#8661)
Part of #8544. Continued in #8781. Drive-by fix: ensure that tuples aren't generated with a size larger than TUPLE_MAX_SIZE: ```diff - size_t maxElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 1); + size_t maxElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 2); ``` After increasing the seed file size, the wide arithmetic instructions [were generated](https://github.com/WebAssembly/binaryen/actions/runs/26316945566/job/77478064626) (ctrl + f "wideint"), but fails in CI due to #8770. For now I leave the seed file unchanged without showing that the wide arithmetic instructions are generated in the golden file. Also generated a new seed for test/lit/fuzz-import.wast since it was failing after these changes, seemingly due to bad luck (which the test file mentions is a possibility).
1 parent 04adfce commit ac6c001

6 files changed

Lines changed: 86 additions & 49 deletions

File tree

src/tools/fuzzing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ class TranslateToFuzzReader {
477477
Expression* makeGlobalGet(Type type);
478478
Expression* makeGlobalSet(Type type);
479479
Expression* makeTupleMake(Type type);
480+
Expression* makeWideIntAddSub(Type type);
481+
Expression* makeWideIntMul(Type type);
482+
Expression* makeWideIntExpression(Type type);
480483
Expression* makeTupleExtract(Type type);
481484
Expression* makePointer();
482485
Expression* makeNonAtomicLoad(Type type);

src/tools/fuzzing/fuzzing.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2812,7 +2812,11 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
28122812
&Self::makeStringGet);
28132813
}
28142814
if (type.isTuple()) {
2815-
options.add(FeatureSet::Multivalue, &Self::makeTupleMake);
2815+
if (type == Types::getI64Pair() && oneIn(2)) {
2816+
options.add(FeatureSet::WideArithmetic, &Self::makeWideIntExpression);
2817+
} else {
2818+
options.add(FeatureSet::Multivalue, &Self::makeTupleMake);
2819+
}
28162820
}
28172821
if (type.isRef()) {
28182822
auto heapType = type.getHeapType();
@@ -3495,6 +3499,30 @@ Expression* TranslateToFuzzReader::makeTupleMake(Type type) {
34953499
return builder.makeTupleMake(std::move(elements));
34963500
}
34973501

3502+
Expression* TranslateToFuzzReader::makeWideIntAddSub(Type type) {
3503+
assert(wasm.features.hasWideArithmetic());
3504+
assert(type == Types::getI64Pair());
3505+
auto op = oneIn(2) ? AddInt128 : SubInt128;
3506+
auto* leftLow = make(Type::i64);
3507+
auto* leftHigh = make(Type::i64);
3508+
auto* rightLow = make(Type::i64);
3509+
auto* rightHigh = make(Type::i64);
3510+
return builder.makeWideIntAddSub(op, leftLow, leftHigh, rightLow, rightHigh);
3511+
}
3512+
3513+
Expression* TranslateToFuzzReader::makeWideIntMul(Type type) {
3514+
assert(wasm.features.hasWideArithmetic());
3515+
assert(type == Types::getI64Pair());
3516+
auto op = oneIn(2) ? MulWideSInt64 : MulWideUInt64;
3517+
auto* left = make(Type::i64);
3518+
auto* right = make(Type::i64);
3519+
return builder.makeWideIntMul(op, left, right);
3520+
}
3521+
3522+
Expression* TranslateToFuzzReader::makeWideIntExpression(Type type) {
3523+
return oneIn(2) ? makeWideIntAddSub(type) : makeWideIntMul(type);
3524+
}
3525+
34983526
Expression* TranslateToFuzzReader::makeTupleExtract(Type type) {
34993527
// Tuples can require locals in binary format conversions.
35003528
if (!type.isDefaultable()) {
@@ -6425,9 +6453,14 @@ Type TranslateToFuzzReader::getMVPType() {
64256453
}
64266454

64276455
Type TranslateToFuzzReader::getTupleType() {
6456+
// Give a significant chance to an i64 pair, for wide arithmetic.
6457+
if (wasm.features.hasWideArithmetic() && oneIn(5)) {
6458+
return Types::getI64Pair();
6459+
}
6460+
64286461
std::vector<Type> elements;
6429-
size_t maxElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 1);
6430-
for (size_t i = 0; i < maxElements; ++i) {
6462+
size_t numElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 2);
6463+
for (size_t i = 0; i < numElements; ++i) {
64316464
auto type = getSingleConcreteType();
64326465
// Don't add a non-defaultable type into a tuple, as currently we can't
64336466
// spill them into locals (that would require a "let").

src/tools/fuzzing/heap-types.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ struct HeapTypeGeneratorImpl {
422422
}
423423

424424
Type generateTupleType(Shareability share) {
425-
std::vector<Type> types(2 + rand.upTo(params.MAX_TUPLE_SIZE - 1));
425+
std::vector<Type> types(2 + rand.upTo(params.MAX_TUPLE_SIZE - 2));
426426
for (auto& type : types) {
427427
type = generateSingleType(share);
428428
}

src/tools/fuzzing/parameters.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void FuzzParams::setDefaults() {
2626

2727
MAX_GLOBALS = 30;
2828

29-
MAX_TUPLE_SIZE = 6;
29+
MAX_TUPLE_SIZE = 7;
3030

3131
MAX_STRUCT_SIZE = 6;
3232

test/lit/fuzz-import.wast.dat

73 Bytes
Binary file not shown.
Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
11
Metrics
22
total
3-
[exports] : 10
3+
[exports] : 9
44
[funcs] : 5
55
[globals] : 2
6-
[imports] : 13
6+
[imports] : 12
77
[memories] : 1
88
[memory-data] : 16
9-
[table-data] : 2
9+
[table-data] : 3
1010
[tables] : 2
11-
[tags] : 3
12-
[total] : 704
13-
[vars] : 26
14-
ArrayNewFixed : 6
15-
AtomicFence : 3
16-
Binary : 30
17-
Block : 130
18-
BrOn : 6
19-
Break : 23
20-
Call : 30
21-
CallRef : 2
22-
Const : 103
23-
Drop : 10
24-
GlobalGet : 44
25-
GlobalSet : 42
26-
I31Get : 3
27-
If : 39
28-
Load : 6
29-
LocalGet : 25
30-
LocalSet : 27
31-
Loop : 16
32-
MemoryInit : 1
33-
Nop : 7
11+
[tags] : 2
12+
[total] : 717
13+
[vars] : 24
14+
ArrayNew : 4
15+
ArrayNewFixed : 9
16+
AtomicFence : 2
17+
AtomicNotify : 2
18+
Binary : 40
19+
Block : 114
20+
BrOn : 3
21+
Break : 24
22+
Call : 15
23+
CallRef : 3
24+
Const : 122
25+
Drop : 8
26+
GlobalGet : 40
27+
GlobalSet : 36
28+
I31Get : 1
29+
If : 34
30+
Load : 7
31+
LocalGet : 27
32+
LocalSet : 36
33+
Loop : 13
34+
Nop : 19
3435
Pop : 6
35-
RefEq : 1
36-
RefFunc : 11
37-
RefI31 : 10
38-
RefNull : 10
39-
RefTest : 7
40-
Return : 3
41-
Select : 1
42-
Store : 2
43-
StringConst : 7
44-
StringEq : 1
45-
StringMeasure : 2
46-
StringWTF16Get : 2
36+
RefAs : 3
37+
RefEq : 3
38+
RefFunc : 10
39+
RefI31 : 5
40+
RefIsNull : 1
41+
RefNull : 3
42+
Return : 2
43+
SIMDExtract : 5
44+
Select : 3
45+
Store : 4
46+
StringConst : 15
47+
StringEncode : 5
48+
StringEq : 2
49+
StringMeasure : 1
4750
StructNew : 8
48-
TableSet : 2
49-
Throw : 2
50-
Try : 6
51+
Try : 7
5152
TryTable : 6
5253
TupleExtract : 3
53-
TupleMake : 5
54-
Unary : 35
55-
Unreachable : 21
54+
TupleMake : 7
55+
Unary : 40
56+
Unreachable : 19

0 commit comments

Comments
 (0)