From 0f46cadc4566552a1219b81ff873b2bc61a584bd Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 25 Mar 2025 19:08:52 -0700 Subject: [PATCH] Revert exact reference types We decided that Custom Descriptors should introduce exact heap types rather than exact reference types. Although these new features are very similar, the APIs we need to change for them are completely different. One option would have been to keep the existing exact reference type implementation while additionally implementing exact heap types, but there are not enough free bits in the type implementation to have both at once without increasing the alignment of HeapTypeInfo allocations. Portably increasing the alignment is annoying enough that it's easier to just eagerly remove exact reference types to free up the bit for use with exact heap types. Fully or partially revert the following PRs: - #7371 - #7365 - #7360 - #7357 - #7356 - #7355 - #7354 - #7353 - #7347 - #7342 - #7328 Keep the new `.with(...)` Type APIs and the relevant parts of the type relations gtest that were introduced as part of the reverted work. --- scripts/test/fuzzing.py | 8 - src/ir/manipulation.h | 5 +- src/ir/type-updating.cpp | 1 - src/ir/type-updating.h | 1 - src/literal.h | 2 +- src/parser/contexts.h | 18 +- src/parser/parsers.h | 73 +- src/passes/OptimizeInstructions.cpp | 30 +- src/passes/RemoveUnusedBrs.cpp | 4 +- src/tools/fuzzing.h | 6 - src/tools/fuzzing/fuzzing.cpp | 75 +- src/wasm-binary.h | 11 - src/wasm-builder.h | 10 +- src/wasm-type.h | 31 +- src/wasm/literal.cpp | 4 +- src/wasm/wasm-binary.cpp | 56 +- src/wasm/wasm-stack.cpp | 52 +- src/wasm/wasm-type.cpp | 110 +-- src/wasm/wasm-validator.cpp | 4 - src/wasm/wasm.cpp | 22 +- test/gtest/type-builder.cpp | 161 +---- test/lit/basic/exact-references.wast | 672 ------------------ test/lit/basic/reference-types.wast | 16 +- .../lit/ctor-eval/materialize-null-local.wast | 26 - test/lit/exec/exact.wast | 21 - test/lit/heap-types.wast | 4 +- test/lit/passes/cfp.wast | 4 +- test/lit/passes/coalesce-locals-exact.wast | 47 -- test/lit/passes/code-pushing-gc.wast | 4 +- test/lit/passes/dae-gc-refine-params.wast | 2 +- test/lit/passes/dae-gc.wast | 2 +- test/lit/passes/flatten_all-features.wast | 6 +- test/lit/passes/global-refining.wast | 18 +- test/lit/passes/gufa-refs.wast | 52 +- test/lit/passes/gufa-vs-cfp.wast | 4 +- test/lit/passes/heap2local-rmw.wast | 38 +- test/lit/passes/heap2local.wast | 178 ++--- test/lit/passes/local-subtyping-exact.wast | 39 - test/lit/passes/local-subtyping-nn.wast | 4 +- test/lit/passes/local-subtyping.wast | 2 +- test/lit/passes/merge-blocks.wast | 2 +- test/lit/passes/monomorphize-context.wast | 4 +- .../passes/optimize-instructions-exact.wast | 33 - .../passes/optimize-instructions-gc-tnh.wast | 4 +- test/lit/passes/optimize-instructions-gc.wast | 4 +- test/lit/passes/precompute-gc.wast | 2 +- test/lit/passes/remove-unused-brs-exact.wast | 40 -- test/lit/passes/remove-unused-brs-gc.wast | 22 +- .../lit/passes/remove-unused-types-exact.wast | 16 - test/lit/passes/signature-refining_gto.wat | 4 +- test/lit/passes/ssa.wast | 4 +- .../passes/type-refining-isorecursive.wast | 6 +- test/lit/passes/type-refining-rmw.wast | 4 +- test/lit/passes/type-refining.wast | 14 +- test/passes/precompute_all-features.txt | 2 +- 55 files changed, 337 insertions(+), 1647 deletions(-) delete mode 100644 test/lit/basic/exact-references.wast delete mode 100644 test/lit/ctor-eval/materialize-null-local.wast delete mode 100644 test/lit/exec/exact.wast delete mode 100644 test/lit/passes/coalesce-locals-exact.wast delete mode 100644 test/lit/passes/local-subtyping-exact.wast delete mode 100644 test/lit/passes/optimize-instructions-exact.wast delete mode 100644 test/lit/passes/remove-unused-brs-exact.wast delete mode 100644 test/lit/passes/remove-unused-types-exact.wast diff --git a/scripts/test/fuzzing.py b/scripts/test/fuzzing.py index ba36f41bcf5..75166fd7871 100644 --- a/scripts/test/fuzzing.py +++ b/scripts/test/fuzzing.py @@ -101,14 +101,6 @@ 'stack_switching_resume.wast', 'stack_switching_resume_throw.wast', 'stack_switching_switch.wast', - # TODO: fuzzer support for exact references - 'exact-references.wast', - 'optimize-instructions-exact.wast', - 'local-subtyping-exact.wast', - 'remove-unused-types-exact.wast', - 'coalesce-locals-exact.wast', - 'remove-unused-brs-exact.wast', - 'exact.wast', # TODO: fuzzer support for custom descriptors 'custom-descriptors.wast', ] diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h index c766fb8719e..e7816af9fce 100644 --- a/src/ir/manipulation.h +++ b/src/ir/manipulation.h @@ -40,9 +40,10 @@ template inline Nop* nop(InputType* target) { } template -inline RefNull* refNull(InputType* target, HeapType type) { +inline RefNull* refNull(InputType* target, Type type) { + assert(type.isNullable() && type.getHeapType().isBottom()); auto* ret = convert(target); - ret->finalize(Type(type.getBottom(), Nullable, Exact)); + ret->finalize(type); return ret; } diff --git a/src/ir/type-updating.cpp b/src/ir/type-updating.cpp index 65886bd2bd9..6dd91e0960e 100644 --- a/src/ir/type-updating.cpp +++ b/src/ir/type-updating.cpp @@ -342,7 +342,6 @@ Type GlobalTypeRewriter::getTempType(Type type) { if (type.isRef()) { auto heapType = type.getHeapType(); if (auto it = typeIndices.find(heapType); it != typeIndices.end()) { - // TODO: Handle exactness. return typeBuilder.getTempRefType(typeBuilder[it->second], type.getNullability()); } diff --git a/src/ir/type-updating.h b/src/ir/type-updating.h index e4e2c536992..fe1cd2806aa 100644 --- a/src/ir/type-updating.h +++ b/src/ir/type-updating.h @@ -497,7 +497,6 @@ class TypeMapper : public GlobalTypeRewriter { auto heapType = type.getHeapType(); auto iter = mapping.find(heapType); if (iter != mapping.end()) { - // TODO: Handle exactness. return getTempType(Type(iter->second, type.getNullability())); } return getTempType(type); diff --git a/src/literal.h b/src/literal.h index 4f9e3d535ad..c3cf2c15f70 100644 --- a/src/literal.h +++ b/src/literal.h @@ -246,7 +246,7 @@ class Literal { } } static Literal makeNull(HeapType type) { - return Literal(Type(type.getBottom(), Nullable, Exact)); + return Literal(Type(type.getBottom(), Nullable)); } static Literal makeFunc(Name func, HeapType type) { return Literal(func, type); diff --git a/src/parser/contexts.h b/src/parser/contexts.h index fa96c270670..4c56780323b 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -127,9 +127,7 @@ struct NullTypeParserCtx { TypeT makeF64() { return Ok{}; } TypeT makeV128() { return Ok{}; } - TypeT makeRefType(HeapTypeT, Nullability, Exactness) { return Ok{}; } - - HeapTypeT getHeapTypeFromRefType(TypeT) { return Ok{}; } + TypeT makeRefType(HeapTypeT, Nullability) { return Ok{}; } TupleElemListT makeTupleElemList() { return Ok{}; } void appendTupleElem(TupleElemListT&, TypeT) {} @@ -259,13 +257,10 @@ template struct TypeParserCtx { TypeT makeF64() { return Type::f64; } TypeT makeV128() { return Type::v128; } - TypeT - makeRefType(HeapTypeT ht, Nullability nullability, Exactness exactness) { - return Type(ht, nullability, exactness); + TypeT makeRefType(HeapTypeT ht, Nullability nullability) { + return Type(ht, nullability); } - HeapTypeT getHeapTypeFromRefType(TypeT t) { return t.getHeapType(); } - std::vector makeTupleElemList() { return {}; } void appendTupleElem(std::vector& elems, Type elem) { elems.push_back(elem); @@ -1122,13 +1117,10 @@ struct ParseTypeDefsCtx : TypeParserCtx { : TypeParserCtx(typeIndices), in(in), builder(builder), names(builder.size()) {} - TypeT - makeRefType(HeapTypeT ht, Nullability nullability, Exactness exactness) { - return builder.getTempRefType(ht, nullability, exactness); + TypeT makeRefType(HeapTypeT ht, Nullability nullability) { + return builder.getTempRefType(ht, nullability); } - HeapTypeT getHeapTypeFromRefType(TypeT t) { return t.getHeapType(); } - TypeT makeTupleType(const std::vector types) { return builder.getTempTupleType(types); } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 26c20767938..33e9d20fdc9 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -30,8 +30,6 @@ using namespace std::string_view_literals; template Result absheaptype(Ctx&, Shareability); template Result heaptype(Ctx&); -template -MaybeResult maybeReftypeAbbrev(Ctx&); template MaybeResult maybeReftype(Ctx&); template Result reftype(Ctx&); template MaybeResult tupletype(Ctx&); @@ -460,85 +458,68 @@ template Result heaptype(Ctx& ctx) { // | 'i31ref' => i31ref // | 'structref' => structref // | 'arrayref' => arrayref -// | ... -template -MaybeResult maybeReftypeAbbrev(Ctx& ctx) { +// | '(' ref null? t:heaptype ')' => ref null? t +template MaybeResult maybeReftype(Ctx& ctx) { if (ctx.in.takeKeyword("funcref"sv)) { - return ctx.makeRefType(ctx.makeFuncType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeFuncType(Unshared), Nullable); } if (ctx.in.takeKeyword("externref"sv)) { - return ctx.makeRefType(ctx.makeExternType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeExternType(Unshared), Nullable); } if (ctx.in.takeKeyword("anyref"sv)) { - return ctx.makeRefType(ctx.makeAnyType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeAnyType(Unshared), Nullable); } if (ctx.in.takeKeyword("eqref"sv)) { - return ctx.makeRefType(ctx.makeEqType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeEqType(Unshared), Nullable); } if (ctx.in.takeKeyword("i31ref"sv)) { - return ctx.makeRefType(ctx.makeI31Type(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeI31Type(Unshared), Nullable); } if (ctx.in.takeKeyword("structref"sv)) { - return ctx.makeRefType(ctx.makeStructType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeStructType(Unshared), Nullable); } if (ctx.in.takeKeyword("arrayref"sv)) { - return ctx.makeRefType(ctx.makeArrayType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeArrayType(Unshared), Nullable); } if (ctx.in.takeKeyword("exnref"sv)) { - return ctx.makeRefType(ctx.makeExnType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeExnType(Unshared), Nullable); } if (ctx.in.takeKeyword("stringref"sv)) { - return ctx.makeRefType(ctx.makeStringType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeStringType(Unshared), Nullable); } if (ctx.in.takeKeyword("contref"sv)) { - return ctx.makeRefType(ctx.makeContType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeContType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullref"sv)) { - return ctx.makeRefType(ctx.makeNoneType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeNoneType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullexternref"sv)) { - return ctx.makeRefType(ctx.makeNoextType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeNoextType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullfuncref"sv)) { - return ctx.makeRefType(ctx.makeNofuncType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeNofuncType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullexnref"sv)) { - return ctx.makeRefType(ctx.makeNoexnType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeNoexnType(Unshared), Nullable); } if (ctx.in.takeKeyword("nullcontref"sv)) { - return ctx.makeRefType(ctx.makeNocontType(Unshared), Nullable, Inexact); + return ctx.makeRefType(ctx.makeNocontType(Unshared), Nullable); } - return {}; -} -// reftype ::= ... -// | '(' 'exact' (ref null ht):shorthand ')' => ref null exact ht -// | '(' ref null? exact? ht:heaptype ')' => ref null? t -template MaybeResult maybeReftype(Ctx& ctx) { - if (ctx.in.takeSExprStart("exact"sv)) { - auto rt = maybeReftypeAbbrev(ctx); - CHECK_ERR(rt); - if (!rt) { - return ctx.in.err("expected reftype shorthand"); - } - if (!ctx.in.takeRParen()) { - return ctx.in.err("expected end of reftype"); - } - return ctx.makeRefType(ctx.getHeapTypeFromRefType(*rt), Nullable, Exact); + if (!ctx.in.takeSExprStart("ref"sv)) { + return {}; } - if (ctx.in.takeSExprStart("ref"sv)) { - auto nullability = ctx.in.takeKeyword("null"sv) ? Nullable : NonNullable; - auto exactness = ctx.in.takeKeyword("exact"sv) ? Exact : Inexact; - auto type = heaptype(ctx); - CHECK_ERR(type); - if (!ctx.in.takeRParen()) { - return ctx.in.err("expected end of reftype"); - } - return ctx.makeRefType(*type, nullability, exactness); + auto nullability = ctx.in.takeKeyword("null"sv) ? Nullable : NonNullable; + + auto type = heaptype(ctx); + CHECK_ERR(type); + + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected end of reftype"); } - return maybeReftypeAbbrev(ctx); + return ctx.makeRefType(*type, nullability); } template Result reftype(Ctx& ctx) { diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 916a493bca6..c8c192685a2 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -2277,14 +2277,10 @@ struct OptimizeInstructions // emit a null check. bool needsNullCheck = ref->type.getNullability() == Nullable && curr->type.getNullability() == NonNullable; - // Same with exactness. - bool needsExactCast = ref->type.getExactness() == Inexact && - curr->type.getExactness() == Exact; // If the best value to propagate is the argument to the cast, we can // simply remove the cast (or downgrade it to a null check if - // necessary). This does not work if we need a cast to prove - // exactness. - if (ref == curr->ref && !needsExactCast) { + // necessary). + if (ref == curr->ref) { if (needsNullCheck) { replaceCurrent(builder.makeRefAs(RefAsNonNull, curr->ref)); } else { @@ -2293,9 +2289,9 @@ struct OptimizeInstructions return; } // Otherwise we can't just remove the cast and replace it with `ref` - // because the intermediate expressions might have had side effects or - // we need to check exactness. We can replace the cast with a drop - // followed by a direct return of the value, though. + // because the intermediate expressions might have had side effects. + // We can replace the cast with a drop followed by a direct return of + // the value, though. if (ref->type.isNull()) { // We can materialize the resulting null value directly. // @@ -2303,7 +2299,7 @@ struct OptimizeInstructions // would be, aside from the interesting corner case of // uninhabitable types: // - // (ref.cast (ref func) + // (ref.cast func // (block (result (ref nofunc)) // (unreachable) // ) @@ -2350,20 +2346,18 @@ struct OptimizeInstructions } [[fallthrough]]; case GCTypeUtils::SuccessOnlyIfNull: { + auto nullType = Type(curr->type.getHeapType().getBottom(), Nullable); // The cast either returns null or traps. In trapsNeverHappen mode // we know the result, since by assumption it will not trap. if (getPassOptions().trapsNeverHappen) { - replaceCurrent( - builder.makeBlock({builder.makeDrop(curr->ref), - builder.makeRefNull(curr->type.getHeapType())}, - curr->type)); + replaceCurrent(builder.makeBlock( + {builder.makeDrop(curr->ref), builder.makeRefNull(nullType)}, + curr->type)); return; } // Otherwise, we should have already refined the cast type to cast - // directly to null. We do not further refine the cast type to exact - // null because the extra precision is not useful and doing so would - // increase the size of the instruction encoding. - assert(curr->type.isNull()); + // directly to null. + assert(curr->type == nullType); break; } case GCTypeUtils::Unreachable: diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 72dea0405e1..47a1f1c6553 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -859,8 +859,8 @@ struct RemoveUnusedBrs : public WalkerPass> { if (Type::isSubType(expr->type, type)) { return expr; } - if (type.isNonNullable() && expr->type.isNullable() && - Type::isSubType(expr->type.with(NonNullable), type)) { + if (HeapType::isSubType(expr->type.getHeapType(), + type.getHeapType())) { return builder.makeRefAs(RefAsNonNull, expr); } return builder.makeRefCast(expr, type); diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index bb43fa39fa2..383e5af70c1 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -360,10 +360,6 @@ class TranslateToFuzzReader { // instruction for EH is supposed to exist only at the beginning of a 'catch' // block, so it shouldn't be moved around or deleted freely. bool canBeArbitrarilyReplaced(Expression* curr) { - // TODO: Remove this once we better support exact references. - if (curr->type.isExact()) { - return false; - } return curr->type.isDefaultable() && !EHUtils::containsValidDanglingPop(curr); } @@ -525,9 +521,7 @@ class TranslateToFuzzReader { Type getLoggableType(); bool isLoggableType(Type type); Nullability getNullability(); - Exactness getExactness(); Nullability getSubType(Nullability nullability); - Exactness getSubType(Exactness exactness); HeapType getSubType(HeapType type); Type getSubType(Type type); Nullability getSuperType(Nullability nullability); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index c72b239bda2..2b958590384 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -1566,22 +1566,20 @@ void TranslateToFuzzReader::recombine(Function* func) { } std::vector ret; - ret.push_back(type); + auto heapType = type.getHeapType(); + auto nullability = type.getNullability(); - if (type.isNonNullable()) { - auto nullable = getRelevantTypes(type.with(Nullable)); - ret.insert(ret.end(), nullable.begin(), nullable.end()); - } - if (type.isExact()) { - auto inexact = getRelevantTypes(type.with(Inexact)); - ret.insert(ret.end(), inexact.begin(), inexact.end()); - // Do not consider exact references to supertypes. - return ret; + if (nullability == NonNullable) { + ret = getRelevantTypes(Type(heapType, Nullable)); } - for (auto heapType = type.getHeapType().getSuperType(); heapType; - heapType = heapType->getSuperType()) { - ret.push_back(type.with(*heapType)); + while (1) { + ret.push_back(Type(heapType, nullability)); + auto super = heapType.getSuperType(); + if (!super) { + break; + } + heapType = *super; } return ret; @@ -4904,17 +4902,9 @@ static auto makeArrayBoundsCheck(Expression* ref, Function* func, Builder& builder, Expression* length = nullptr) { - // The reference might be a RefNull, in which case its type is exact. But we - // want to avoid creating exact-typed locals until we support them more widely - // in the fuzzer, so adjust the type. TODO: remove this once exact references - // are better supported. - Type refType = ref->type; - if (refType.isExact()) { - refType = refType.with(Inexact); - } - auto tempRef = builder.addVar(func, refType); + auto tempRef = builder.addVar(func, ref->type); auto tempIndex = builder.addVar(func, index->type); - auto* teeRef = builder.makeLocalTee(tempRef, ref, refType); + auto* teeRef = builder.makeLocalTee(tempRef, ref, ref->type); auto* teeIndex = builder.makeLocalTee(tempIndex, index, index->type); auto* getSize = builder.makeArrayLen(teeRef); @@ -4941,7 +4931,7 @@ static auto makeArrayBoundsCheck(Expression* ref, // An additional use of the length, if it was provided. Expression* getLength = nullptr; } result = {builder.makeBinary(LtUInt32, effectiveIndex, getSize), - builder.makeLocalGet(tempRef, refType), + builder.makeLocalGet(tempRef, ref->type), builder.makeLocalGet(tempIndex, index->type), getLength}; return result; @@ -5330,23 +5320,6 @@ Nullability TranslateToFuzzReader::getNullability() { return Nullable; } -Exactness TranslateToFuzzReader::getExactness() { - // Without GC, the only heap types are func and extern, neither of which is - // exactly inhabitable. To avoid introducing uninhabitable types, only - // generate exact references when GC is enabled. We don't need custom - // descriptors to be enabled even though that is the feature that introduces - // exact references because the binary writer can always generalize the exact - // reference types away. - // - // if (wasm.features.hasGC() && oneIn(8)) { - // return Exact; - // } - // - // However, we cannot yet handle creating exact references in general, so for - // now we always generate inexact references when given the choice. TODO. - return Inexact; -} - Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { if (nullability == NonNullable) { return NonNullable; @@ -5354,13 +5327,6 @@ Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { return getNullability(); } -Exactness TranslateToFuzzReader::getSubType(Exactness exactness) { - if (exactness == Exact) { - return Exact; - } - return getExactness(); -} - HeapType TranslateToFuzzReader::getSubType(HeapType type) { if (oneIn(3)) { return type; @@ -5453,18 +5419,9 @@ Type TranslateToFuzzReader::getSubType(Type type) { if (!funcContext && heapType.isMaybeShared(HeapType::exn)) { return type; } - if (type.isExact()) { - // The only other possible heap type is bottom, but we don't want to - // generate too many bottom types. - if (!heapType.isBottom() && oneIn(20)) { - heapType = heapType.getBottom(); - } - } else { - heapType = getSubType(heapType); - } + heapType = getSubType(heapType); auto nullability = getSubType(type.getNullability()); - auto exactness = getSubType(type.getExactness()); - auto subType = Type(heapType, nullability, exactness); + auto subType = Type(heapType, nullability); // We don't want to emit lots of uninhabitable types like (ref none), so // avoid them with high probability. Specifically, if the original type was // inhabitable then return that; avoid adding more uninhabitability. diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9d99e20ce75..c20e8e5ab0e 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -304,13 +304,6 @@ enum SegmentFlag { UsesExpressions = 1 << 2 }; -enum BrOnCastFlag { - InputNullable = 1 << 0, - OutputNullable = 1 << 1, - InputExact = 1 << 2, - OutputExact = 1 << 3, -}; - enum EncodedType { // value types i32 = -0x1, // 0x7f @@ -334,7 +327,6 @@ enum EncodedType { eqref = -0x13, // 0x6d nonnullable = -0x1c, // 0x64 nullable = -0x1d, // 0x63 - exact = -0x1e, // 0x62 contref = -0x18, // 0x68 nullcontref = -0x0b, // 0x75 // exception handling @@ -1135,8 +1127,6 @@ enum ASTNodes { I31GetS = 0x1d, I31GetU = 0x1e, RefI31Shared = 0x1f, - RefTestRT = 0x20, - RefCastRT = 0x21, // Shared GC Opcodes @@ -1509,7 +1499,6 @@ class WasmBinaryReader { Type getType(); // Get a type given the initial S32LEB has already been read, and is provided. Type getType(int code); - Type getTypeNoExact(int code); HeapType getHeapType(); HeapType getIndexedHeapType(); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 13c124783a6..8344355b64a 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -670,11 +670,11 @@ class Builder { } RefNull* makeRefNull(HeapType type) { auto* ret = wasm.allocator.alloc(); - ret->finalize(Type(type.getBottom(), Nullable, Exact)); + ret->finalize(Type(type.getBottom(), Nullable)); return ret; } RefNull* makeRefNull(Type type) { - assert(type.isNullable() && type.isNull() && type.isExact()); + assert(type.isNullable() && type.isNull()); auto* ret = wasm.allocator.alloc(); ret->finalize(type); return ret; @@ -1270,7 +1270,7 @@ class Builder { return makeConst(value); } if (value.isNull()) { - return makeRefNull(type.getHeapType()); + return makeRefNull(type); } if (type.isFunction()) { return makeRefFunc(value.getFunc(), type.getHeapType()); @@ -1435,8 +1435,8 @@ class Builder { return maybeWrap(makeConstantExpression(Literal::makeZeros(curr->type))); } if (curr->type.isNullable()) { - return maybeWrap( - ExpressionManipulator::refNull(curr, curr->type.getHeapType())); + return maybeWrap(ExpressionManipulator::refNull( + curr, Type(curr->type.getHeapType().getBottom(), Nullable))); } if (curr->type.isRef() && curr->type.getHeapType().isMaybeShared(HeapType::i31)) { diff --git a/src/wasm-type.h b/src/wasm-type.h index b250e38c9c8..6b337530a24 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -62,7 +62,6 @@ using Tuple = TypeList; enum Nullability { NonNullable, Nullable }; enum Mutability { Immutable, Mutable }; -enum Exactness { Inexact, Exact }; // HeapType name information used for printing. struct TypeNames { @@ -319,10 +318,10 @@ class Type { // Construct from a heap type description. Also covers construction from // Signature, Struct or Array via implicit conversion to HeapType. - Type(HeapType heapType, Nullability nullable, Exactness exact = Inexact) - : Type(heapType.getID() | (nullable == Nullable ? NullMask : 0) | - (exact == Exact ? ExactMask : 0)) { - assert(!(heapType.getID() & (TupleMask | NullMask | ExactMask))); + Type(HeapType heapType, Nullability nullable) + : Type(heapType.getID() | (nullable == Nullable ? NullMask : 0)) { + assert(heapType.isBasic() || + !(heapType.getID() & (TupleMask | NullMask | ExactMask))); } // Predicates @@ -371,8 +370,6 @@ class Type { bool isRef() const { return !isBasic() && !(id & TupleMask); } bool isNullable() const { return isRef() && (id & NullMask); } bool isNonNullable() const { return isRef() && !(id & NullMask); } - bool isExact() const { return isRef() && (id & ExactMask); } - bool isInexact() const { return isRef() && !(id & ExactMask); } HeapType getHeapType() const { assert(isRef()); return HeapType(id & ~(NullMask | ExactMask)); @@ -397,20 +394,11 @@ class Type { Nullability getNullability() const { return isNullable() ? Nullable : NonNullable; } - Exactness getExactness() const { - assert(isRef()); - return isExact() ? Exact : Inexact; - } // Return a new reference type with some part updated to the specified value. - Type with(HeapType heapType) { - return Type(heapType, getNullability(), getExactness()); - } + Type with(HeapType heapType) { return Type(heapType, getNullability()); } Type with(Nullability nullability) { - return Type(getHeapType(), nullability, getExactness()); - } - Type with(Exactness exactness) { - return Type(getHeapType(), getNullability(), exactness); + return Type(getHeapType(), nullability); } private: @@ -730,8 +718,7 @@ struct TypeBuilder { return t; } assert(t.isRef()); - return getTempRefType( - map(t.getHeapType()), t.getNullability(), t.getExactness()); + return getTempRefType(map(t.getHeapType()), t.getNullability()); }; auto copyType = [&](Type t) -> Type { if (t.isTuple()) { @@ -784,9 +771,7 @@ struct TypeBuilder { // TypeBuilder's HeapTypes. For Ref types, the HeapType may be a temporary // HeapType owned by this builder or a canonical HeapType. Type getTempTupleType(const Tuple&); - Type getTempRefType(HeapType heapType, - Nullability nullable, - Exactness exact = Inexact); + Type getTempRefType(HeapType heapType, Nullability nullable); // Declare the HeapType being built at index `i` to be an immediate subtype of // the given HeapType. diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index de95fe565bf..9e015501a0a 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -72,9 +72,7 @@ Literal::Literal(const uint8_t init[16]) : type(Type::v128) { } Literal::Literal(std::shared_ptr gcData, HeapType type) - : gcData(gcData), - type(type, gcData ? NonNullable : Nullable, gcData ? Inexact : Exact) { - // TODO: Use exact types for more than just nulls. + : gcData(gcData), type(type, gcData ? NonNullable : Nullable) { // The type must be a proper type for GC data: either a struct, array, or // string; or an externalized version of the same; or a null; or an // internalized string (which appears as an anyref). diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index c3b6d310d12..c18416a727f 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1559,12 +1559,6 @@ void WasmBinaryWriter::writeInlineBuffer(const char* data, size_t size) { void WasmBinaryWriter::writeType(Type type) { if (type.isRef()) { - // Exact references are introduced by the custom descriptors feature, but - // can be used internally even when it is not enabled. In that case, we have - // to generalize the types to be inexact before writing them. - if (!wasm->features.hasCustomDescriptors()) { - type = Type(type.getHeapType(), type.getNullability(), Inexact); - } // The only reference types allowed without GC are funcref, externref, and // exnref. We internally use more refined versions of those types, but we // cannot emit those without GC. @@ -1581,12 +1575,6 @@ void WasmBinaryWriter::writeType(Type type) { type = Type(type.getHeapType().getTop(), Nullable); } } - // If the type is exact, emit the exact prefix and continue on without - // considering exactness. - if (type.isExact()) { - o << S32LEB(BinaryConsts::EncodedType::exact); - type = Type(type.getHeapType(), type.getNullability(), Inexact); - } auto heapType = type.getHeapType(); if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) { switch (heapType.getBasic(Unshared)) { @@ -2175,7 +2163,7 @@ Signature WasmBinaryReader::getBlockType() { return Signature(Type::none, getType(code)); } -Type WasmBinaryReader::getTypeNoExact(int code) { +Type WasmBinaryReader::getType(int code) { Type type; if (getBasicType(code, type)) { return type; @@ -2191,17 +2179,6 @@ Type WasmBinaryReader::getTypeNoExact(int code) { WASM_UNREACHABLE("unexpected type"); } -Type WasmBinaryReader::getType(int code) { - if (code == BinaryConsts::EncodedType::exact) { - auto type = getTypeNoExact(getS32LEB()); - if (!type.isRef()) { - throwError("invalid exact prefix on non-reference type"); - } - return Type(type.getHeapType(), type.getNullability(), Exact); - } - return getTypeNoExact(code); -} - Type WasmBinaryReader::getType() { return getType(getS32LEB()); } HeapType WasmBinaryReader::getHeapType() { @@ -2362,7 +2339,7 @@ void WasmBinaryReader::readTypes() { } return builder.getTempHeapType(size_t(htCode)); }; - auto makeTypeNoExact = [&](int32_t typeCode) { + auto makeType = [&](int32_t typeCode) { Type type; if (getBasicType(typeCode, type)) { return type; @@ -2387,17 +2364,6 @@ void WasmBinaryReader::readTypes() { } WASM_UNREACHABLE("unexpected type"); }; - auto makeType = [&](int32_t typeCode) { - if (typeCode == BinaryConsts::EncodedType::exact) { - auto type = makeTypeNoExact(getS32LEB()); - if (!type.isRef()) { - throwError("unexpected exact prefix on non-reference type"); - } - return builder.getTempRefType( - type.getHeapType(), type.getNullability(), Exact); - } - return makeTypeNoExact(typeCode); - }; auto readType = [&]() { return makeType(getS32LEB()); }; auto readSignatureDef = [&]() { @@ -4271,30 +4237,16 @@ Result<> WasmBinaryReader::readInst() { return builder.makeRefTest(Type(getHeapType(), NonNullable)); case BinaryConsts::RefTestNull: return builder.makeRefTest(Type(getHeapType(), Nullable)); - case BinaryConsts::RefTestRT: - return builder.makeRefTest(getType()); case BinaryConsts::RefCast: return builder.makeRefCast(Type(getHeapType(), NonNullable)); case BinaryConsts::RefCastNull: return builder.makeRefCast(Type(getHeapType(), Nullable)); - case BinaryConsts::RefCastRT: - return builder.makeRefCast(getType()); case BinaryConsts::BrOnCast: case BinaryConsts::BrOnCastFail: { auto flags = getInt8(); auto label = getU32LEB(); - auto srcNull = (flags & BinaryConsts::BrOnCastFlag::InputNullable) - ? Nullable - : NonNullable; - auto dstNull = (flags & BinaryConsts::BrOnCastFlag::OutputNullable) - ? Nullable - : NonNullable; - auto srcExact = - (flags & BinaryConsts::BrOnCastFlag::InputExact) ? Exact : Inexact; - auto dstExact = - (flags & BinaryConsts::BrOnCastFlag::OutputExact) ? Exact : Inexact; - auto in = Type(getHeapType(), srcNull, srcExact); - auto cast = Type(getHeapType(), dstNull, dstExact); + auto in = Type(getHeapType(), (flags & 1) ? Nullable : NonNullable); + auto cast = Type(getHeapType(), (flags & 2) ? Nullable : NonNullable); auto kind = op == BinaryConsts::BrOnCast ? BrOnCast : BrOnCastFail; return builder.makeBrOn(label, kind, in, cast); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 506b11a085e..060b01b04ee 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2260,38 +2260,22 @@ void BinaryInstWriter::visitCallRef(CallRef* curr) { void BinaryInstWriter::visitRefTest(RefTest* curr) { o << int8_t(BinaryConsts::GCPrefix); - if (curr->castType.isExact() && - parent.getModule()->features.hasCustomDescriptors()) { - // Fall back to the general form with a reftype immediate. - o << U32LEB(BinaryConsts::RefTestRT); - parent.writeType(curr->castType); + if (curr->castType.isNullable()) { + o << U32LEB(BinaryConsts::RefTestNull); } else { - // Use the special-case form with heap type immediate. - if (curr->castType.isNullable()) { - o << U32LEB(BinaryConsts::RefTestNull); - } else { - o << U32LEB(BinaryConsts::RefTest); - } - parent.writeHeapType(curr->castType.getHeapType()); + o << U32LEB(BinaryConsts::RefTest); } + parent.writeHeapType(curr->castType.getHeapType()); } void BinaryInstWriter::visitRefCast(RefCast* curr) { o << int8_t(BinaryConsts::GCPrefix); - if (curr->type.isExact() && - parent.getModule()->features.hasCustomDescriptors()) { - // Fall back to the general form with a reftype immediate. - o << U32LEB(BinaryConsts::RefCastRT); - parent.writeType(curr->type); + if (curr->type.isNullable()) { + o << U32LEB(BinaryConsts::RefCastNull); } else { - // Use the special-case form with heap type immediate. - if (curr->type.isNullable()) { - o << U32LEB(BinaryConsts::RefCastNull); - } else { - o << U32LEB(BinaryConsts::RefCast); - } - parent.writeHeapType(curr->type.getHeapType()); + o << U32LEB(BinaryConsts::RefCast); } + parent.writeHeapType(curr->type.getHeapType()); } void BinaryInstWriter::visitBrOn(BrOn* curr) { @@ -2314,24 +2298,8 @@ void BinaryInstWriter::visitBrOn(BrOn* curr) { } assert(curr->ref->type.isRef()); assert(Type::isSubType(curr->castType, curr->ref->type)); - uint8_t flags = 0; - if (curr->ref->type.isNullable()) { - flags |= BinaryConsts::BrOnCastFlag::InputNullable; - } - if (curr->castType.isNullable()) { - flags |= BinaryConsts::BrOnCastFlag::OutputNullable; - } - if (parent.getModule()->features.hasCustomDescriptors()) { - // If custom descriptors (and therefore exact references) are not - // enabled, then these flags wouldn't be recognized, and we will be - // generalizing all exact references to be non-exact anyway. - if (curr->ref->type.isExact()) { - flags |= BinaryConsts::BrOnCastFlag::InputExact; - } - if (curr->castType.isExact()) { - flags |= BinaryConsts::BrOnCastFlag::OutputExact; - } - } + uint8_t flags = (curr->ref->type.isNullable() ? 1 : 0) | + (curr->castType.isNullable() ? 2 : 0); o << flags; o << U32LEB(getBreakIndex(curr->name)); parent.writeHeapType(curr->ref->type.getHeapType()); diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index ada53eb150b..5cdb76c19dd 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -790,19 +790,11 @@ Type Type::getLeastUpperBound(Type a, Type b) { return Type(elems); } if (a.isRef() && b.isRef()) { - auto heapTypeA = a.getHeapType(); - auto heapTypeB = b.getHeapType(); - if (auto heapType = HeapType::getLeastUpperBound(heapTypeA, heapTypeB)) { + if (auto heapType = + HeapType::getLeastUpperBound(a.getHeapType(), b.getHeapType())) { auto nullability = (a.isNullable() || b.isNullable()) ? Nullable : NonNullable; - auto exactness = (a.isInexact() || b.isInexact()) ? Inexact : Exact; - // The LUB can only be exact if the heap types are the same or one of them - // is bottom. - if (heapTypeA != heapTypeB && !heapTypeA.isBottom() && - !heapTypeB.isBottom()) { - exactness = Inexact; - } - return Type(*heapType, nullability, exactness); + return Type(*heapType, nullability); } } return Type::none; @@ -836,7 +828,6 @@ Type Type::getGreatestLowerBound(Type a, Type b) { } auto nullability = (a.isNonNullable() || b.isNonNullable()) ? NonNullable : Nullable; - auto exactness = (a.isExact() || b.isExact()) ? Exact : Inexact; HeapType heapType; if (HeapType::isSubType(heapA, heapB)) { heapType = heapA; @@ -845,13 +836,7 @@ Type Type::getGreatestLowerBound(Type a, Type b) { } else { heapType = heapA.getBottom(); } - // If one of the types is exact, but the GLB heap type is different than its - // heap type, then we must make the GLB heap type bottom. - if ((a.isExact() && heapType != heapA) || - (b.isExact() && heapType != heapB)) { - heapType = heapA.getBottom(); - } - return Type(heapType, nullability, exactness); + return Type(heapType, nullability); } const Type& Type::Iterator::operator*() const { @@ -1506,24 +1491,14 @@ bool SubTyper::isSubType(Type a, Type b) { if (a == Type::unreachable) { return true; } + if (a.isRef() && b.isRef()) { + return (a.isNullable() == b.isNullable() || !a.isNullable()) && + isSubType(a.getHeapType(), b.getHeapType()); + } if (a.isTuple() && b.isTuple()) { return isSubType(a.getTuple(), b.getTuple()); } - if (!a.isRef() || !b.isRef()) { - return false; - } - if (a.isNullable() && !b.isNullable()) { - return false; - } - if (a.isInexact() && !b.isInexact()) { - return false; - } - auto heapTypeA = a.getHeapType(); - auto heapTypeB = b.getHeapType(); - if (b.isExact() && !heapTypeA.isBottom()) { - return heapTypeA == heapTypeB; - } - return isSubType(heapTypeA, heapTypeB); + return false; } bool SubTyper::isSubType(HeapType a, HeapType b) { @@ -1671,69 +1646,44 @@ std::ostream& TypePrinter::print(Type type) { } else if (type.isRef()) { auto heapType = type.getHeapType(); if (type.isNullable() && heapType.isBasic() && !heapType.isShared()) { - if (type.isExact()) { - os << "(exact "; - } // Print shorthands for certain basic heap types. switch (heapType.getBasic(Unshared)) { case HeapType::ext: - os << "externref"; - break; + return os << "externref"; case HeapType::func: - os << "funcref"; - break; + return os << "funcref"; case HeapType::cont: - os << "contref"; - break; + return os << "contref"; case HeapType::any: - os << "anyref"; - break; + return os << "anyref"; case HeapType::eq: - os << "eqref"; - break; + return os << "eqref"; case HeapType::i31: - os << "i31ref"; - break; + return os << "i31ref"; case HeapType::struct_: - os << "structref"; - break; + return os << "structref"; case HeapType::array: - os << "arrayref"; - break; + return os << "arrayref"; case HeapType::exn: - os << "exnref"; - break; + return os << "exnref"; case HeapType::string: - os << "stringref"; - break; + return os << "stringref"; case HeapType::none: - os << "nullref"; - break; + return os << "nullref"; case HeapType::noext: - os << "nullexternref"; - break; + return os << "nullexternref"; case HeapType::nofunc: - os << "nullfuncref"; - break; + return os << "nullfuncref"; case HeapType::nocont: - os << "nullcontref"; - break; + return os << "nullcontref"; case HeapType::noexn: - os << "nullexnref"; - break; + return os << "nullexnref"; } - if (type.isExact()) { - os << ')'; - } - return os; } os << "(ref "; if (type.isNullable()) { os << "null "; } - if (type.isExact()) { - os << "exact "; - } printHeapTypeName(heapType); os << ')'; } else { @@ -1977,9 +1927,8 @@ size_t RecGroupHasher::hash(Type type) const { return digest; } assert(type.isRef()); - wasm::rehash(digest, type.getNullability()); - wasm::rehash(digest, type.getExactness()); - hash_combine(digest, hash(type.getHeapType())); + rehash(digest, type.getNullability()); + rehash(digest, hash(type.getHeapType())); return digest; } @@ -2110,7 +2059,6 @@ bool RecGroupEquator::eq(Type a, Type b) const { } if (a.isRef() && b.isRef()) { return a.getNullability() == b.getNullability() && - a.getExactness() == b.getExactness() && eq(a.getHeapType(), b.getHeapType()); } return false; @@ -2321,10 +2269,8 @@ Type TypeBuilder::getTempTupleType(const Tuple& tuple) { return impl->tupleStore.insert(tuple); } -Type TypeBuilder::getTempRefType(HeapType type, - Nullability nullable, - Exactness exact) { - return Type(type, nullable, exact); +Type TypeBuilder::getTempRefType(HeapType type, Nullability nullable) { + return Type(type, nullable); } void TypeBuilder::setSubType(size_t i, std::optional super) { diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 3b7e33390f3..e33d5c3ef0d 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2288,10 +2288,6 @@ void FunctionValidator::visitRefNull(RefNull* curr) { curr->type.isNullable(), curr, "ref.null types must be nullable")) { return; } - if (!shouldBeTrue( - curr->type.isExact(), curr, "ref.null types must be exact")) { - return; - } shouldBeTrue( curr->type.isNull(), curr, "ref.null must have a bottom heap type"); } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 5cdefe3d25a..ad84449be61 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -800,7 +800,7 @@ void MemoryGrow::finalize() { void RefNull::finalize(HeapType heapType) { assert(heapType.isBottom()); - type = Type(heapType, Nullable, Exact); + type = Type(heapType, Nullable); } void RefNull::finalize(Type type_) { type = type_; } @@ -923,7 +923,6 @@ static void populateTryTableSentTypes(TryTable* curr, Module* wasm) { // wasm spec defines when GC is enabled (=== non-nullable types are allowed). // If GC is not enabled then we emit a nullable type in the binary format in // WasmBinaryWriter::writeType. - // TODO: Make this exact. Type exnref = Type(HeapType::exn, NonNullable); for (Index i = 0; i < curr->catchTags.size(); i++) { auto tagName = curr->catchTags[i]; @@ -978,7 +977,6 @@ void RefI31::finalize() { if (value->type == Type::unreachable) { type = Type::unreachable; } else { - // TODO: Make this exact. assert(type.isRef() && type.getHeapType().isMaybeShared(HeapType::i31)); } } @@ -1014,12 +1012,10 @@ void CallRef::finalize() { // unreachable instead (and similar in other GC accessors), although this // would currently cause the parser to admit more invalid modules. if (type.isRef()) { - // TODO: Make this exact. type = Type(type.getHeapType().getBottom(), NonNullable); } else if (type.isTuple()) { Tuple elems; for (auto t : type) { - // TODO: Make this exact. elems.push_back( t.isRef() ? Type(t.getHeapType().getBottom(), NonNullable) : t); } @@ -1155,7 +1151,6 @@ void StructGet::finalize() { } else if (ref->type.isNull()) { // See comment on CallRef for explanation. if (type.isRef()) { - // TODO: Make this exact. type = Type(type.getHeapType().getBottom(), NonNullable); } } else { @@ -1231,7 +1226,6 @@ void ArrayGet::finalize() { } else if (ref->type.isNull()) { // See comment on CallRef for explanation. if (type.isRef()) { - // TODO: Make this exact. type = Type(type.getHeapType().getBottom(), NonNullable); } } else { @@ -1313,13 +1307,11 @@ void RefAs::finalize() { break; case AnyConvertExtern: type = Type(HeapTypes::any.getBasic(valHeapType.getShared()), - value->type.getNullability(), - Inexact); + value->type.getNullability()); break; case ExternConvertAny: type = Type(HeapTypes::ext.getBasic(valHeapType.getShared()), - value->type.getNullability(), - Inexact); + value->type.getNullability()); break; default: WASM_UNREACHABLE("invalid ref.as_*"); @@ -1332,15 +1324,11 @@ void StringNew::finalize() { (end && end->type == Type::unreachable)) { type = Type::unreachable; } else { - // TODO: Make this exact. type = Type(HeapType::string, NonNullable); } } -void StringConst::finalize() { - // TODO: Make this exact. - type = Type(HeapType::string, NonNullable); -} +void StringConst::finalize() { type = Type(HeapType::string, NonNullable); } void StringMeasure::finalize() { if (ref->type == Type::unreachable) { @@ -1363,7 +1351,6 @@ void StringConcat::finalize() { if (left->type == Type::unreachable || right->type == Type::unreachable) { type = Type::unreachable; } else { - // TODO: Make this exact. type = Type(HeapType::string, NonNullable); } } @@ -1389,7 +1376,6 @@ void StringSliceWTF::finalize() { end->type == Type::unreachable) { type = Type::unreachable; } else { - // TODO: Make this exact. type = Type(HeapType::string, NonNullable); } } diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index 0f8463d55da..1e676b7194a 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -428,32 +428,6 @@ TEST_F(TypeTest, CanonicalizeUses) { EXPECT_NE(built[4], built[6]); } -TEST_F(TypeTest, CanonicalizeExactRefs) { - TypeBuilder builder(4); - - // Types that vary in exactness or nullability of references are different. - Type a = builder.getTempRefType(builder[0], Nullable, Inexact); - Type b = builder.getTempRefType(builder[1], NonNullable, Inexact); - Type c = builder.getTempRefType(builder[2], Nullable, Exact); - Type d = builder.getTempRefType(builder[3], NonNullable, Exact); - - builder[0] = Struct({Field(a, Mutable)}); - builder[1] = Struct({Field(b, Mutable)}); - builder[2] = Struct({Field(c, Mutable)}); - builder[3] = Struct({Field(d, Mutable)}); - - auto result = builder.build(); - ASSERT_TRUE(result); - auto built = *result; - - EXPECT_NE(built[0], built[1]); - EXPECT_NE(built[0], built[2]); - EXPECT_NE(built[0], built[3]); - EXPECT_NE(built[1], built[2]); - EXPECT_NE(built[1], built[3]); - EXPECT_NE(built[2], built[3]); -} - TEST_F(TypeTest, CanonicalizeSelfReferences) { TypeBuilder builder(5); // Single self-reference @@ -1173,26 +1147,18 @@ FUZZ_TEST(TypeFuzzTest, TestHeapTypeRelationsFuzz) #endif // FUZZTEST TEST_F(TypeTest, TestTypeRelations) { - Type any = Type(HeapType::any, NonNullable, Inexact); - Type nullAny = Type(HeapType::any, Nullable, Inexact); - Type exactAny = Type(HeapType::any, NonNullable, Exact); - Type nullExactAny = Type(HeapType::any, Nullable, Exact); + Type any = Type(HeapType::any, NonNullable); + Type nullAny = Type(HeapType::any, Nullable); HeapType defined = Struct(); - Type def = Type(defined, NonNullable, Inexact); - Type nullDef = Type(defined, Nullable, Inexact); - Type exactDef = Type(defined, NonNullable, Exact); - Type nullExactDef = Type(defined, Nullable, Exact); + Type def = Type(defined, NonNullable); + Type nullDef = Type(defined, Nullable); - Type none = Type(HeapType::none, NonNullable, Inexact); - Type nullNone = Type(HeapType::none, Nullable, Inexact); - Type exactNone = Type(HeapType::none, NonNullable, Exact); - Type nullExactNone = Type(HeapType::none, Nullable, Exact); + Type none = Type(HeapType::none, NonNullable); + Type nullNone = Type(HeapType::none, Nullable); - Type func = Type(HeapType::func, NonNullable, Inexact); - Type nullFunc = Type(HeapType::func, Nullable, Inexact); - Type exactFunc = Type(HeapType::func, NonNullable, Exact); - Type nullExactFunc = Type(HeapType::func, Nullable, Exact); + Type func = Type(HeapType::func, NonNullable); + Type nullFunc = Type(HeapType::func, Nullable); Type i32 = Type::i32; Type unreachable = Type::unreachable; @@ -1251,165 +1217,54 @@ TEST_F(TypeTest, TestTypeRelations) { assertLUB(any, any, any, any); assertLUB(any, nullAny, nullAny, any); - assertLUB(any, exactAny, any, exactAny); - assertLUB(any, nullExactAny, nullAny, exactAny); assertLUB(any, def, any, def); assertLUB(any, nullDef, nullAny, def); - assertLUB(any, exactDef, any, exactDef); - assertLUB(any, nullExactDef, nullAny, exactDef); assertLUB(any, none, any, none); assertLUB(any, nullNone, nullAny, none); - assertLUB(any, exactNone, any, exactNone); - assertLUB(any, nullExactNone, nullAny, exactNone); assertLUB(any, func, Type(Type::none), unreachable); assertLUB(any, nullFunc, Type(Type::none), unreachable); - assertLUB(any, exactFunc, Type(Type::none), unreachable); - assertLUB(any, nullExactFunc, Type(Type::none), unreachable); assertLUB(any, i32, Type(Type::none), unreachable); assertLUB(any, unreachable, any, unreachable); assertLUB(nullAny, nullAny, nullAny, nullAny); - assertLUB(nullAny, exactAny, nullAny, exactAny); - assertLUB(nullAny, nullExactAny, nullAny, nullExactAny); assertLUB(nullAny, def, nullAny, def); assertLUB(nullAny, nullDef, nullAny, nullDef); - assertLUB(nullAny, exactDef, nullAny, exactDef); - assertLUB(nullAny, nullExactDef, nullAny, nullExactDef); assertLUB(nullAny, none, nullAny, none); assertLUB(nullAny, nullNone, nullAny, nullNone); - assertLUB(nullAny, exactNone, nullAny, exactNone); - assertLUB(nullAny, nullExactNone, nullAny, nullExactNone); assertLUB(nullAny, func, Type(Type::none), unreachable); assertLUB(nullAny, nullFunc, Type(Type::none), unreachable); - assertLUB(nullAny, exactFunc, Type(Type::none), unreachable); - assertLUB(nullAny, nullExactFunc, Type(Type::none), unreachable); assertLUB(nullAny, i32, Type(Type::none), unreachable); assertLUB(nullAny, unreachable, nullAny, unreachable); - assertLUB(exactAny, exactAny, exactAny, exactAny); - assertLUB(exactAny, nullExactAny, nullExactAny, exactAny); - assertLUB(exactAny, def, any, exactNone); - assertLUB(exactAny, nullDef, nullAny, exactNone); - assertLUB(exactAny, exactDef, any, exactNone); - assertLUB(exactAny, nullExactDef, nullAny, exactNone); - assertLUB(exactAny, none, any, exactNone); - assertLUB(exactAny, nullNone, nullAny, exactNone); - assertLUB(exactAny, exactNone, exactAny, exactNone); - assertLUB(exactAny, nullExactNone, nullExactAny, exactNone); - assertLUB(exactAny, func, Type(Type::none), unreachable); - assertLUB(exactAny, nullFunc, Type(Type::none), unreachable); - assertLUB(exactAny, exactFunc, Type(Type::none), unreachable); - assertLUB(exactAny, nullExactFunc, Type(Type::none), unreachable); - assertLUB(exactAny, i32, Type(Type::none), unreachable); - assertLUB(exactAny, unreachable, exactAny, unreachable); - - assertLUB(nullExactAny, nullExactAny, nullExactAny, nullExactAny); - assertLUB(nullExactAny, def, nullAny, exactNone); - assertLUB(nullExactAny, nullDef, nullAny, nullExactNone); - assertLUB(nullExactAny, exactDef, nullAny, exactNone); - assertLUB(nullExactAny, nullExactDef, nullAny, nullExactNone); - assertLUB(nullExactAny, none, nullAny, exactNone); - assertLUB(nullExactAny, nullNone, nullAny, nullExactNone); - assertLUB(nullExactAny, exactNone, nullExactAny, exactNone); - assertLUB(nullExactAny, nullExactNone, nullExactAny, nullExactNone); - assertLUB(nullExactAny, func, Type(Type::none), unreachable); - assertLUB(nullExactAny, nullFunc, Type(Type::none), unreachable); - assertLUB(nullExactAny, exactFunc, Type(Type::none), unreachable); - assertLUB(nullExactAny, nullExactFunc, Type(Type::none), unreachable); - assertLUB(nullExactAny, i32, Type(Type::none), unreachable); - assertLUB(nullExactAny, unreachable, nullExactAny, unreachable); - assertLUB(def, def, def, def); assertLUB(def, nullDef, nullDef, def); - assertLUB(def, exactDef, def, exactDef); - assertLUB(def, nullExactDef, nullDef, exactDef); assertLUB(def, none, def, none); assertLUB(def, nullNone, nullDef, none); - assertLUB(def, exactNone, def, exactNone); - assertLUB(def, nullExactNone, nullDef, exactNone); assertLUB(def, func, Type(Type::none), unreachable); assertLUB(def, nullFunc, Type(Type::none), unreachable); - assertLUB(def, exactFunc, Type(Type::none), unreachable); - assertLUB(def, nullExactFunc, Type(Type::none), unreachable); assertLUB(def, i32, Type(Type::none), unreachable); assertLUB(def, unreachable, def, unreachable); assertLUB(nullDef, nullDef, nullDef, nullDef); - assertLUB(nullDef, exactDef, nullDef, exactDef); - assertLUB(nullDef, nullExactDef, nullDef, nullExactDef); assertLUB(nullDef, none, nullDef, none); assertLUB(nullDef, nullNone, nullDef, nullNone); - assertLUB(nullDef, exactNone, nullDef, exactNone); - assertLUB(nullDef, nullExactNone, nullDef, nullExactNone); assertLUB(nullDef, func, Type(Type::none), unreachable); assertLUB(nullDef, nullFunc, Type(Type::none), unreachable); - assertLUB(nullDef, exactFunc, Type(Type::none), unreachable); - assertLUB(nullDef, nullExactFunc, Type(Type::none), unreachable); assertLUB(nullDef, i32, Type(Type::none), unreachable); assertLUB(nullDef, unreachable, nullDef, unreachable); - assertLUB(exactDef, exactDef, exactDef, exactDef); - assertLUB(exactDef, nullExactDef, nullExactDef, exactDef); - assertLUB(exactDef, none, def, exactNone); - assertLUB(exactDef, nullNone, nullDef, exactNone); - assertLUB(exactDef, exactNone, exactDef, exactNone); - assertLUB(exactDef, nullExactNone, nullExactDef, exactNone); - assertLUB(exactDef, func, Type(Type::none), unreachable); - assertLUB(exactDef, nullFunc, Type(Type::none), unreachable); - assertLUB(exactDef, exactFunc, Type(Type::none), unreachable); - assertLUB(exactDef, nullExactFunc, Type(Type::none), unreachable); - assertLUB(exactDef, i32, Type(Type::none), unreachable); - assertLUB(exactDef, unreachable, exactDef, unreachable); - - assertLUB(nullExactDef, nullExactDef, nullExactDef, nullExactDef); - assertLUB(nullExactDef, none, nullDef, exactNone); - assertLUB(nullExactDef, nullNone, nullDef, nullExactNone); - assertLUB(nullExactDef, exactNone, nullExactDef, exactNone); - assertLUB(nullExactDef, nullExactNone, nullExactDef, nullExactNone); - assertLUB(nullExactDef, func, Type(Type::none), unreachable); - assertLUB(nullExactDef, nullFunc, Type(Type::none), unreachable); - assertLUB(nullExactDef, exactFunc, Type(Type::none), unreachable); - assertLUB(nullExactDef, nullExactFunc, Type(Type::none), unreachable); - assertLUB(nullExactDef, i32, Type(Type::none), unreachable); - assertLUB(nullExactDef, unreachable, nullExactDef, unreachable); - assertLUB(none, none, none, none); assertLUB(none, nullNone, nullNone, none); - assertLUB(none, exactNone, none, exactNone); - assertLUB(none, nullExactNone, nullNone, exactNone); assertLUB(none, func, Type(Type::none), unreachable); assertLUB(none, nullFunc, Type(Type::none), unreachable); - assertLUB(none, exactFunc, Type(Type::none), unreachable); - assertLUB(none, nullExactFunc, Type(Type::none), unreachable); assertLUB(none, i32, Type(Type::none), unreachable); assertLUB(none, unreachable, none, unreachable); assertLUB(nullNone, nullNone, nullNone, nullNone); - assertLUB(nullNone, exactNone, nullNone, exactNone); - assertLUB(nullNone, nullExactNone, nullNone, nullExactNone); assertLUB(nullNone, func, Type(Type::none), unreachable); assertLUB(nullNone, nullFunc, Type(Type::none), unreachable); - assertLUB(nullNone, exactFunc, Type(Type::none), unreachable); - assertLUB(nullNone, nullExactFunc, Type(Type::none), unreachable); assertLUB(nullNone, i32, Type(Type::none), unreachable); assertLUB(nullNone, unreachable, nullNone, unreachable); - - assertLUB(exactNone, exactNone, exactNone, exactNone); - assertLUB(exactNone, nullExactNone, nullExactNone, exactNone); - assertLUB(exactNone, func, Type(Type::none), unreachable); - assertLUB(exactNone, nullFunc, Type(Type::none), unreachable); - assertLUB(exactNone, exactFunc, Type(Type::none), unreachable); - assertLUB(exactNone, nullExactFunc, Type(Type::none), unreachable); - assertLUB(exactNone, i32, Type(Type::none), unreachable); - assertLUB(exactNone, unreachable, exactNone, unreachable); - - assertLUB(nullExactNone, nullExactNone, nullExactNone, nullExactNone); - assertLUB(nullExactNone, func, Type(Type::none), unreachable); - assertLUB(nullExactNone, nullFunc, Type(Type::none), unreachable); - assertLUB(nullExactNone, exactFunc, Type(Type::none), unreachable); - assertLUB(nullExactNone, nullExactFunc, Type(Type::none), unreachable); - assertLUB(nullExactNone, i32, Type(Type::none), unreachable); - assertLUB(nullExactNone, unreachable, nullExactNone, unreachable); } TEST_F(TypeTest, TestSubtypeErrors) { diff --git a/test/lit/basic/exact-references.wast b/test/lit/basic/exact-references.wast deleted file mode 100644 index e6c1599ea48..00000000000 --- a/test/lit/basic/exact-references.wast +++ /dev/null @@ -1,672 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. - -;; RUN: wasm-opt %s -all -o %t.text.wast -g -S -;; RUN: wasm-as %s -all -g -o %t.wasm -;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast -;; RUN: wasm-as %s -all -o %t.nodebug.wasm -;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast -;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT -;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN -;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG - -;; Also check that if we emit a binary without custom descriptors enabled, the -;; types are generalized to be inexact. - -;; RUN: wasm-opt %s -all --disable-custom-descriptors -g -o %t.noexact.wasm -;; RUN: wasm-opt %t.noexact.wasm -all -S -o - | filecheck %s --check-prefix=NO-EXACT - -(module - ;; CHECK-TEXT: (type $foo (struct (field (exact anyref)) (field (ref exact any)) (field (ref null exact $foo)) (field (ref exact $foo)))) - ;; CHECK-BIN: (type $foo (struct (field (exact anyref)) (field (ref exact any)) (field (ref null exact $foo)) (field (ref exact $foo)))) - ;; NO-EXACT: (type $foo (struct (field anyref) (field (ref any)) (field (ref null $foo)) (field (ref $foo)))) - (type $foo (struct (field (exact anyref) (ref exact any) (ref null exact $foo) (ref exact $foo)))) - - - ;; CHECK-TEXT: (type $1 (func (param (exact anyref)) (result (ref exact any)))) - - ;; CHECK-TEXT: (type $2 (func (param anyref) (result anyref))) - - ;; CHECK-TEXT: (type $3 (func (param (exact i31ref)))) - - ;; CHECK-TEXT: (type $4 (func (param (exact eqref)))) - - ;; CHECK-TEXT: (type $5 (func (param (exact anyref)))) - - ;; CHECK-TEXT: (type $6 (func (param (exact anyref)) (result (exact anyref)))) - - ;; CHECK-TEXT: (import "" "g1" (global $g1 (exact anyref))) - ;; CHECK-BIN: (type $1 (func (param (exact anyref)) (result (ref exact any)))) - - ;; CHECK-BIN: (type $2 (func (param anyref) (result anyref))) - - ;; CHECK-BIN: (type $3 (func (param (exact i31ref)))) - - ;; CHECK-BIN: (type $4 (func (param (exact eqref)))) - - ;; CHECK-BIN: (type $5 (func (param (exact anyref)))) - - ;; CHECK-BIN: (type $6 (func (param (exact anyref)) (result (exact anyref)))) - - ;; CHECK-BIN: (import "" "g1" (global $g1 (exact anyref))) - ;; NO-EXACT: (type $1 (func (param anyref) (result anyref))) - - ;; NO-EXACT: (type $2 (func (param anyref) (result (ref any)))) - - ;; NO-EXACT: (type $3 (func (param i31ref))) - - ;; NO-EXACT: (type $4 (func (param eqref))) - - ;; NO-EXACT: (type $5 (func (param anyref))) - - ;; NO-EXACT: (import "" "g1" (global $g1 anyref)) - (import "" "g1" (global $g1 (exact anyref))) - - ;; CHECK-TEXT: (import "" "g2" (global $g2 (ref exact any))) - ;; CHECK-BIN: (import "" "g2" (global $g2 (ref exact any))) - ;; NO-EXACT: (import "" "g2" (global $g2 (ref any))) - (import "" "g2" (global $g2 (ref exact any))) - - ;; CHECK-TEXT: (import "" "g3" (global $g3 (ref null exact $foo))) - ;; CHECK-BIN: (import "" "g3" (global $g3 (ref null exact $foo))) - ;; NO-EXACT: (import "" "g3" (global $g3 (ref null $foo))) - (import "" "g3" (global $g3 (ref null exact $foo))) - - ;; CHECK-TEXT: (import "" "g4" (global $g4 (ref exact $foo))) - ;; CHECK-BIN: (import "" "g4" (global $g4 (ref exact $foo))) - ;; NO-EXACT: (import "" "g4" (global $g4 (ref $foo))) - (import "" "g4" (global $g4 (ref exact $foo))) - - ;; CHECK-TEXT: (func $ref-test (type $3) (param $0 (exact i31ref)) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (ref.test (ref exact i31) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (ref.test (exact i31ref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-test (type $3) (param $0 (exact i31ref)) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (ref.test (ref exact i31) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (ref.test (exact i31ref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $ref-test (type $3) (param $0 i31ref) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (ref.test (ref i31) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (ref.test i31ref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $ref-test (param (ref null exact i31)) - (drop - (ref.test (ref exact i31) - (local.get 0) - ) - ) - (drop - (ref.test (ref null exact i31) - (local.get 0) - ) - ) - ) - - ;; CHECK-TEXT: (func $ref-cast (type $4) (param $0 (exact eqref)) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (ref.cast (ref exact eq) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (ref.cast (exact eqref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (ref.cast (ref exact none) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $ref-cast (type $4) (param $0 (exact eqref)) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (ref.cast (ref exact eq) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (ref.cast (exact eqref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (ref.cast (ref exact none) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $ref-cast (type $4) (param $0 eqref) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (ref.cast (ref eq) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (ref.cast eqref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (ref.cast (ref none) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $ref-cast (param (ref null exact eq)) - (drop - (ref.cast (ref exact eq) - (local.get 0) - ) - ) - (drop - (ref.cast (ref null exact eq) - (local.get 0) - ) - ) - (drop - (ref.cast (ref exact i31) - (local.get 0) - ) - ) - ) - - ;; CHECK-TEXT: (func $br-on-cast (type $2) (param $0 anyref) (result anyref) - ;; CHECK-TEXT-NEXT: (block $label (result anyref) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast $label anyref (exact eqref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast $label anyref (ref exact eq) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast $label anyref (exact i31ref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $br-on-cast (type $2) (param $0 anyref) (result anyref) - ;; CHECK-BIN-NEXT: (block $block (result anyref) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast $block anyref (exact eqref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast $block anyref (ref exact eq) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast $block anyref (exact i31ref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $br-on-cast (type $1) (param $0 anyref) (result anyref) - ;; NO-EXACT-NEXT: (block $block (result anyref) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast $block anyref eqref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast $block anyref (ref eq) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast $block anyref i31ref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $br-on-cast (param anyref) (result anyref) - (drop - (br_on_cast 0 anyref (ref null exact eq) - (local.get 0) - ) - ) - (drop - (br_on_cast 0 anyref (ref exact eq) - (local.get 0) - ) - ) - (drop - (br_on_cast 0 anyref (ref null exact i31) - (local.get 0) - ) - ) - (local.get 0) - ) - - ;; CHECK-TEXT: (func $br-on-cast-fail (type $2) (param $0 anyref) (result anyref) - ;; CHECK-TEXT-NEXT: (block $label (result anyref) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast_fail $label anyref (exact eqref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast_fail $label anyref (ref exact eq) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (br_on_cast_fail $label anyref (exact i31ref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $br-on-cast-fail (type $2) (param $0 anyref) (result anyref) - ;; CHECK-BIN-NEXT: (block $block (result anyref) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast_fail $block anyref (exact eqref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast_fail $block anyref (ref exact eq) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast_fail $block anyref (exact i31ref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $br-on-cast-fail (type $1) (param $0 anyref) (result anyref) - ;; NO-EXACT-NEXT: (block $block (result anyref) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast_fail $block anyref eqref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast_fail $block anyref (ref eq) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast_fail $block anyref i31ref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $br-on-cast-fail (param anyref) (result anyref) - (drop - (br_on_cast_fail 0 anyref (ref null exact eq) - (local.get 0) - ) - ) - (drop - (br_on_cast_fail 0 anyref (ref exact eq) - (local.get 0) - ) - ) - (drop - (br_on_cast_fail 0 anyref (ref null exact i31) - (local.get 0) - ) - ) - (local.get 0) - ) - - ;; CHECK-TEXT: (func $valid-ref-as-non-null (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (ref.as_non_null - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $valid-ref-as-non-null (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-BIN-NEXT: (ref.as_non_null - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $valid-ref-as-non-null (type $2) (param $0 anyref) (result (ref any)) - ;; NO-EXACT-NEXT: (ref.as_non_null - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $valid-ref-as-non-null (param (ref null exact any)) (result (ref exact any)) - (ref.as_non_null - (local.get 0) - ) - ) - - ;; CHECK-TEXT: (func $valid-br-on-null (type $5) (param $0 (exact anyref)) - ;; CHECK-TEXT-NEXT: (block $label - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (block (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (br_on_null $label - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $valid-br-on-null (type $5) (param $0 (exact anyref)) - ;; CHECK-BIN-NEXT: (block $block - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_null $block - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $valid-br-on-null (type $5) (param $0 anyref) - ;; NO-EXACT-NEXT: (block $block - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_null $block - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $valid-br-on-null (param (ref null exact any)) - (drop - (block (result (ref exact any)) - (br_on_null 1 - (local.get 0) - ) - ) - ) - ) - - ;; CHECK-TEXT: (func $valid-br-on-non-null (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (block $label (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (br_on_non_null $label - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $valid-br-on-non-null (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-BIN-NEXT: (block $block (result (ref exact any)) - ;; CHECK-BIN-NEXT: (br_on_non_null $block - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $valid-br-on-non-null (type $2) (param $0 anyref) (result (ref any)) - ;; NO-EXACT-NEXT: (block $block (result (ref any)) - ;; NO-EXACT-NEXT: (br_on_non_null $block - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (unreachable) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $valid-br-on-non-null (param (ref null exact any)) (result (ref exact any)) - (br_on_non_null 0 - (local.get 0) - ) - (unreachable) - ) - - ;; CHECK-TEXT: (func $valid-br-on-cast (type $6) (param $0 (exact anyref)) (result (exact anyref)) - ;; CHECK-TEXT-NEXT: (block $label (result (exact anyref)) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (block (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (br_on_cast $label (exact anyref) (exact anyref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $valid-br-on-cast (type $6) (param $0 (exact anyref)) (result (exact anyref)) - ;; CHECK-BIN-NEXT: (block $block (result (exact anyref)) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast $block (exact anyref) (exact anyref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $valid-br-on-cast (type $1) (param $0 anyref) (result anyref) - ;; NO-EXACT-NEXT: (block $block (result anyref) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast $block anyref anyref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (unreachable) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $valid-br-on-cast (param (ref null exact any)) (result (ref null exact any)) - (drop - (block (result (ref exact any)) - (br_on_cast 1 (ref null exact any) (ref null exact any) - (local.get 0) - ) - ) - ) - (unreachable) - ) - - ;; CHECK-TEXT: (func $valid-br-on-cast-fail (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (block $label (result (ref exact any)) - ;; CHECK-TEXT-NEXT: (drop - ;; CHECK-TEXT-NEXT: (block (result (exact anyref)) - ;; CHECK-TEXT-NEXT: (br_on_cast_fail $label (exact anyref) (exact anyref) - ;; CHECK-TEXT-NEXT: (local.get $0) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: (unreachable) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-TEXT-NEXT: ) - ;; CHECK-BIN: (func $valid-br-on-cast-fail (type $1) (param $0 (exact anyref)) (result (ref exact any)) - ;; CHECK-BIN-NEXT: (block $block (result (ref exact any)) - ;; CHECK-BIN-NEXT: (drop - ;; CHECK-BIN-NEXT: (br_on_cast_fail $block (exact anyref) (exact anyref) - ;; CHECK-BIN-NEXT: (local.get $0) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: (unreachable) - ;; CHECK-BIN-NEXT: ) - ;; CHECK-BIN-NEXT: ) - ;; NO-EXACT: (func $valid-br-on-cast-fail (type $2) (param $0 anyref) (result (ref any)) - ;; NO-EXACT-NEXT: (block $block (result (ref any)) - ;; NO-EXACT-NEXT: (drop - ;; NO-EXACT-NEXT: (br_on_cast_fail $block anyref anyref - ;; NO-EXACT-NEXT: (local.get $0) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: (unreachable) - ;; NO-EXACT-NEXT: ) - ;; NO-EXACT-NEXT: ) - (func $valid-br-on-cast-fail (param (ref null exact any)) (result (ref exact any)) - (drop - (block (result (ref null exact any)) - (br_on_cast_fail 1 (ref null exact any) (ref null exact any) - (local.get 0) - ) - ) - ) - (unreachable) - ) -) -;; CHECK-BIN-NODEBUG: (type $0 (struct (field (exact anyref)) (field (ref exact any)) (field (ref null exact $0)) (field (ref exact $0)))) - -;; CHECK-BIN-NODEBUG: (type $1 (func (param (exact anyref)) (result (ref exact any)))) - -;; CHECK-BIN-NODEBUG: (type $2 (func (param anyref) (result anyref))) - -;; CHECK-BIN-NODEBUG: (type $3 (func (param (exact i31ref)))) - -;; CHECK-BIN-NODEBUG: (type $4 (func (param (exact eqref)))) - -;; CHECK-BIN-NODEBUG: (type $5 (func (param (exact anyref)))) - -;; CHECK-BIN-NODEBUG: (type $6 (func (param (exact anyref)) (result (exact anyref)))) - -;; CHECK-BIN-NODEBUG: (import "" "g1" (global $gimport$0 (exact anyref))) - -;; CHECK-BIN-NODEBUG: (import "" "g2" (global $gimport$1 (ref exact any))) - -;; CHECK-BIN-NODEBUG: (import "" "g3" (global $gimport$2 (ref null exact $0))) - -;; CHECK-BIN-NODEBUG: (import "" "g4" (global $gimport$3 (ref exact $0))) - -;; CHECK-BIN-NODEBUG: (func $0 (type $3) (param $0 (exact i31ref)) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (ref.test (ref exact i31) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (ref.test (exact i31ref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $1 (type $4) (param $0 (exact eqref)) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (ref exact eq) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (exact eqref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (ref exact none) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $2 (type $2) (param $0 anyref) (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (block $block (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast $block anyref (exact eqref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast $block anyref (ref exact eq) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast $block anyref (exact i31ref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $3 (type $2) (param $0 anyref) (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (block $block (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast_fail $block anyref (exact eqref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast_fail $block anyref (ref exact eq) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast_fail $block anyref (exact i31ref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $4 (type $1) (param $0 (exact anyref)) (result (ref exact any)) -;; CHECK-BIN-NODEBUG-NEXT: (ref.as_non_null -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $5 (type $5) (param $0 (exact anyref)) -;; CHECK-BIN-NODEBUG-NEXT: (block $block -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_null $block -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $6 (type $1) (param $0 (exact anyref)) (result (ref exact any)) -;; CHECK-BIN-NODEBUG-NEXT: (block $block (result (ref exact any)) -;; CHECK-BIN-NODEBUG-NEXT: (br_on_non_null $block -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $7 (type $6) (param $0 (exact anyref)) (result (exact anyref)) -;; CHECK-BIN-NODEBUG-NEXT: (block $block (result (exact anyref)) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast $block (exact anyref) (exact anyref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) - -;; CHECK-BIN-NODEBUG: (func $8 (type $1) (param $0 (exact anyref)) (result (ref exact any)) -;; CHECK-BIN-NODEBUG-NEXT: (block $block (result (ref exact any)) -;; CHECK-BIN-NODEBUG-NEXT: (drop -;; CHECK-BIN-NODEBUG-NEXT: (br_on_cast_fail $block (exact anyref) (exact anyref) -;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: (unreachable) -;; CHECK-BIN-NODEBUG-NEXT: ) -;; CHECK-BIN-NODEBUG-NEXT: ) diff --git a/test/lit/basic/reference-types.wast b/test/lit/basic/reference-types.wast index 7c4f2a23e76..82b1f8da4e3 100644 --- a/test/lit/basic/reference-types.wast +++ b/test/lit/basic/reference-types.wast @@ -961,7 +961,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block2 (result eqref) - ;; CHECK-BIN-NEXT: (ref.cast (exact nullref) + ;; CHECK-BIN-NEXT: (ref.cast nullref ;; CHECK-BIN-NEXT: (br_if $block2 ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: (i32.const 1) @@ -987,7 +987,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block5 (result funcref) - ;; CHECK-BIN-NEXT: (ref.cast (exact nullfuncref) + ;; CHECK-BIN-NEXT: (ref.cast nullfuncref ;; CHECK-BIN-NEXT: (br_if $block5 ;; CHECK-BIN-NEXT: (ref.null nofunc) ;; CHECK-BIN-NEXT: (i32.const 1) @@ -1023,7 +1023,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block9 (result anyref) - ;; CHECK-BIN-NEXT: (ref.cast (exact nullref) + ;; CHECK-BIN-NEXT: (ref.cast nullref ;; CHECK-BIN-NEXT: (br_if $block9 ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: (i32.const 1) @@ -1043,7 +1043,7 @@ ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: (drop ;; CHECK-BIN-NEXT: (block $block11 (result anyref) - ;; CHECK-BIN-NEXT: (ref.cast (exact nullref) + ;; CHECK-BIN-NEXT: (ref.cast nullref ;; CHECK-BIN-NEXT: (br_if $block11 ;; CHECK-BIN-NEXT: (ref.null none) ;; CHECK-BIN-NEXT: (i32.const 1) @@ -2298,7 +2298,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block2 (result eqref) -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (exact nullref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.cast nullref ;; CHECK-BIN-NODEBUG-NEXT: (br_if $block2 ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) @@ -2324,7 +2324,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block5 (result funcref) -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (exact nullfuncref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.cast nullfuncref ;; CHECK-BIN-NODEBUG-NEXT: (br_if $block5 ;; CHECK-BIN-NODEBUG-NEXT: (ref.null nofunc) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) @@ -2360,7 +2360,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block9 (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (exact nullref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.cast nullref ;; CHECK-BIN-NODEBUG-NEXT: (br_if $block9 ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) @@ -2380,7 +2380,7 @@ ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: (drop ;; CHECK-BIN-NODEBUG-NEXT: (block $block11 (result anyref) -;; CHECK-BIN-NODEBUG-NEXT: (ref.cast (exact nullref) +;; CHECK-BIN-NODEBUG-NEXT: (ref.cast nullref ;; CHECK-BIN-NODEBUG-NEXT: (br_if $block11 ;; CHECK-BIN-NODEBUG-NEXT: (ref.null none) ;; CHECK-BIN-NODEBUG-NEXT: (i32.const 1) diff --git a/test/lit/ctor-eval/materialize-null-local.wast b/test/lit/ctor-eval/materialize-null-local.wast deleted file mode 100644 index 1f880f6816b..00000000000 --- a/test/lit/ctor-eval/materialize-null-local.wast +++ /dev/null @@ -1,26 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. - -;; RUN: wasm-ctor-eval %s -all --ctors=test --kept-exports=test --ignore-external-input -S -o - \ -;; RUN: | filecheck %s - -;; Check that materializing a non-data null local, which at time of writing uses -;; Builder::makeConstantExpression, does not trigger an assertion failure. - -(module - (func $test (export "test") (param $0 externref) - (local $3 anyref) - (local.set $3 - (any.convert_extern - (local.get $0) - ) - ) - ) -) -;; CHECK: (type $0 (func (param externref))) - -;; CHECK: (export "test" (func $test_1)) - -;; CHECK: (func $test_1 (type $0) (param $0 externref) -;; CHECK-NEXT: (local $3 anyref) -;; CHECK-NEXT: (nop) -;; CHECK-NEXT: ) diff --git a/test/lit/exec/exact.wast b/test/lit/exec/exact.wast deleted file mode 100644 index 2667e0e4dce..00000000000 --- a/test/lit/exec/exact.wast +++ /dev/null @@ -1,21 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. - -;; RUN: wasm-opt %s -all --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s - -(module - ;; CHECK: [fuzz-exec] calling convert-null-extern - ;; CHECK-NEXT: [fuzz-exec] note result: convert-null-extern => null - (func $convert-null-extern (export "convert-null-extern") (result (exact nullref)) - (local externref) - ;; The value produced by this cast must be exact to avoid triggering an - ;; assertion. - (ref.cast (exact nullref) - (any.convert_extern - (local.get 0) - ) - ) - ) -) -;; CHECK: [fuzz-exec] calling convert-null-extern -;; CHECK-NEXT: [fuzz-exec] note result: convert-null-extern => null -;; CHECK-NEXT: [fuzz-exec] comparing convert-null-extern diff --git a/test/lit/heap-types.wast b/test/lit/heap-types.wast index baf77196611..4613f4894fd 100644 --- a/test/lit/heap-types.wast +++ b/test/lit/heap-types.wast @@ -12,7 +12,7 @@ (type $struct.B (struct i32)) ;; CHECK: (func $test (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.test (ref exact none) + ;; CHECK-NEXT: (ref.test (ref none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -29,7 +29,7 @@ (type $struct.B (struct i32)) ;; CHECK: (func $test (type $0) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast (exact nullref) + ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index ab9b7f8a745..0bc4372ec35 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -1034,7 +1034,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $struct3) @@ -1233,7 +1233,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (local.get $struct3) diff --git a/test/lit/passes/coalesce-locals-exact.wast b/test/lit/passes/coalesce-locals-exact.wast deleted file mode 100644 index 1568d3634cf..00000000000 --- a/test/lit/passes/coalesce-locals-exact.wast +++ /dev/null @@ -1,47 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; Check that TypeUpdating::handleNonDefaultableLocals handles locals with exact -;; reference types correctly, and in particular that it preserves the exactness -;; of the types. - -;; RUN: wasm-opt %s -all --coalesce-locals -S -o - | filecheck %s - -(module - ;; CHECK: (func $test (type $0) (param $0 (exact i31ref)) (result (ref exact i31)) - ;; CHECK-NEXT: (local $1 (exact i31ref)) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block $l - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $test (param (exact i31ref)) (result (ref exact i31)) - (local $l (ref exact i31)) - ;; This dead set will be optimized out. - (local.set $l - (ref.as_non_null - (local.get 0) - ) - ) - (block $l - ;; This remaining set does not structurally dominate the get. - (local.set $l - (ref.as_non_null - (local.get 0) - ) - ) - ) - ;; This will have to be fixed up and the local made nullable. - (local.get $l) - ) -) diff --git a/test/lit/passes/code-pushing-gc.wast b/test/lit/passes/code-pushing-gc.wast index fb9ff12f7da..1aac5c55cf7 100644 --- a/test/lit/passes/code-pushing-gc.wast +++ b/test/lit/passes/code-pushing-gc.wast @@ -7,7 +7,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $out (result (ref func)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $out (exact nullfuncref) (ref exact nofunc) + ;; CHECK-NEXT: (br_on_cast $out nullfuncref (ref nofunc) ;; CHECK-NEXT: (ref.null nofunc) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -48,7 +48,7 @@ ;; CHECK-NEXT: (ref.func $br_on_no) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $out (exact nullfuncref) (ref exact nofunc) + ;; CHECK-NEXT: (br_on_cast $out nullfuncref (ref nofunc) ;; CHECK-NEXT: (ref.null nofunc) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast index a93f3e7347f..8cefbe88184 100644 --- a/test/lit/passes/dae-gc-refine-params.wast +++ b/test/lit/passes/dae-gc-refine-params.wast @@ -262,7 +262,7 @@ ) ;; This function is called in ways that allow us to make the first parameter ;; non-nullable. - ;; CHECK: (func $various-params-null (type $13) (param $x (ref exact none)) (param $y (ref null $"{i32}")) + ;; CHECK: (func $various-params-null (type $13) (param $x (ref none)) (param $y (ref null $"{i32}")) ;; CHECK-NEXT: (local $temp i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $x) diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast index 015e515c02b..1f39567d146 100644 --- a/test/lit/passes/dae-gc.wast +++ b/test/lit/passes/dae-gc.wast @@ -110,7 +110,7 @@ ) ;; CHECK: (func $bar (type $2) (param $0 i31ref) - ;; CHECK-NEXT: (local $1 (exact nullref)) + ;; CHECK-NEXT: (local $1 nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/flatten_all-features.wast b/test/lit/passes/flatten_all-features.wast index 6c117d0a907..b601b8a1295 100644 --- a/test/lit/passes/flatten_all-features.wast +++ b/test/lit/passes/flatten_all-features.wast @@ -3581,8 +3581,8 @@ ;; CHECK: (func $subtype (type $7) (result anyref) ;; CHECK-NEXT: (local $0 eqref) ;; CHECK-NEXT: (local $1 anyref) - ;; CHECK-NEXT: (local $2 (exact nullref)) - ;; CHECK-NEXT: (local $3 (exact nullref)) + ;; CHECK-NEXT: (local $2 nullref) + ;; CHECK-NEXT: (local $3 nullref) ;; CHECK-NEXT: (local $4 eqref) ;; CHECK-NEXT: (local $5 eqref) ;; CHECK-NEXT: (local $6 eqref) @@ -3680,7 +3680,7 @@ ;; CHECK: (type $0 (func (result funcref))) ;; CHECK: (func $0 (type $0) (result funcref) - ;; CHECK-NEXT: (local $0 (ref exact nofunc)) + ;; CHECK-NEXT: (local $0 (ref nofunc)) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (ref.null nofunc) diff --git a/test/lit/passes/global-refining.wast b/test/lit/passes/global-refining.wast index 7be5a9e4e2a..927dfd1f26c 100644 --- a/test/lit/passes/global-refining.wast +++ b/test/lit/passes/global-refining.wast @@ -11,8 +11,8 @@ ;; CLOSD: (type $foo_t (func)) (type $foo_t (func)) - ;; CHECK: (global $func-null-init (mut (exact nullfuncref)) (ref.null nofunc)) - ;; CLOSD: (global $func-null-init (mut (exact nullfuncref)) (ref.null nofunc)) + ;; CHECK: (global $func-null-init (mut nullfuncref) (ref.null nofunc)) + ;; CLOSD: (global $func-null-init (mut nullfuncref) (ref.null nofunc)) (global $func-null-init (mut funcref) (ref.null $foo_t)) ;; CHECK: (global $func-func-init (mut (ref $foo_t)) (ref.func $foo)) ;; CLOSD: (global $func-func-init (mut (ref $foo_t)) (ref.func $foo)) @@ -32,8 +32,8 @@ ;; CLOSD: (type $foo_t (func)) (type $foo_t (func)) - ;; CHECK: (global $func-null-init (mut (exact nullfuncref)) (ref.null nofunc)) - ;; CLOSD: (global $func-null-init (mut (exact nullfuncref)) (ref.null nofunc)) + ;; CHECK: (global $func-null-init (mut nullfuncref) (ref.null nofunc)) + ;; CLOSD: (global $func-null-init (mut nullfuncref) (ref.null nofunc)) (global $func-null-init (mut funcref) (ref.null $foo_t)) ;; CHECK: (global $func-func-init (mut (ref null $foo_t)) (ref.func $foo)) ;; CLOSD: (global $func-func-init (mut (ref null $foo_t)) (ref.func $foo)) @@ -202,16 +202,16 @@ ;; (ref null func) to nullfuncref only when not exported, and if exported, then ;; only when immutable in open world. (module - ;; CHECK: (global $mut (mut (exact nullfuncref)) (ref.null nofunc)) - ;; CLOSD: (global $mut (mut (exact nullfuncref)) (ref.null nofunc)) + ;; CHECK: (global $mut (mut nullfuncref) (ref.null nofunc)) + ;; CLOSD: (global $mut (mut nullfuncref) (ref.null nofunc)) (global $mut (mut (ref null func)) (ref.null nofunc)) - ;; CHECK: (global $imm (exact nullfuncref) (ref.null nofunc)) - ;; CLOSD: (global $imm (exact nullfuncref) (ref.null nofunc)) + ;; CHECK: (global $imm nullfuncref (ref.null nofunc)) + ;; CLOSD: (global $imm nullfuncref (ref.null nofunc)) (global $imm (ref null func) (ref.null nofunc)) ;; CHECK: (global $mut-exp (mut funcref) (ref.null nofunc)) ;; CLOSD: (global $mut-exp (mut funcref) (ref.null nofunc)) (global $mut-exp (mut (ref null func)) (ref.null nofunc)) - ;; CHECK: (global $imm-exp (exact nullfuncref) (ref.null nofunc)) + ;; CHECK: (global $imm-exp nullfuncref (ref.null nofunc)) ;; CLOSD: (global $imm-exp funcref (ref.null nofunc)) (global $imm-exp (ref null func) (ref.null nofunc)) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index 6142550638d..6d48d651a5f 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -955,7 +955,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $child 1 ;; CHECK-NEXT: (local.get $child) @@ -970,7 +970,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $parent 0 ;; CHECK-NEXT: (local.get $parent) @@ -1072,9 +1072,9 @@ ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block (result (exact nullref)) + ;; CHECK-NEXT: (block $block (result nullref) ;; CHECK-NEXT: (br $block ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -1085,9 +1085,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block0 (result (exact nullref)) + ;; CHECK-NEXT: (block $block0 (result nullref) ;; CHECK-NEXT: (br $block0 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -1098,13 +1098,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block1 (result (exact nullref)) + ;; CHECK-NEXT: (block $block1 (result nullref) ;; CHECK-NEXT: (br $block1 - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast (exact nullref) + ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1237,7 +1237,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $child 0 ;; CHECK-NEXT: (local.get $child) @@ -1577,7 +1577,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (array.get $null ;; CHECK-NEXT: (array.new_default $null @@ -1775,10 +1775,10 @@ ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $x - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.new $storage - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $pass-through ;; CHECK-NEXT: (ref.null none) @@ -1928,7 +1928,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2153,7 +2153,7 @@ ;; CHECK-NEXT: (pop (tuple anyref anyref)) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (tuple.drop 2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2213,7 +2213,7 @@ ;; CHECK: (func $func (type $1) (result (ref $"{}")) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block (result (ref exact none)) + ;; CHECK-NEXT: (block $block (result (ref none)) ;; CHECK-NEXT: (br_on_non_null $block ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -2539,10 +2539,10 @@ ;; CHECK: (func $test-nulls (type $2) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast (exact nullref) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (ref.cast nullref + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) @@ -2554,9 +2554,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast (exact nullref) + ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (select (result i31ref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.i31 @@ -3256,7 +3256,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $import) ;; CHECK-NEXT: ) @@ -3793,7 +3793,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (array.get $chars ;; CHECK-NEXT: (local.get $chars) @@ -6056,7 +6056,7 @@ ) (module - ;; CHECK: (type $0 (func (result i64 (exact nullref) i32))) + ;; CHECK: (type $0 (func (result i64 nullref i32))) ;; CHECK: (type $array (sub (array (mut i8)))) (type $array (sub (array (mut i8)))) @@ -6096,7 +6096,7 @@ ;; CHECK: (func $loop-tuple-br_on (type $2) ;; CHECK-NEXT: (tuple.drop 3 - ;; CHECK-NEXT: (loop $loop (type $0) (result i64 (exact nullref) i32) + ;; CHECK-NEXT: (loop $loop (type $0) (result i64 nullref i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop diff --git a/test/lit/passes/gufa-vs-cfp.wast b/test/lit/passes/gufa-vs-cfp.wast index eb26820b74d..bd731d89150 100644 --- a/test/lit/passes/gufa-vs-cfp.wast +++ b/test/lit/passes/gufa-vs-cfp.wast @@ -1087,7 +1087,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $struct3 2 ;; CHECK-NEXT: (local.get $ref) @@ -1329,7 +1329,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $create3) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/heap2local-rmw.wast b/test/lit/passes/heap2local-rmw.wast index f0b397dcc99..33fef1cb506 100644 --- a/test/lit/passes/heap2local-rmw.wast +++ b/test/lit/passes/heap2local-rmw.wast @@ -50,7 +50,7 @@ ;; CHECK-NEXT: (local $1 (ref null $struct)) ;; CHECK-NEXT: (struct.atomic.rmw.cmpxchg $struct 0 ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -74,7 +74,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -107,7 +107,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -140,7 +140,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -173,7 +173,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -206,7 +206,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -239,7 +239,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -270,7 +270,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -312,7 +312,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -345,7 +345,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -378,7 +378,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -411,7 +411,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -444,7 +444,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -477,7 +477,7 @@ ;; CHECK-NEXT: (local $1 i64) ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -508,7 +508,7 @@ ;; CHECK-NEXT: (local $2 i64) ;; CHECK-NEXT: (local $3 i64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i64.const 0) ;; CHECK-NEXT: ) @@ -550,7 +550,7 @@ ;; CHECK-NEXT: (local $2 (ref null $struct)) ;; CHECK-NEXT: (local $3 (ref null $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -581,7 +581,7 @@ ;; CHECK-NEXT: (local $4 (ref null $struct)) ;; CHECK-NEXT: (local $5 (ref null $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -623,7 +623,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -657,7 +657,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 8b0384671c3..619a33a23c5 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -50,7 +50,7 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -74,7 +74,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -102,7 +102,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -135,7 +135,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -162,7 +162,7 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -193,7 +193,7 @@ ;; CHECK-NEXT: (local $5 i32) ;; CHECK-NEXT: (local $6 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) @@ -259,7 +259,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $5 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -318,7 +318,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -388,7 +388,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $struct.A)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (struct.new_default $struct.A) ;; CHECK-NEXT: ) @@ -418,7 +418,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -456,7 +456,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -494,7 +494,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -559,7 +559,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -673,7 +673,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -713,7 +713,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -771,7 +771,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -821,7 +821,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -901,7 +901,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -927,7 +927,7 @@ ;; CHECK-NEXT: (local $ref (ref null $struct.recursive)) ;; CHECK-NEXT: (local $1 (ref null $struct.recursive)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -975,7 +975,7 @@ ;; CHECK-NEXT: (local $1 (ref null $struct.recursive)) ;; CHECK-NEXT: (local $2 (ref null $struct.recursive)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (struct.new_default $struct.recursive) ;; CHECK-NEXT: ) @@ -1070,7 +1070,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref $struct.A)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (local.get $a) ;; CHECK-NEXT: ) @@ -1104,7 +1104,7 @@ ;; CHECK-NEXT: (local $5 f64) ;; CHECK-NEXT: (loop $outer ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) @@ -1271,7 +1271,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1287,7 +1287,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1303,7 +1303,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1343,7 +1343,7 @@ ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (local $4 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1362,7 +1362,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1411,7 +1411,7 @@ ;; CHECK-NEXT: (local $4 i32) ;; CHECK-NEXT: (local $5 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1422,7 +1422,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1553,7 +1553,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1749,7 +1749,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1800,7 +1800,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1851,7 +1851,7 @@ ;; CHECK-NEXT: (block $block (result (ref null $struct.A)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $block - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) @@ -1905,7 +1905,7 @@ ;; CHECK-NEXT: (br_if $loop ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1938,7 +1938,7 @@ ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -1977,7 +1977,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2061,7 +2061,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2096,7 +2096,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2138,7 +2138,7 @@ ;; CHECK-NEXT: (local.get $other) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2174,7 +2174,7 @@ ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (local $4 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2216,7 +2216,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2253,7 +2253,7 @@ ;; CHECK-NEXT: (local $3 f64) ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2287,7 +2287,7 @@ ;; CHECK-NEXT: (local $4 i32) ;; CHECK-NEXT: (local $5 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2334,7 +2334,7 @@ ;; CHECK-NEXT: (local $6 i32) ;; CHECK-NEXT: (local $7 f64) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2351,7 +2351,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -2396,7 +2396,7 @@ ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.is_null - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2450,7 +2450,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2472,7 +2472,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $6 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -2494,7 +2494,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $10 ;; CHECK-NEXT: (i32.const 3) ;; CHECK-NEXT: ) @@ -2560,7 +2560,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2582,7 +2582,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $7 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) @@ -2648,7 +2648,7 @@ ;; CHECK-NEXT: (ref.cast (ref $B) ;; CHECK-NEXT: (block (result (ref $A)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) @@ -2697,7 +2697,7 @@ ;; CHECK-NEXT: (local $2 (ref $A)) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) @@ -2736,7 +2736,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) @@ -2776,7 +2776,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (struct.new $A ;; CHECK-NEXT: (ref.null none) @@ -2819,9 +2819,9 @@ ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) - ;; CHECK-NEXT: (block (result (exact nullref)) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -2870,7 +2870,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -2907,7 +2907,7 @@ ;; CHECK-NEXT: (struct.new_default $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $2 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -3005,7 +3005,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -3151,7 +3151,7 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -3197,7 +3197,7 @@ ;; CHECK-NEXT: (local $4 i32) ;; CHECK-NEXT: (local $5 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (call $get-i32) ;; CHECK-NEXT: ) @@ -3327,11 +3327,11 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -3391,7 +3391,7 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (call $get-i32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3500,7 +3500,7 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (call $get-i32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3512,7 +3512,7 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (call $get-i32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -3533,7 +3533,7 @@ ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (call $get-i32) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $24 ;; CHECK-NEXT: (local.get $4) ;; CHECK-NEXT: ) @@ -3706,7 +3706,7 @@ ;; CHECK: (func $array.nested.refinalize.get (type $3) (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3726,7 +3726,7 @@ ;; CHECK: (func $array.nested.refinalize.set (type $2) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -3756,7 +3756,7 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -3849,7 +3849,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -3867,7 +3867,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -3916,7 +3916,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -3983,7 +3983,7 @@ ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4030,7 +4030,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4070,7 +4070,7 @@ ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) @@ -4173,7 +4173,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -4253,7 +4253,7 @@ ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $3 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -4319,7 +4319,7 @@ ;; CHECK: (func $array.cast.struct (type $0) (result (ref struct)) ;; CHECK-NEXT: (local $eq (ref eq)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4341,7 +4341,7 @@ ;; CHECK: (func $array.cast.struct.null (type $3) (result structref) ;; CHECK-NEXT: (local $eq (ref eq)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4380,7 +4380,7 @@ ;; CHECK-NEXT: (local $eq (ref eq)) ;; CHECK-NEXT: (local $array (ref array)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4405,7 +4405,7 @@ ;; CHECK-NEXT: (local.tee $struct ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -4442,7 +4442,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result structref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) @@ -4513,7 +4513,7 @@ ;; CHECK-NEXT: (pop i32) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) @@ -4565,7 +4565,7 @@ ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (local.get $7) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4620,7 +4620,7 @@ ;; CHECK-NEXT: (local $0 (ref null $struct)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (ref null exact (shared none))) + ;; CHECK-NEXT: (block (result (ref null (shared none))) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) @@ -4666,7 +4666,7 @@ ;; CHECK-NEXT: (local $0 (ref null $struct)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (ref null exact (shared none))) + ;; CHECK-NEXT: (block (result (ref null (shared none))) ;; CHECK-NEXT: (local.set $1 ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/local-subtyping-exact.wast b/test/lit/passes/local-subtyping-exact.wast deleted file mode 100644 index 725c7d499fb..00000000000 --- a/test/lit/passes/local-subtyping-exact.wast +++ /dev/null @@ -1,39 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; Check that LocalSubtyping handles exact references properly when it -;; determines that a local that would otherwise be non-nullable must be nullable -;; because of control flow dominance constraints. - -;; RUN: wasm-opt %s -all --local-subtyping -S -o - | filecheck %s - -(module - ;; CHECK: (func $test (type $0) (param $0 (exact nullref)) (result anyref) - ;; CHECK-NEXT: (local $1 (exact nullref)) - ;; CHECK-NEXT: (if - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $1) - ;; CHECK-NEXT: ) - (func $test (param (exact nullref)) (result anyref) - (local (exact nullref)) - (if - (i32.const 0) - (then - (local.set 1 - ;; This would let the local be (ref exact none) if it dominated the get. - (ref.as_non_null - (local.get 0) - ) - ) - ) - ) - (local.get 1) - ) -) diff --git a/test/lit/passes/local-subtyping-nn.wast b/test/lit/passes/local-subtyping-nn.wast index f2237156f01..3754230d82f 100644 --- a/test/lit/passes/local-subtyping-nn.wast +++ b/test/lit/passes/local-subtyping-nn.wast @@ -8,7 +8,7 @@ (import "out" "i32" (func $i32 (result i32))) ;; CHECK: (func $non-nullable (type $1) - ;; CHECK-NEXT: (local $x (ref exact none)) + ;; CHECK-NEXT: (local $x (ref none)) ;; CHECK-NEXT: (local $y (ref $0)) ;; CHECK-NEXT: (local.set $x ;; CHECK-NEXT: (ref.as_non_null @@ -41,7 +41,7 @@ ) ;; CHECK: (func $uses-default (type $2) (param $i i32) - ;; CHECK-NEXT: (local $x (exact nullref)) + ;; CHECK-NEXT: (local $x nullref) ;; CHECK-NEXT: (if ;; CHECK-NEXT: (local.get $i) ;; CHECK-NEXT: (then diff --git a/test/lit/passes/local-subtyping.wast b/test/lit/passes/local-subtyping.wast index 777df93524f..795a0a01cd1 100644 --- a/test/lit/passes/local-subtyping.wast +++ b/test/lit/passes/local-subtyping.wast @@ -273,7 +273,7 @@ ) ;; CHECK: (func $multiple-iterations-refinalize-call-ref-bottom (type $0) - ;; CHECK-NEXT: (local $f (exact nullfuncref)) + ;; CHECK-NEXT: (local $f nullfuncref) ;; CHECK-NEXT: (local $x (ref none)) ;; CHECK-NEXT: (local.set $f ;; CHECK-NEXT: (ref.null nofunc) diff --git a/test/lit/passes/merge-blocks.wast b/test/lit/passes/merge-blocks.wast index 7a517ccbc27..86181f7a488 100644 --- a/test/lit/passes/merge-blocks.wast +++ b/test/lit/passes/merge-blocks.wast @@ -20,7 +20,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $label$1 (result i31ref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $label$1 (exact nullref) (ref exact none) + ;; CHECK-NEXT: (br_on_cast $label$1 nullref (ref none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/monomorphize-context.wast b/test/lit/passes/monomorphize-context.wast index 92b483a7ae1..7f9cb2f566e 100644 --- a/test/lit/passes/monomorphize-context.wast +++ b/test/lit/passes/monomorphize-context.wast @@ -277,7 +277,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (local.set $21 -;; ALWAYS-NEXT: (ref.cast (exact nullref) +;; ALWAYS-NEXT: (ref.cast nullref ;; ALWAYS-NEXT: (ref.null none) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) @@ -555,7 +555,7 @@ ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: (local.set $21 -;; ALWAYS-NEXT: (ref.cast (exact nullref) +;; ALWAYS-NEXT: (ref.cast nullref ;; ALWAYS-NEXT: (ref.null none) ;; ALWAYS-NEXT: ) ;; ALWAYS-NEXT: ) diff --git a/test/lit/passes/optimize-instructions-exact.wast b/test/lit/passes/optimize-instructions-exact.wast deleted file mode 100644 index 61769b78f34..00000000000 --- a/test/lit/passes/optimize-instructions-exact.wast +++ /dev/null @@ -1,33 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; Check that optimizations on casts involving exact reference types work -;; correctly. - -;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s - -(module - ;; CHECK: (func $cast-any-to-exact-none (type $0) (param $0 anyref) (result (exact nullref)) - ;; CHECK-NEXT: (ref.cast (exact nullref) - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $cast-any-to-exact-none (param anyref) (result (exact nullref)) - ;; This will not be changed, but should not trigger an assertion. - (ref.cast (exact nullref) - (local.get 0) - ) - ) - ;; CHECK: (func $cast-null-to-exact-none (type $1) (result (exact nullref)) - ;; CHECK-NEXT: (local $0 nullref) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: ) - (func $cast-null-to-exact-none (result (exact nullref)) - (local nullref) - (ref.cast (exact nullref) - (local.get 0) - ) - ) -) diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast index 3893e048e14..c930f2fc19a 100644 --- a/test/lit/passes/optimize-instructions-gc-tnh.wast +++ b/test/lit/passes/optimize-instructions-gc-tnh.wast @@ -509,7 +509,7 @@ ;; TNH-NEXT: ) ;; TNH-NEXT: (block ;; TNH-NEXT: (drop - ;; TNH-NEXT: (block (result (exact nullref)) + ;; TNH-NEXT: (block (result nullref) ;; TNH-NEXT: (drop ;; TNH-NEXT: (call $get-i32) ;; TNH-NEXT: ) @@ -532,7 +532,7 @@ ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (block ;; NO_TNH-NEXT: (drop - ;; NO_TNH-NEXT: (block (result (exact nullref)) + ;; NO_TNH-NEXT: (block (result nullref) ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (call $get-i32) ;; NO_TNH-NEXT: ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index 86804d7ddbd..4b88507ffc7 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -1570,7 +1570,7 @@ ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.tee $a ;; CHECK-NEXT: (ref.null none) @@ -1590,7 +1590,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.cast nullref diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 94adaa53fbb..fc4cc7c2ee9 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -28,7 +28,7 @@ ;; CHECK: (func $test-fallthrough (type $func-return-i32) (result i32) ;; CHECK-NEXT: (local $x funcref) ;; CHECK-NEXT: (local.set $x - ;; CHECK-NEXT: (block (result (exact nullfuncref)) + ;; CHECK-NEXT: (block (result nullfuncref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (call $test-fallthrough) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/remove-unused-brs-exact.wast b/test/lit/passes/remove-unused-brs-exact.wast deleted file mode 100644 index 3bebd07de02..00000000000 --- a/test/lit/passes/remove-unused-brs-exact.wast +++ /dev/null @@ -1,40 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; RUN: wasm-opt %s -all --remove-unused-brs -S -o - | filecheck %s - -;; Check that we optimize the cast correctly when the fallthrough has exact -;; type. In particular, we should not insert a ref.as_non_null, which would -;; trap. - -(module - ;; CHECK: (func $br_on_cast_fail (type $0) (param $0 (exact nullref)) - ;; CHECK-NEXT: (local $1 nullref) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast (exact nullref) - ;; CHECK-NEXT: (local.tee $1 - ;; CHECK-NEXT: (local.get $0) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $br_on_cast_fail (param (ref null exact none)) - (local $1 nullref) - (drop - (block $block (result (ref none)) - (drop - (br_on_cast_fail $block nullref nullref - (local.tee $1 - (local.get 0) - ) - ) - ) - (return) - ) - ) - ) -) diff --git a/test/lit/passes/remove-unused-brs-gc.wast b/test/lit/passes/remove-unused-brs-gc.wast index c26fe3a95ba..2ee6171cbcb 100644 --- a/test/lit/passes/remove-unused-brs-gc.wast +++ b/test/lit/passes/remove-unused-brs-gc.wast @@ -63,7 +63,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (br_on_non_null $block ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) @@ -119,7 +119,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (br_on_non_null $block ;; CHECK-NEXT: (ref.cast (ref null $struct) ;; CHECK-NEXT: (local.tee $any @@ -438,7 +438,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (br_on_non_null $block ;; CHECK-NEXT: (local.get $nullable-struct2) ;; CHECK-NEXT: ) @@ -507,7 +507,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (br_on_non_null $block ;; CHECK-NEXT: (local.tee $any ;; CHECK-NEXT: (local.get $nullable-struct2) @@ -653,7 +653,7 @@ ;; CHECK-NEXT: (if (result i32) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (then - ;; CHECK-NEXT: (ref.test (ref exact none) + ;; CHECK-NEXT: (ref.test (ref none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -663,13 +663,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (if (result (exact nullref)) + ;; CHECK-NEXT: (if (result nullref) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (then ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (else - ;; CHECK-NEXT: (ref.cast (exact nullref) + ;; CHECK-NEXT: (ref.cast nullref ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -681,7 +681,7 @@ ;; CHECK-NEXT: (then ;; CHECK-NEXT: (block $something (result (ref null $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (br_on_non_null $something ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) @@ -697,8 +697,8 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (select (result (exact nullref)) - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (select (result nullref) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (block $nothing ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block @@ -805,7 +805,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (select (result (exact nullref)) + ;; CHECK-NEXT: (select (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (local.get $x) diff --git a/test/lit/passes/remove-unused-types-exact.wast b/test/lit/passes/remove-unused-types-exact.wast deleted file mode 100644 index 6cb9c1ddd74..00000000000 --- a/test/lit/passes/remove-unused-types-exact.wast +++ /dev/null @@ -1,16 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. - -;; RUN: wasm-opt %s -all --closed-world --remove-unused-types -S -o - | filecheck %s - -;; Test that a simple type rewrite handles exact references in heap type -;; definitions correctly. In particular, the function should continue returning -;; an exact nullref and the call expression should have the same type. - -(module - ;; CHECK: (func $return-exact (type $0) (result (exact nullref)) - ;; CHECK-NEXT: (call $return-exact) - ;; CHECK-NEXT: ) - (func $return-exact (result (exact nullref)) - (call $return-exact) - ) -) diff --git a/test/lit/passes/signature-refining_gto.wat b/test/lit/passes/signature-refining_gto.wat index 1eedcd4f67c..c69eeb24455 100644 --- a/test/lit/passes/signature-refining_gto.wat +++ b/test/lit/passes/signature-refining_gto.wat @@ -9,11 +9,11 @@ ;; CHECK-NOT: (type $A (type $A (struct (field (mut (ref null $A))))) - ;; CHECK: (type $0 (func (param (ref exact none)))) + ;; CHECK: (type $0 (func (param (ref none)))) ;; CHECK: (type $1 (func (param funcref i32))) - ;; CHECK: (func $struct.get (type $0) (param $0 (ref exact none)) + ;; CHECK: (func $struct.get (type $0) (param $0 (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/ssa.wast b/test/lit/passes/ssa.wast index a0b18b0777d..0d696f75a0d 100644 --- a/test/lit/passes/ssa.wast +++ b/test/lit/passes/ssa.wast @@ -36,9 +36,9 @@ ;; CHECK: (func $refine-to-null (type $3) (result (ref $A)) ;; CHECK-NEXT: (local $0 (ref null $A)) - ;; CHECK-NEXT: (block $label (result (ref exact none)) + ;; CHECK-NEXT: (block $label (result (ref none)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (br_on_cast $label (exact nullref) (ref exact none) + ;; CHECK-NEXT: (br_on_cast $label nullref (ref none) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/type-refining-isorecursive.wast b/test/lit/passes/type-refining-isorecursive.wast index 025b8cec9f5..537f99e668e 100644 --- a/test/lit/passes/type-refining-isorecursive.wast +++ b/test/lit/passes/type-refining-isorecursive.wast @@ -5,11 +5,11 @@ ;; The types should be refined to a set of three mutually recursive types. ;; CHECK: (rec - ;; CHECK-NEXT: (type $2 (sub (struct (field (exact nullexternref)) (field (ref $0))))) + ;; CHECK-NEXT: (type $2 (sub (struct (field nullexternref) (field (ref $0))))) - ;; CHECK: (type $1 (sub (struct (field (exact nullfuncref)) (field (ref $2))))) + ;; CHECK: (type $1 (sub (struct (field nullfuncref) (field (ref $2))))) - ;; CHECK: (type $0 (sub (struct (field (exact nullref)) (field (ref $1))))) + ;; CHECK: (type $0 (sub (struct (field nullref) (field (ref $1))))) (type $0 (sub (struct nullref anyref))) (type $1 (sub (struct nullfuncref anyref))) (type $2 (sub (struct nullexternref anyref))) diff --git a/test/lit/passes/type-refining-rmw.wast b/test/lit/passes/type-refining-rmw.wast index 7739fceb0f4..a4bb0a85cae 100644 --- a/test/lit/passes/type-refining-rmw.wast +++ b/test/lit/passes/type-refining-rmw.wast @@ -6,7 +6,7 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $null (shared (struct (field (mut (ref null exact (shared none))))))) + ;; CHECK-NEXT: (type $null (shared (struct (field (mut (ref null (shared none))))))) (type $null (shared (struct (field (mut (ref null (shared any))))))) ;; CHECK: (type $i31 (shared (struct (field (mut (ref (shared i31))))))) @@ -75,7 +75,7 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $null (shared (struct (field (mut (ref null exact (shared none))))))) + ;; CHECK-NEXT: (type $null (shared (struct (field (mut (ref null (shared none))))))) (type $null (shared (struct (field (mut (ref null (shared eq))))))) ;; CHECK: (type $i31 (shared (struct (field (mut (ref (shared i31))))))) diff --git a/test/lit/passes/type-refining.wast b/test/lit/passes/type-refining.wast index 02357e8b6c0..622e7422011 100644 --- a/test/lit/passes/type-refining.wast +++ b/test/lit/passes/type-refining.wast @@ -1101,7 +1101,7 @@ ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (exact nullref)) + ;; CHECK-NEXT: (block (result nullref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1180,7 +1180,7 @@ (module (rec ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (struct (field (mut (exact nullref))))) + ;; CHECK-NEXT: (type $A (struct (field (mut nullref)))) (type $A (struct (field (mut anyref)))) ;; CHECK: (type $B (struct (field (mut nullref)))) (type $B (struct (field (mut (ref null $A))))) @@ -1234,7 +1234,7 @@ (module ;; CHECK: (rec - ;; CHECK-NEXT: (type $A (struct (field (mut (ref exact noextern))))) + ;; CHECK-NEXT: (type $A (struct (field (mut (ref noextern))))) (type $A (struct (field (mut externref)))) ;; CHECK: (type $1 (func)) @@ -1252,7 +1252,7 @@ ;; CHECK: (func $struct.new (type $2) (param $extern externref) (result anyref) ;; CHECK-NEXT: (struct.new $A - ;; CHECK-NEXT: (ref.cast (ref exact noextern) + ;; CHECK-NEXT: (ref.cast (ref noextern) ;; CHECK-NEXT: (try (result externref) ;; CHECK-NEXT: (do ;; CHECK-NEXT: (struct.get $A 0 @@ -1304,7 +1304,7 @@ ;; CHECK: (func $struct.set (type $3) (param $ref (ref $A)) (param $extern externref) ;; CHECK-NEXT: (struct.set $A 0 ;; CHECK-NEXT: (local.get $ref) - ;; CHECK-NEXT: (ref.cast (ref exact noextern) + ;; CHECK-NEXT: (ref.cast (ref noextern) ;; CHECK-NEXT: (try (result externref) ;; CHECK-NEXT: (do ;; CHECK-NEXT: (struct.get $A 0 @@ -1581,7 +1581,7 @@ (type $never (sub (struct (field i32)))) ;; CHECK: (rec - ;; CHECK-NEXT: (type $optimizable (struct (field (mut (exact nullfuncref))))) + ;; CHECK-NEXT: (type $optimizable (struct (field (mut nullfuncref)))) (type $optimizable (struct (field (mut (ref null func))))) ;; CHECK: (type $2 (func)) @@ -1604,7 +1604,7 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block (result (ref exact none)) + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (ref.as_non_null ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) diff --git a/test/passes/precompute_all-features.txt b/test/passes/precompute_all-features.txt index 1372035920f..189adadcec1 100644 --- a/test/passes/precompute_all-features.txt +++ b/test/passes/precompute_all-features.txt @@ -286,7 +286,7 @@ ) ) (drop - (block $l2 (result (exact nullexternref)) + (block $l2 (result nullexternref) (drop (block $l3 (global.set $global-mut