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..2bd6dd79109 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,13 @@ Type TranslateToFuzzReader::getMVPType() { } Type TranslateToFuzzReader::getTupleType() { + if (wasm.features.hasWideArithmetic() && oneIn(2)) { + 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"). @@ -6443,7 +6475,7 @@ Type TranslateToFuzzReader::getTupleType() { } Type TranslateToFuzzReader::getConcreteType() { - if (wasm.features.hasMultivalue() && oneIn(5)) { + if (wasm.features.hasMultivalue() && oneIn(2)) { return getTupleType(); } else { return getSingleConcreteType(); 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..1af95448afd 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,59 @@ Metrics total - [exports] : 10 - [funcs] : 5 + [exports] : 16 + [funcs] : 21 [globals] : 2 - [imports] : 13 + [imports] : 14 [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 + [tags] : 2 + [total] : 694 + [vars] : 70 + ArrayNewFixed : 4 + AtomicFence : 1 + AtomicNotify : 3 + Binary : 34 + Block : 122 + BrOn : 1 + Break : 9 + Call : 32 + CallIndirect : 2 + Const : 144 + Drop : 18 + GlobalGet : 54 + GlobalSet : 54 + I31Get : 1 + If : 38 + Load : 2 + LocalGet : 12 + LocalSet : 8 + Loop : 6 MemoryInit : 1 - Nop : 7 - Pop : 6 - RefEq : 1 - RefFunc : 11 - RefI31 : 10 - RefNull : 10 - RefTest : 7 - Return : 3 + Nop : 10 + Pop : 3 + RefAs : 2 + RefEq : 3 + RefFunc : 5 + RefI31 : 12 + RefIsNull : 1 + RefNull : 1 + RefTest : 1 + Return : 4 + SIMDExtract : 2 Select : 1 Store : 2 - StringConst : 7 - StringEq : 1 - StringMeasure : 2 - StringWTF16Get : 2 - StructNew : 8 - TableSet : 2 - Throw : 2 - Try : 6 - TryTable : 6 + StringConst : 8 + StringMeasure : 1 + StructNew : 3 + Switch : 1 + TableSet : 1 + Throw : 3 + ThrowRef : 1 + Try : 4 + TryTable : 5 TupleExtract : 3 - TupleMake : 5 - Unary : 35 - Unreachable : 21 + TupleMake : 6 + Unary : 37 + Unreachable : 28