From ae773355c60334cb5227655fe58f53188220730d Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 13 Aug 2026 17:08:54 -0700 Subject: [PATCH] Generate tuple.extract of wide arithmetic in fuzzer The fuzzer already supported emitting wide arithmetic instructions, but only when the required type was a pair of i64s. To make it easier to generate these instructions, also generate them when a single i64 is required, randomly choosing which result to use and dropping the other. --- src/tools/fuzzing.h | 1 + src/tools/fuzzing/fuzzing.cpp | 13 ++ ...e-to-fuzz_all-features_metrics_noprint.txt | 165 +++++++++--------- 3 files changed, 98 insertions(+), 81 deletions(-) diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index d1719540279..736920829fe 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -480,6 +480,7 @@ class TranslateToFuzzReader { Expression* makeWideIntAddSub(Type type); Expression* makeWideIntMul(Type type); Expression* makeWideIntExpression(Type type); + Expression* makeWideIntExtract(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 40b80fdf076..c28026bca07 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2839,6 +2839,10 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) { &Self::makeStringMeasure, &Self::makeStringGet); } + if (type == Type::i64) { + options.add(FeatureSet::WideArithmetic | FeatureSet::Multivalue, + &Self::makeWideIntExtract); + } if (type.isTuple()) { if (type == Types::getI64Pair() && oneIn(2)) { options.add(FeatureSet::WideArithmetic, &Self::makeWideIntExpression); @@ -3553,6 +3557,15 @@ Expression* TranslateToFuzzReader::makeWideIntExpression(Type type) { return oneIn(2) ? makeWideIntAddSub(type) : makeWideIntMul(type); } +Expression* TranslateToFuzzReader::makeWideIntExtract(Type type) { + assert(wasm.features.hasWideArithmetic()); + assert(wasm.features.hasMultivalue()); + assert(type == Type::i64); + auto* child = makeWideIntExpression(Types::getI64Pair()); + Index index = upTo(2); + return builder.makeTupleExtract(child, index); +} + Expression* TranslateToFuzzReader::makeTupleExtract(Type type) { // Tuples can require locals in binary format conversions. if (!type.isDefaultable()) { 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 6310040e4a3..e19475f7818 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,90 +1,93 @@ Metrics total - [exports] : 151 - [funcs] : 263 + [exports] : 167 + [funcs] : 287 [globals] : 6 [imports] : 14 [memories] : 1 [memory-data] : 31 - [table-data] : 84 + [table-data] : 96 [tables] : 2 [tags] : 2 - [total] : 51935 - [vars] : 4780 - ArrayCmpxchg : 46 - ArrayCopy : 24 - ArrayFill : 21 - ArrayGet : 236 - ArrayLen : 394 - ArrayNew : 549 - ArrayNewFixed : 202 - ArrayRMW : 39 - ArraySet : 31 - AtomicCmpxchg : 31 - AtomicFence : 41 - AtomicNotify : 19 - AtomicRMW : 24 - Binary : 2448 - Block : 4781 - BrOn : 206 - Break : 668 - Call : 884 - CallIndirect : 134 - CallRef : 177 - Const : 7820 - ContBind : 1 - ContNew : 123 - DataDrop : 10 - Drop : 414 - GlobalGet : 2745 - GlobalSet : 1748 - I31Get : 44 - If : 1829 - Load : 196 - LocalGet : 4376 - LocalSet : 2553 - Loop : 611 - MemoryCopy : 12 - MemoryFill : 15 - MemoryInit : 10 - Nop : 471 - RefAs : 3013 - RefCast : 510 - RefEq : 189 - RefFunc : 883 - RefGetDesc : 41 - RefI31 : 225 - RefIsNull : 53 - RefNull : 3752 - RefTest : 47 - Return : 274 - SIMDExtract : 90 - SIMDLoad : 1 - SIMDShift : 1 - SIMDShuffle : 1 - SIMDTernary : 3 - Select : 188 - Store : 104 - StringConcat : 2 - StringConst : 361 - StringEncode : 45 - StringEq : 46 - StringMeasure : 33 - StringNew : 5 + [total] : 79259 + [vars] : 5045 + ArrayCmpxchg : 86 + ArrayCopy : 47 + ArrayFill : 42 + ArrayGet : 380 + ArrayLen : 716 + ArrayNew : 887 + ArrayNewFixed : 298 + ArrayRMW : 81 + ArraySet : 106 + AtomicCmpxchg : 40 + AtomicFence : 86 + AtomicNotify : 31 + AtomicRMW : 45 + Binary : 3866 + Block : 7625 + BrOn : 302 + Break : 1130 + Call : 1197 + CallIndirect : 173 + CallRef : 241 + Const : 11471 + ContBind : 4 + ContNew : 166 + DataDrop : 16 + Drop : 601 + GlobalGet : 3805 + GlobalSet : 2428 + I31Get : 81 + If : 2910 + Load : 312 + LocalGet : 7252 + LocalSet : 4643 + Loop : 927 + MemoryCopy : 19 + MemoryFill : 25 + MemoryInit : 18 + Nop : 881 + Pop : 379 + RefAs : 4388 + RefCast : 674 + RefEq : 273 + RefFunc : 1094 + RefGetDesc : 55 + RefI31 : 349 + RefIsNull : 81 + RefNull : 5253 + RefTest : 68 + Return : 447 + SIMDExtract : 188 + SIMDLoad : 3 + SIMDReplace : 4 + SIMDShuffle : 4 + SIMDTernary : 4 + Select : 333 + Store : 167 + StringConcat : 1 + StringConst : 589 + StringEncode : 71 + StringEq : 74 + StringMeasure : 83 + StringNew : 9 StringSliceWTF : 1 - StringWTF16Get : 37 - StructCmpxchg : 37 - StructGet : 311 - StructNew : 4161 - StructRMW : 31 - StructSet : 46 - TableGet : 1 - TableSet : 40 - Throw : 33 - ThrowRef : 5 - Try : 260 - TryTable : 282 - TupleExtract : 202 - TupleMake : 276 - Unary : 1510 - Unreachable : 902 + StringWTF16Get : 92 + StructCmpxchg : 61 + StructGet : 515 + StructNew : 5459 + StructRMW : 47 + StructSet : 97 + Switch : 6 + TableSet : 97 + Throw : 89 + ThrowRef : 10 + Try : 482 + TryTable : 487 + TupleExtract : 304 + TupleMake : 397 + Unary : 2298 + Unreachable : 1254 + WideIntAddSub : 18 + WideIntMul : 16