diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 803e13d5d0b..abc21c60a1a 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -477,6 +477,9 @@ class TranslateToFuzzReader { Expression* makeGlobalGet(Type type); Expression* makeGlobalSet(Type type); Expression* makeTupleMake(Type type); + Expression* makeWideIntAddSub(Type type); + Expression* makeWideIntMul(Type type); + Expression* makeWideIntExpression(Type type); Expression* makeTupleExtract(Type type); Expression* makePointer(); Expression* makeNonAtomicLoad(Type type); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 759061da88f..e94ddcbfc44 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2813,7 +2813,11 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) { &Self::makeStringGet); } if (type.isTuple()) { - options.add(FeatureSet::Multivalue, &Self::makeTupleMake); + if (type == Types::getI64Pair() && oneIn(2)) { + options.add(FeatureSet::WideArithmetic, &Self::makeWideIntExpression); + } else { + options.add(FeatureSet::Multivalue, &Self::makeTupleMake); + } } if (type.isRef()) { auto heapType = type.getHeapType(); @@ -3496,6 +3500,30 @@ Expression* TranslateToFuzzReader::makeTupleMake(Type type) { return builder.makeTupleMake(std::move(elements)); } +Expression* TranslateToFuzzReader::makeWideIntAddSub(Type type) { + assert(wasm.features.hasWideArithmetic()); + assert(type == Types::getI64Pair()); + auto op = oneIn(2) ? AddInt128 : SubInt128; + auto* leftLow = make(Type::i64); + auto* leftHigh = make(Type::i64); + auto* rightLow = make(Type::i64); + auto* rightHigh = make(Type::i64); + return builder.makeWideIntAddSub(op, leftLow, leftHigh, rightLow, rightHigh); +} + +Expression* TranslateToFuzzReader::makeWideIntMul(Type type) { + assert(wasm.features.hasWideArithmetic()); + assert(type == Types::getI64Pair()); + auto op = oneIn(2) ? MulWideSInt64 : MulWideUInt64; + auto* left = make(Type::i64); + auto* right = make(Type::i64); + return builder.makeWideIntMul(op, left, right); +} + +Expression* TranslateToFuzzReader::makeWideIntExpression(Type type) { + return oneIn(2) ? makeWideIntAddSub(type) : makeWideIntMul(type); +} + Expression* TranslateToFuzzReader::makeTupleExtract(Type type) { // Tuples can require locals in binary format conversions. if (!type.isDefaultable()) { @@ -6426,9 +6454,14 @@ Type TranslateToFuzzReader::getMVPType() { } Type TranslateToFuzzReader::getTupleType() { + // Give a significant chance to an i64 pair, for wide arithmetic. + if (wasm.features.hasWideArithmetic() && oneIn(5)) { + return Types::getI64Pair(); + } + std::vector elements; - size_t maxElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 1); - for (size_t i = 0; i < maxElements; ++i) { + size_t numElements = 2 + upTo(fuzzParams->MAX_TUPLE_SIZE - 2); + for (size_t i = 0; i < numElements; ++i) { auto type = getSingleConcreteType(); // Don't add a non-defaultable type into a tuple, as currently we can't // spill them into locals (that would require a "let"). diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index e2b6b552623..41d3a1cf084 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -422,7 +422,7 @@ struct HeapTypeGeneratorImpl { } Type generateTupleType(Shareability share) { - std::vector types(2 + rand.upTo(params.MAX_TUPLE_SIZE - 1)); + std::vector types(2 + rand.upTo(params.MAX_TUPLE_SIZE - 2)); for (auto& type : types) { type = generateSingleType(share); } diff --git a/src/tools/fuzzing/parameters.cpp b/src/tools/fuzzing/parameters.cpp index 3220f9625d3..423cad941d5 100644 --- a/src/tools/fuzzing/parameters.cpp +++ b/src/tools/fuzzing/parameters.cpp @@ -26,7 +26,7 @@ void FuzzParams::setDefaults() { MAX_GLOBALS = 30; - MAX_TUPLE_SIZE = 6; + MAX_TUPLE_SIZE = 7; MAX_STRUCT_SIZE = 6; diff --git a/test/lit/fuzz-import.wast.dat b/test/lit/fuzz-import.wast.dat index 922d620d004..172f50c7db9 100644 Binary files a/test/lit/fuzz-import.wast.dat and b/test/lit/fuzz-import.wast.dat differ diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index 961f8e1e8bc..7e417cb72b4 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,55 +1,56 @@ Metrics total - [exports] : 10 + [exports] : 9 [funcs] : 5 [globals] : 2 - [imports] : 13 + [imports] : 12 [memories] : 1 [memory-data] : 16 - [table-data] : 2 + [table-data] : 3 [tables] : 2 - [tags] : 3 - [total] : 704 - [vars] : 26 - ArrayNewFixed : 6 - AtomicFence : 3 - Binary : 30 - Block : 130 - BrOn : 6 - Break : 23 - Call : 30 - CallRef : 2 - Const : 103 - Drop : 10 - GlobalGet : 44 - GlobalSet : 42 - I31Get : 3 - If : 39 - Load : 6 - LocalGet : 25 - LocalSet : 27 - Loop : 16 - MemoryInit : 1 - Nop : 7 + [tags] : 2 + [total] : 717 + [vars] : 24 + ArrayNew : 4 + ArrayNewFixed : 9 + AtomicFence : 2 + AtomicNotify : 2 + Binary : 40 + Block : 114 + BrOn : 3 + Break : 24 + Call : 15 + CallRef : 3 + Const : 122 + Drop : 8 + GlobalGet : 40 + GlobalSet : 36 + I31Get : 1 + If : 34 + Load : 7 + LocalGet : 27 + LocalSet : 36 + Loop : 13 + Nop : 19 Pop : 6 - RefEq : 1 - RefFunc : 11 - RefI31 : 10 - RefNull : 10 - RefTest : 7 - Return : 3 - Select : 1 - Store : 2 - StringConst : 7 - StringEq : 1 - StringMeasure : 2 - StringWTF16Get : 2 + RefAs : 3 + RefEq : 3 + RefFunc : 10 + RefI31 : 5 + RefIsNull : 1 + RefNull : 3 + Return : 2 + SIMDExtract : 5 + Select : 3 + Store : 4 + StringConst : 15 + StringEncode : 5 + StringEq : 2 + StringMeasure : 1 StructNew : 8 - TableSet : 2 - Throw : 2 - Try : 6 + Try : 7 TryTable : 6 TupleExtract : 3 - TupleMake : 5 - Unary : 35 - Unreachable : 21 + TupleMake : 7 + Unary : 40 + Unreachable : 19