diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h index 603a5a6ecfd..071ee2cdfe6 100644 --- a/src/ir/subtype-exprs.h +++ b/src/ir/subtype-exprs.h @@ -390,7 +390,11 @@ struct SubtypingDiscoverer : public OverriddenVisitor { return; } const auto& fields = curr->ref->type.getHeapType().getStruct().fields; - self()->noteSubtype(curr->expected, fields[curr->index].type); + auto expectedType = fields[curr->index].type; + if (expectedType.isRef()) { + expectedType = Type(HeapTypes::eq.getBasic(Shared), Nullable); + } + self()->noteSubtype(curr->expected, expectedType); } void visitWaitqueueNew(WaitqueueNew* curr) {} void visitWaitqueueNotify(WaitqueueNotify* curr) { diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp index 1afda6dbc4f..232aa63766d 100644 --- a/src/passes/TypeRefining.cpp +++ b/src/passes/TypeRefining.cpp @@ -568,19 +568,6 @@ struct TypeRefining : public Pass { curr->replacement = fixType(curr->replacement, fieldType); } - void visitStructWait(StructWait* curr) { - if (curr->ref->type == Type::unreachable) { - return; - } - auto type = curr->ref->type.getHeapType(); - if (type.isBottom()) { - return; - } - - auto fieldType = type.getStruct().fields[curr->index].type; - curr->expected = fixType(curr->expected, fieldType); - } - bool refinalize = false; // Fix up a given value so it fits into the type the location it is diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 736920829fe..c6085511690 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -220,6 +220,9 @@ class TranslateToFuzzReader { // All struct fields that are mutable. std::vector mutableStructFields; + // All struct fields that can be waited on. + std::vector structWaitFields; + // All arrays that are mutable. std::vector mutableArrays; @@ -560,6 +563,8 @@ class TranslateToFuzzReader { Expression* makeStructRMW(Type type); Expression* makeStructCmpxchg(Type type); Expression* makeStructSet(Type type); + Expression* makeStructWait(Type type); + Expression* makeWaitqueueNotify(Type type); Expression* makeArrayGet(Type type); Expression* makeArraySet(Type type); Expression* makeArrayRMW(Type type); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index d906b706c5f..800a7df5ab9 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -603,11 +603,19 @@ void TranslateToFuzzReader::setupHeapTypes() { interestingHeapSubTypes[struct_].push_back(type); interestingHeapSubTypes[eq].push_back(type); interestingHeapSubTypes[any].push_back(type); - // Note the mutable fields. - auto& fields = type.getStruct().fields; + // Note the mutable fields and fields that can be waited on. + const auto& fields = type.getStruct().fields; for (Index i = 0; i < fields.size(); i++) { if (fields[i].mutable_) { - mutableStructFields.push_back(StructField{type, i}); + mutableStructFields.emplace_back(type, i); + } + if (!fields[i].isPacked()) { + auto fieldType = fields[i].type; + if (fieldType == Type::i32 || fieldType == Type::i64 || + Type::isSubType( + fieldType, Type(HeapTypes::eq.getBasic(Shared), Nullable))) { + structWaitFields.emplace_back(type, i); + } } } break; @@ -1901,6 +1909,16 @@ void TranslateToFuzzReader::addHangLimitChecks(Function* func) { AndInt32, arrayNew->size, builder.makeConst(int32_t(1024 - 1))); } } + if (!ATOMIC_WAITS) { + for (auto* wait : FindAll(func->body).list) { + if (auto* c = wait->timeout->dynCast()) { + c->value = Literal(int64_t(0)); + } else if (wait->timeout->type == Type::i64) { + wait->timeout = builder.makeSequence(builder.makeDrop(wait->timeout), + builder.makeConst(int64_t(0))); + } + } + } } void TranslateToFuzzReader::recombine(Function* func) { @@ -2881,6 +2899,13 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) { &Self::makeStringEq, &Self::makeStringMeasure, &Self::makeStringGet); + options.add(FeatureSet::ReferenceTypes | FeatureSet::SharedEverything, + &Self::makeWaitqueueNotify); + if (!structWaitFields.empty()) { + options.add(FeatureSet::ReferenceTypes | FeatureSet::GC | + FeatureSet::SharedEverything, + &Self::makeStructWait); + } } if (type == Type::i64) { options.add(FeatureSet::WideArithmetic | FeatureSet::Multivalue, @@ -4407,7 +4432,8 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { case HeapType::noext: case HeapType::nofunc: case HeapType::nocont: - case HeapType::noexn: { + case HeapType::noexn: + case HeapType::nowaitqueue: { auto null = builder.makeRefNull(heapType.getBasic(share)); if (!type.isNullable()) { return builder.makeRefAs(RefAsNonNull, null); @@ -4415,9 +4441,11 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { return null; } - case HeapType::waitqueue: - case HeapType::nowaitqueue: { - WASM_UNREACHABLE("waitqueue is unimplemented in the fuzzer"); + case HeapType::waitqueue: { + if (type.isNullable() && oneIn(2)) { + return builder.makeRefNull(HeapTypes::sharedWaitqueue.getBasic(share)); + } + return builder.makeWaitqueueNew(); } } WASM_UNREACHABLE("invalid basic ref type"); @@ -6060,8 +6088,8 @@ Expression* TranslateToFuzzReader::makeStructSet(Type type) { return makeTrivial(type); } auto [structType, fieldIndex] = pick(mutableStructFields); - auto fieldType = structType.getStruct().fields[fieldIndex].type; auto* ref = makeTrappingRefUse(structType); + auto fieldType = structType.getStruct().fields[fieldIndex].type; auto* value = make(fieldType); auto order = MemoryOrder::Unordered; if (wasm.features.hasAtomics() && wasm.features.hasSharedEverything() && @@ -6071,6 +6099,35 @@ Expression* TranslateToFuzzReader::makeStructSet(Type type) { return builder.makeStructSet(fieldIndex, ref, value, order); } +Expression* TranslateToFuzzReader::makeStructWait(Type type) { + assert(type == Type::i32); + assert(!structWaitFields.empty()); + auto [structType, fieldIndex] = pick(structWaitFields); + auto* ref = makeTrappingRefUse(structType); + auto* waitqueue = + makeTrappingRefUse(Type(HeapTypes::sharedWaitqueue, Nullable)); + auto expectedType = structType.getStruct().fields[fieldIndex].type; + if (expectedType.isRef()) { + expectedType = Type(HeapTypes::eq.getBasic(Shared), Nullable); + } + auto* expected = make(expectedType); + Expression* timeout = nullptr; + if (ATOMIC_WAITS && oneIn(2)) { + timeout = make(Type::i64); + } else { + timeout = builder.makeConst(int64_t{0}); + } + return builder.makeStructWait(fieldIndex, ref, waitqueue, expected, timeout); +} + +Expression* TranslateToFuzzReader::makeWaitqueueNotify(Type type) { + assert(type == Type::i32); + auto* waitqueue = + makeTrappingRefUse(Type(HeapTypes::sharedWaitqueue, Nullable)); + auto* count = make(Type::i32); + return builder.makeWaitqueueNotify(waitqueue, count); +} + // Make a bounds check for an array operation, given a ref + index. An optional // additional length parameter can be provided, which is added to the index if // so (that is useful for something like array.fill, which operations on not a @@ -6705,11 +6762,11 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) { case HeapType::nofunc: case HeapType::nocont: case HeapType::noexn: + case HeapType::nowaitqueue: break; case HeapType::waitqueue: - case HeapType::nowaitqueue: { - WASM_UNREACHABLE("waitqueue is unimplemented in the fuzzer"); - } + return pick(HeapTypes::sharedWaitqueue, HeapTypes::sharedNowaitqueue) + .getBasic(share); } } // Look for an interesting subtype. diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index ee9ce65df3c..3509b867e01 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -344,6 +344,9 @@ struct HeapTypeGeneratorImpl { if (features.hasStackSwitching() && share == Unshared) { bottoms.push_back(HeapType::nocont); } + if (features.hasSharedEverything() && share == Shared) { + bottoms.push_back(HeapType::nowaitqueue); + } return rand.pick(bottoms).getBasic(share); } @@ -366,6 +369,9 @@ struct HeapTypeGeneratorImpl { if (features.hasExceptionHandling() && share == Unshared) { options.push_back(HeapType::exn); } + if (features.hasSharedEverything() && share == Shared) { + options.push_back(HeapType::waitqueue); + } auto ht = rand.pick(options); return ht.getBasic(share); } @@ -691,11 +697,13 @@ struct HeapTypeGeneratorImpl { case HeapType::nofunc: case HeapType::nocont: case HeapType::noexn: + case HeapType::nowaitqueue: return type; case HeapType::waitqueue: - case HeapType::nowaitqueue: { - WASM_UNREACHABLE("waitqueue is unimplemented in the fuzzer"); - } + if (rand.oneIn(2)) { + return HeapTypes::sharedNowaitqueue.getBasic(share); + } + return type; } WASM_UNREACHABLE("unexpected type"); } @@ -743,6 +751,7 @@ struct HeapTypeGeneratorImpl { case HeapType::exn: case HeapType::cont: case HeapType::any: + case HeapType::waitqueue: break; case HeapType::eq: candidates.push_back(HeapTypes::any.getBasic(share)); @@ -768,10 +777,9 @@ struct HeapTypeGeneratorImpl { case HeapType::noexn: candidates.push_back(HeapTypes::exn.getBasic(share)); break; - case HeapType::waitqueue: - case HeapType::nowaitqueue: { - WASM_UNREACHABLE("waitqueue is unimplemented in the fuzzer"); - } + case HeapType::nowaitqueue: + candidates.push_back(HeapTypes::sharedWaitqueue.getBasic(share)); + break; } assert(!candidates.empty()); return rand.pick(candidates); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 56db519263a..e2fb73bebf2 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1524,6 +1524,9 @@ class Builder { return makeRefAs(ExternConvertAny, makeConstantExpression(value.internalize())); } + if (type.isRef() && type.getHeapType() == HeapTypes::sharedWaitqueue) { + return makeWaitqueueNew(); + } TODO_SINGLE_COMPOUND(type); WASM_UNREACHABLE("unsupported constant expression"); } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 03a445d33bd..9a1e9f048fc 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3739,8 +3739,11 @@ void FunctionValidator::visitStructWait(StructWait* curr) { return; } + auto expectedType = field.type.isRef() + ? Type(HeapTypes::eq.getBasic(Shared), Nullable) + : field.type; shouldBeSubType(curr->expected->type, - field.type, + expectedType, curr, "struct.wait expected value must match the field immediate"); } diff --git a/test/lit/fuzz-types.test b/test/lit/fuzz-types.test index ffcac612584..067606aa049 100644 --- a/test/lit/fuzz-types.test +++ b/test/lit/fuzz-types.test @@ -1,60 +1,60 @@ ;; RUN: wasm-fuzz-types -v --seed=3 | filecheck %s -;; CHECK: Running with seed 3 -;; CHECK-NEXT: Built 20 types: -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (shared (func (param i64 f64 exnref (ref null $0)) (result (ref cont)))))) -;; CHECK-NEXT: (type $1 (shared (descriptor $2) (struct))) -;; CHECK-NEXT: (type $2 (shared (describes $1) (descriptor $4) (struct (field (mut v128)) (field (mut (ref $4))) (field (mut v128)) (field (mut i32)) (field f32)))) -;; CHECK-NEXT: (type $3 (array i8)) -;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $5 (shared (descriptor $6) (struct (field f64) (field (ref $7)) (field (mut f64)) (field (mut (ref null (shared eq)))) (field (ref $11)) (field (ref (shared any)))))) -;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut i32)) (field (mut i16)) (field i64) (field f32) (field (ref null $11)) (field (mut f64))))) -;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field i8) (field (mut f32)) (field (mut f64)) (field (mut i32)) (field (mut f32)) (field (mut i64))))) -;; CHECK-NEXT: (type $8 (sub (struct))) -;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct (field (mut v128)) (field (mut v128)) (field (mut f32))))) -;; CHECK-NEXT: (type $10 (func (param f32 f64 f32))) -;; CHECK-NEXT: (type $11 (shared (describes $9) (struct (field (ref (shared struct))) (field i32) (field f32) (field (mut (ref null (shared struct)))) (field i64) (field i32)))) -;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field (mut i8)) (field f32) (field (mut v128))))) -;; CHECK-NEXT: (type $13 (sub (describes $12) (struct (field i32) (field (ref $10)) (field i8) (field (mut i64))))) -;; CHECK-NEXT: (type $14 (sub $8 (struct))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $15 (sub $8 (struct (field v128) (field (mut (ref null (shared struct))))))) -;; CHECK-NEXT: (type $16 (shared (func (param (ref null $10)) (result (ref $6) i32 f64)))) -;; CHECK-NEXT: (type $17 (sub final $12 (descriptor $18) (struct (field (mut i8)) (field f32) (field (mut v128)) (field (ref $17)) (field (mut i8)) (field (mut eqref))))) -;; CHECK-NEXT: (type $18 (sub final $13 (describes $17) (struct (field i32) (field (ref $10)) (field i8) (field (mut i64)) (field (mut (ref null $11))) (field f64)))) -;; CHECK-NEXT: (type $19 (sub $8 (struct (field (mut i8)) (field (mut v128)) (field v128) (field v128)))) -;; CHECK-NEXT: ) +;; CHECK: Running with seed 3 +;; CHECK-NEXT: Built 20 types: +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $0 (sub (shared (func (param i64 f64 exnref (ref null $0)) (result (ref cont)))))) +;; CHECK-NEXT: (type $1 (shared (descriptor $2) (struct))) +;; CHECK-NEXT: (type $2 (shared (describes $1) (descriptor $4) (struct (field (mut v128)) (field (mut (ref $4))) (field (mut v128)) (field (mut i32)) (field f32)))) +;; CHECK-NEXT: (type $3 (array i8)) +;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $5 (shared (descriptor $6) (struct (field f64) (field (ref $7)) (field (mut f64)) (field (mut (ref (shared i31)))) (field (mut (ref $11))) (field (ref (shared i31)))))) +;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut i32)) (field (mut (ref null $0))) (field (ref null (shared i31))) (field (mut v128)) (field (mut i64)) (field (mut (ref $2)))))) +;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field (ref null $6)) (field (mut (ref $0))) (field (ref $7)) (field i8) (field (mut i8)) (field (ref null $5))))) +;; CHECK-NEXT: (type $8 (sub (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64))))) +;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct (field (mut (ref $0))) (field (mut v128))))) +;; CHECK-NEXT: (type $10 (func (result (ref extern) (ref noextern) (ref $13) i32 exnref))) +;; CHECK-NEXT: (type $11 (shared (describes $9) (struct (field i16) (field (ref null $11))))) +;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field i64) (field (ref (shared extern))) (field (mut i16)) (field (mut (ref noextern)))))) +;; CHECK-NEXT: (type $13 (sub (describes $12) (struct (field (ref extern)) (field f64)))) +;; CHECK-NEXT: (type $14 (sub final $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field v128)))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $15 (sub $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field (mut i32))))) +;; CHECK-NEXT: (type $16 (shared (func (param (ref null $17)) (result exnref)))) +;; CHECK-NEXT: (type $17 (sub final $12 (descriptor $18) (struct (field i64) (field (ref (shared extern))) (field (mut i16)) (field (mut (ref noextern))) (field (mut (ref null $10)))))) +;; CHECK-NEXT: (type $18 (sub final $13 (describes $17) (struct (field (ref extern)) (field f64) (field (mut i16)) (field (mut i8))))) +;; CHECK-NEXT: (type $19 (sub $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field (mut (ref cont))) (field (mut i64))))) +;; CHECK-NEXT: ) ;; CHECK-EMPTY: -;; CHECK-NEXT: Inhabitable types: +;; CHECK-NEXT: Inhabitable types: ;; CHECK-EMPTY: -;; CHECK-NEXT: Built 20 types: -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (shared (func (param i64 f64 exnref (ref null $0)) (result (ref cont)))))) -;; CHECK-NEXT: (type $1 (shared (descriptor $2) (struct))) -;; CHECK-NEXT: (type $2 (shared (describes $1) (descriptor $4) (struct (field (mut v128)) (field (mut (ref $4))) (field (mut v128)) (field (mut i32)) (field f32)))) -;; CHECK-NEXT: (type $3 (array i8)) -;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $5 (shared (descriptor $6) (struct (field f64) (field (ref $7)) (field (mut f64)) (field (mut (ref null (shared eq)))) (field (ref $11)) (field (ref (shared any)))))) -;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut i32)) (field (mut i16)) (field i64) (field f32) (field (ref null $11)) (field (mut f64))))) -;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field i8) (field (mut f32)) (field (mut f64)) (field (mut i32)) (field (mut f32)) (field (mut i64))))) -;; CHECK-NEXT: (type $8 (sub (struct))) -;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct (field (mut v128)) (field (mut v128)) (field (mut f32))))) -;; CHECK-NEXT: (type $10 (func (param f32 f64 f32))) -;; CHECK-NEXT: (type $11 (shared (describes $9) (struct (field (ref (shared struct))) (field i32) (field f32) (field (mut (ref null (shared struct)))) (field i64) (field i32)))) -;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field (mut i8)) (field f32) (field (mut v128))))) -;; CHECK-NEXT: (type $13 (sub (describes $12) (struct (field i32) (field (ref $10)) (field i8) (field (mut i64))))) -;; CHECK-NEXT: (type $14 (sub $8 (struct))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $15 (sub $8 (struct (field v128) (field (mut (ref null (shared struct))))))) -;; CHECK-NEXT: (type $16 (shared (func (param (ref null $10)) (result (ref $6) i32 f64)))) -;; CHECK-NEXT: (type $17 (sub final $12 (descriptor $18) (struct (field (mut i8)) (field f32) (field (mut v128)) (field (ref null $17)) (field (mut i8)) (field (mut eqref))))) -;; CHECK-NEXT: (type $18 (sub final $13 (describes $17) (struct (field i32) (field (ref $10)) (field i8) (field (mut i64)) (field (mut (ref null $11))) (field f64)))) -;; CHECK-NEXT: (type $19 (sub $8 (struct (field (mut i8)) (field (mut v128)) (field v128) (field v128)))) -;; CHECK-NEXT: ) +;; CHECK-NEXT: Built 20 types: +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $0 (sub (shared (func (param i64 f64 exnref (ref null $0)) (result (ref cont)))))) +;; CHECK-NEXT: (type $1 (shared (descriptor $2) (struct))) +;; CHECK-NEXT: (type $2 (shared (describes $1) (descriptor $4) (struct (field (mut v128)) (field (mut (ref $4))) (field (mut v128)) (field (mut i32)) (field f32)))) +;; CHECK-NEXT: (type $3 (array i8)) +;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $5 (shared (descriptor $6) (struct (field f64) (field (ref $7)) (field (mut f64)) (field (mut (ref (shared i31)))) (field (mut (ref $11))) (field (ref (shared i31)))))) +;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut i32)) (field (mut (ref null $0))) (field (ref null (shared i31))) (field (mut v128)) (field (mut i64)) (field (mut (ref $2)))))) +;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field (ref null $6)) (field (mut (ref $0))) (field (ref null $7)) (field i8) (field (mut i8)) (field (ref null $5))))) +;; CHECK-NEXT: (type $8 (sub (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64))))) +;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct (field (mut (ref $0))) (field (mut v128))))) +;; CHECK-NEXT: (type $10 (func (result (ref extern) (ref noextern) (ref $13) i32 exnref))) +;; CHECK-NEXT: (type $11 (shared (describes $9) (struct (field i16) (field (ref null $11))))) +;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field i64) (field (ref null (shared extern))) (field (mut i16)) (field (mut nullexternref))))) +;; CHECK-NEXT: (type $13 (sub (describes $12) (struct (field externref) (field f64)))) +;; CHECK-NEXT: (type $14 (sub final $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field v128)))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $15 (sub $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field (mut i32))))) +;; CHECK-NEXT: (type $16 (shared (func (param (ref null $17)) (result exnref)))) +;; CHECK-NEXT: (type $17 (sub final $12 (descriptor $18) (struct (field i64) (field (ref null (shared extern))) (field (mut i16)) (field (mut nullexternref)) (field (mut (ref null $10)))))) +;; CHECK-NEXT: (type $18 (sub final $13 (describes $17) (struct (field externref) (field f64) (field (mut i16)) (field (mut i8))))) +;; CHECK-NEXT: (type $19 (sub $8 (struct (field (mut i16)) (field (mut (ref null $3))) (field (mut i64)) (field (mut (ref cont))) (field (mut i64))))) +;; CHECK-NEXT: ) diff --git a/test/lit/passes/type-refining-gufa-rmw.wast b/test/lit/passes/type-refining-gufa-rmw.wast index 16e990b47d8..a362f41d50a 100644 --- a/test/lit/passes/type-refining-gufa-rmw.wast +++ b/test/lit/passes/type-refining-gufa-rmw.wast @@ -466,12 +466,7 @@ ;; GUFA-NEXT: (struct.wait $struct 0 ;; GUFA-NEXT: (local.get $struct) ;; GUFA-NEXT: (unreachable) - ;; GUFA-NEXT: (block (result (ref null (shared none))) - ;; GUFA-NEXT: (drop - ;; GUFA-NEXT: (local.get $struct) - ;; GUFA-NEXT: ) - ;; GUFA-NEXT: (ref.null (shared none)) - ;; GUFA-NEXT: ) + ;; GUFA-NEXT: (local.get $struct) ;; GUFA-NEXT: (i64.const -1) ;; GUFA-NEXT: ) ;; GUFA-NEXT: ) 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 79bac424b20..28d68d4e379 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,92 +1,94 @@ Metrics total - [exports] : 41 - [funcs] : 114 - [globals] : 13 - [imports] : 12 + [exports] : 109 + [funcs] : 205 + [globals] : 22 + [imports] : 15 [memories] : 1 [memory-data] : 31 - [table-data] : 33 + [table-data] : 66 [tables] : 2 [tags] : 2 - [total] : 89280 - [vars] : 3822 - ArrayCmpxchg : 14 - ArrayCopy : 35 - ArrayFill : 24 - ArrayGet : 332 - ArrayLen : 485 - ArrayNew : 1170 - ArrayNewFixed : 259 - ArrayRMW : 19 - ArraySet : 67 - AtomicCmpxchg : 21 - AtomicFence : 55 - AtomicNotify : 20 - AtomicRMW : 31 - Binary : 3205 - Block : 5335 - BrOn : 206 - Break : 820 - Call : 831 - CallIndirect : 72 - CallRef : 221 - Const : 11991 - ContNew : 59 - DataDrop : 14 - Drop : 432 - GlobalGet : 4707 - GlobalSet : 1594 - I31Get : 42 - If : 2005 - Load : 260 - LocalGet : 10609 - LocalSet : 3430 - Loop : 678 - MemoryCopy : 13 - MemoryFill : 23 - MemoryInit : 13 - Nop : 549 - Pop : 251 - RefAs : 8721 - RefCast : 506 - RefEq : 209 - RefFunc : 1855 - RefGetDesc : 43 - RefI31 : 549 - RefIsNull : 65 - RefNull : 10369 - RefTest : 45 - Return : 334 - SIMDExtract : 123 + [total] : 111414 + [vars] : 4479 + ArrayCmpxchg : 15 + ArrayCopy : 47 + ArrayFill : 34 + ArrayGet : 481 + ArrayLen : 642 + ArrayNew : 2316 + ArrayNewFixed : 672 + ArrayRMW : 13 + ArraySet : 77 + AtomicCmpxchg : 49 + AtomicFence : 75 + AtomicNotify : 41 + AtomicRMW : 43 + Binary : 5029 + Block : 6507 + BrOn : 293 + Break : 1012 + Call : 866 + CallIndirect : 250 + CallRef : 259 + Const : 17289 + ContBind : 1 + ContNew : 193 + DataDrop : 9 + Drop : 580 + GlobalGet : 5513 + GlobalSet : 2079 + I31Get : 75 + If : 2566 + Load : 313 + LocalGet : 11499 + LocalSet : 3978 + Loop : 834 + MemoryCopy : 27 + MemoryFill : 18 + MemoryInit : 23 + Nop : 784 + RefAs : 9921 + RefCast : 703 + RefEq : 291 + RefFunc : 2029 + RefGetDesc : 79 + RefI31 : 796 + RefIsNull : 69 + RefNull : 11791 + RefTest : 59 + Return : 389 + SIMDExtract : 132 SIMDLoad : 2 - SIMDReplace : 1 - SIMDShuffle : 3 - SIMDTernary : 3 - Select : 251 - Store : 122 - StringConst : 316 - StringEncode : 51 - StringEq : 56 - StringMeasure : 51 - StringNew : 6 - StringSliceWTF : 2 + SIMDShift : 1 + SIMDShuffle : 1 + Select : 312 + Store : 142 + StringConcat : 3 + StringConst : 400 + StringEncode : 70 + StringEq : 69 + StringMeasure : 70 + StringNew : 10 + StringSliceWTF : 1 StringWTF16Get : 55 - StructCmpxchg : 33 - StructGet : 464 - StructNew : 11370 - StructRMW : 36 - StructSet : 70 + StructCmpxchg : 57 + StructGet : 442 + StructNew : 13734 + StructRMW : 54 + StructSet : 84 + StructWait : 78 Switch : 4 - TableGet : 3 - TableSet : 50 - Throw : 50 - ThrowRef : 7 - Try : 340 - TryTable : 365 - TupleExtract : 215 - TupleMake : 199 - Unary : 1587 - Unreachable : 826 - WideIntAddSub : 9 - WideIntMul : 22 + TableSet : 77 + Throw : 87 + ThrowRef : 5 + Try : 410 + TryTable : 477 + TupleExtract : 262 + TupleMake : 231 + Unary : 1996 + Unreachable : 1066 + WaitqueueNew : 373 + WaitqueueNotify: 51 + WideIntAddSub : 16 + WideIntMul : 13