diff options
-rw-r--r-- | src/ir/module-utils.cpp | 139 | ||||
-rw-r--r-- | src/passes/Print.cpp | 35 | ||||
-rw-r--r-- | src/wasm-binary.h | 2 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 16 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 44 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 2 | ||||
-rw-r--r-- | test/lit/blocktype.wast | 99 | ||||
-rw-r--r-- | test/lit/multivalue.wast | 14 | ||||
-rw-r--r-- | test/lit/passes/coalesce-locals-gc.wast | 10 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-multivalue.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/poppify.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/remove-unused-brs.wast | 6 | ||||
-rw-r--r-- | test/lit/passes/roundtrip.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/tuple-optimization.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/type-merging.wast | 6 | ||||
-rw-r--r-- | test/lit/types-function-references.wast | 62 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 14 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_enable-multivalue.txt | 8 |
19 files changed, 337 insertions, 130 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 0da47e811..cd865a79c 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -230,10 +230,18 @@ void renameFunction(Module& wasm, Name oldName, Name newName) { namespace { // Helper for collecting HeapTypes and their frequencies. -struct Counts : public InsertOrderedMap<HeapType, size_t> { +struct Counts { + InsertOrderedMap<HeapType, size_t> counts; + + // Multivalue control flow structures need a function type, but the identity + // of the function type (i.e. what recursion group it is in or whether it is + // final) doesn't matter. Save them for the end to see if we can re-use an + // existing function type with the necessary signature. + InsertOrderedMap<Signature, size_t> controlFlowSignatures; + void note(HeapType type) { if (!type.isBasic()) { - (*this)[type]++; + counts[type]++; } } void note(Type type) { @@ -244,7 +252,7 @@ struct Counts : public InsertOrderedMap<HeapType, size_t> { // Ensure a type is included without increasing its count. void include(HeapType type) { if (!type.isBasic()) { - (*this)[type]; + counts[type]; } } void include(Type type) { @@ -252,6 +260,18 @@ struct Counts : public InsertOrderedMap<HeapType, size_t> { include(ht); } } + void noteControlFlow(Signature sig) { + // TODO: support control flow input parameters. + assert(sig.params.size() == 0); + if (sig.results.isTuple()) { + // We have to use a function type. + controlFlowSignatures[sig]++; + } else if (sig.results != Type::none) { + // The result type can be emitted directly instead of using a function + // type. + note(sig.results[0]); + } + } }; struct CodeScanner @@ -319,12 +339,7 @@ struct CodeScanner } else if (auto* set = curr->dynCast<ArraySet>()) { counts.note(set->ref->type); } else if (Properties::isControlFlowStructure(curr)) { - if (curr->type.isTuple()) { - // TODO: Allow control flow to have input types as well - counts.note(Signature(Type::none, curr->type)); - } else { - counts.note(curr->type); - } + counts.noteControlFlow(Signature(Type::none, curr->type)); } } }; @@ -332,7 +347,8 @@ struct CodeScanner // Count the number of times each heap type that would appear in the binary is // referenced. If `prune`, exclude types that are never referenced, even though // a binary would be invalid without them. -Counts getHeapTypeCounts(Module& wasm, bool prune = false) { +InsertOrderedMap<HeapType, size_t> getHeapTypeCounts(Module& wasm, + bool prune = false) { // Collect module-level info. Counts counts; CodeScanner(wasm, counts).walkModuleCode(&wasm); @@ -363,18 +379,21 @@ Counts getHeapTypeCounts(Module& wasm, bool prune = false) { // Combine the function info with the module info. for (auto& [_, functionCounts] : analysis.map) { - for (auto& [sig, count] : functionCounts) { - counts[sig] += count; + for (auto& [type, count] : functionCounts.counts) { + counts.counts[type] += count; + } + for (auto& [sig, count] : functionCounts.controlFlowSignatures) { + counts.controlFlowSignatures[sig] += count; } } if (prune) { // Remove types that are not actually used. - auto it = counts.begin(); - while (it != counts.end()) { + auto it = counts.counts.begin(); + while (it != counts.counts.end()) { if (it->second == 0) { auto deleted = it++; - counts.erase(deleted); + counts.counts.erase(deleted); } else { ++it; } @@ -388,50 +407,75 @@ Counts getHeapTypeCounts(Module& wasm, bool prune = false) { // appear in the type section once, so we just need to visit it once. Also // track which recursion groups we've already processed to avoid quadratic // behavior when there is a single large group. - InsertOrderedSet<HeapType> newTypes; - for (auto& [type, _] : counts) { - newTypes.insert(type); + UniqueNonrepeatingDeferredQueue<HeapType> newTypes; + std::unordered_map<Signature, HeapType> seenSigs; + auto noteNewType = [&](HeapType type) { + newTypes.push(type); + if (type.isSignature()) { + seenSigs.insert({type.getSignature(), type}); + } + }; + for (auto& [type, _] : counts.counts) { + noteNewType(type); } + auto controlFlowIt = counts.controlFlowSignatures.begin(); std::unordered_set<RecGroup> includedGroups; while (!newTypes.empty()) { - auto iter = newTypes.begin(); - auto ht = *iter; - newTypes.erase(iter); - for (HeapType child : ht.getHeapTypeChildren()) { - if (!child.isBasic()) { - if (!counts.count(child)) { - newTypes.insert(child); + while (!newTypes.empty()) { + auto ht = newTypes.pop(); + for (HeapType child : ht.getHeapTypeChildren()) { + if (!child.isBasic()) { + if (!counts.counts.count(child)) { + noteNewType(child); + } + counts.note(child); } - counts.note(child); } - } - if (auto super = ht.getDeclaredSuperType()) { - if (!counts.count(*super)) { - newTypes.insert(*super); - // We should unconditionally count supertypes, but while the type system - // is in flux, skip counting them to keep the type orderings in nominal - // test outputs more similar to the orderings in the equirecursive - // outputs. FIXME - counts.include(*super); + if (auto super = ht.getDeclaredSuperType()) { + if (!counts.counts.count(*super)) { + noteNewType(*super); + // We should unconditionally count supertypes, but while the type + // system is in flux, skip counting them to keep the type orderings in + // nominal test outputs more similar to the orderings in the + // equirecursive outputs. FIXME + counts.include(*super); + } } - } - // Make sure we've noted the complete recursion group of each type as well. - if (!prune) { - auto recGroup = ht.getRecGroup(); - if (includedGroups.insert(recGroup).second) { - for (auto type : recGroup) { - if (!counts.count(type)) { - newTypes.insert(type); - counts.include(type); + // Make sure we've noted the complete recursion group of each type as + // well. + if (!prune) { + auto recGroup = ht.getRecGroup(); + if (includedGroups.insert(recGroup).second) { + for (auto type : recGroup) { + if (!counts.counts.count(type)) { + noteNewType(type); + counts.include(type); + } } } } } + + // We've found all the types there are to find without considering more + // control flow types. Consider one more control flow type and repeat. + for (; controlFlowIt != counts.controlFlowSignatures.end(); + ++controlFlowIt) { + auto& [sig, count] = *controlFlowIt; + if (auto it = seenSigs.find(sig); it != seenSigs.end()) { + counts.counts[it->second] += count; + } else { + // We've never seen this signature before, so add a type for it. + HeapType type(sig); + noteNewType(type); + counts.counts[type] += count; + break; + } + } } - return counts; + return counts.counts; } void setIndices(IndexedHeapTypes& indexedTypes) { @@ -561,12 +605,11 @@ std::vector<HeapType> getPrivateHeapTypes(Module& wasm) { } IndexedHeapTypes getOptimizedIndexedHeapTypes(Module& wasm) { - Counts counts = getHeapTypeCounts(wasm); + auto counts = getHeapTypeCounts(wasm); // Types have to be arranged into topologically ordered recursion groups. // Under isorecrsive typing, the topological sort has to take all referenced - // rec groups into account but under nominal typing it only has to take - // supertypes into account. First, sort the groups by average use count among + // rec groups into account. First, sort the groups by average use count among // their members so that the later topological sort will place frequently used // types first. struct GroupInfo { diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index edbb136a3..51d261126 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -169,6 +169,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { int controlFlowDepth = 0; std::vector<HeapType> heapTypes; + std::unordered_map<Signature, HeapType> signatureTypes; // Track the print indent so that we can see when it changes. That affects how // we print debug annotations. In particular, we don't want to print repeated @@ -242,6 +243,22 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { return printPrefixedTypes("param", type); } + std::ostream& printBlockType(Signature sig) { + assert(sig.params == Type::none); + if (sig.results == Type::none) { + return o; + } + if (sig.results.isTuple()) { + if (auto it = signatureTypes.find(sig); it != signatureTypes.end()) { + o << "(type "; + printHeapType(it->second); + o << ") "; + } + } + printResultType(sig.results); + return o; + } + void printDebugLocation(const Function::DebugLocation& location); void printDebugLocation(Expression* curr); @@ -370,6 +387,10 @@ struct PrintExpressionContents return parent.printParamType(type); } + std::ostream& printBlockType(Signature sig) { + return parent.printBlockType(sig); + } + void visitBlock(Block* curr) { printMedium(o, "block"); if (curr->name.is()) { @@ -378,14 +399,14 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitIf(If* curr) { printMedium(o, "if"); if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitLoop(Loop* curr) { @@ -396,7 +417,7 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitBreak(Break* curr) { @@ -1937,7 +1958,7 @@ struct PrintExpressionContents } if (curr->type.isConcrete()) { o << ' '; - printResultType(curr->type); + printBlockType(Signature(Type::none, curr->type)); } } void visitThrow(Throw* curr) { @@ -2369,8 +2390,14 @@ void PrintSExpression::setModule(Module* module) { currModule = module; if (module) { heapTypes = ModuleUtils::getOptimizedIndexedHeapTypes(*module).types; + for (auto type : heapTypes) { + if (type.isSignature()) { + signatureTypes.insert({type.getSignature(), type}); + } + } } else { heapTypes = {}; + signatureTypes = {}; } // Reset the type printer for this module's types (or absence thereof). typePrinter.~TypePrinter(); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 8a4d6969f..ee92fe90e 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1422,6 +1422,7 @@ public: uint32_t getDataSegmentIndex(Name name) const; uint32_t getElementSegmentIndex(Name name) const; uint32_t getTypeIndex(HeapType type) const; + uint32_t getSignatureIndex(Signature sig) const; uint32_t getStringIndex(Name string) const; void writeTableDeclarations(); @@ -1476,6 +1477,7 @@ private: BufferWithRandomAccess& o; BinaryIndexes indexes; ModuleUtils::IndexedHeapTypes indexedTypes; + std::unordered_map<Signature, uint32_t> signatureIndexes; bool debugInfo = true; diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index a2faea771..6853f2c01 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -327,7 +327,7 @@ private: Expression* makeStringSliceIter(Element& s); // Helper functions - Type parseOptionalResultType(Element& s, Index& i); + Type parseBlockType(Element& s, Index& i); Index parseMemoryLimits(Element& s, Index i, std::unique_ptr<Memory>& memory); Index parseMemoryIndex(Element& s, Index i, std::unique_ptr<Memory>& memory); Index parseMemoryForInstruction(const std::string& instrName, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 2b96e839c..b12cb50c7 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -35,6 +35,11 @@ void WasmBinaryWriter::prepare() { // Collect function types and their frequencies. Collect information in each // function in parallel, then merge. indexedTypes = ModuleUtils::getOptimizedIndexedHeapTypes(*wasm); + for (Index i = 0, size = indexedTypes.types.size(); i < size; ++i) { + if (indexedTypes.types[i].isSignature()) { + signatureIndexes.insert({indexedTypes.types[i].getSignature(), i}); + } + } importInfo = std::make_unique<ImportInfo>(*wasm); } @@ -686,6 +691,17 @@ uint32_t WasmBinaryWriter::getTypeIndex(HeapType type) const { return it->second; } +uint32_t WasmBinaryWriter::getSignatureIndex(Signature sig) const { + auto it = signatureIndexes.find(sig); +#ifndef NDEBUG + if (it == signatureIndexes.end()) { + std::cout << "Missing signature: " << sig << '\n'; + assert(0); + } +#endif + return it->second; +} + uint32_t WasmBinaryWriter::getStringIndex(Name string) const { auto it = stringIndexes.find(string); assert(it != stringIndexes.end()); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 215d349e1..4074e4792 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1445,7 +1445,7 @@ Expression* SExpressionWasmBuilder::makeUnary(Element& s, UnaryOp op) { Expression* SExpressionWasmBuilder::makeSelect(Element& s) { auto ret = allocator.alloc<Select>(); Index i = 1; - Type type = parseOptionalResultType(s, i); + Type type = parseBlockType(s, i); ret->ifTrue = parseExpression(s[i++]); ret->ifFalse = parseExpression(s[i++]); ret->condition = parseExpression(s[i]); @@ -1603,7 +1603,7 @@ Expression* SExpressionWasmBuilder::makeBlock(Element& s) { stack.emplace_back(Info{sp, curr, hadName}); curr->name = nameMapper.pushLabelName(sName); // block signature - curr->type = parseOptionalResultType(s, i); + curr->type = parseBlockType(s, i); if (i >= s.size()) { break; // empty block } @@ -1630,7 +1630,8 @@ Expression* SExpressionWasmBuilder::makeBlock(Element& s) { while (i < s.size() && s[i]->isStr()) { i++; } - if (i < s.size() && elementStartsWith(*s[i], RESULT)) { + while (i < s.size() && (elementStartsWith(*s[i], RESULT) || + elementStartsWith(*s[i], TYPE))) { i++; } if (t < int(stack.size()) - 1) { @@ -2370,7 +2371,7 @@ Expression* SExpressionWasmBuilder::makeIf(Element& s) { } auto label = nameMapper.pushLabelName(sName); // if signature - Type type = parseOptionalResultType(s, i); + Type type = parseBlockType(s, i); ret->condition = parseExpression(s[i++]); ret->ifTrue = parseExpression(*s[i++]); if (i < s.size()) { @@ -2409,7 +2410,7 @@ SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, Type type) { return ret; } -Type SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { +Type SExpressionWasmBuilder::parseBlockType(Element& s, Index& i) { if (s.size() == i) { return Type::none; } @@ -2420,11 +2421,34 @@ Type SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { return stringToType(s[i++]->str()); } - Element& results = *s[i]; - IString id = results[0]->str(); + Element* results = s[i]; + IString id = (*results)[0]->str(); + std::optional<Signature> usedType; + if (id == TYPE) { + auto type = parseHeapType(*(*results)[1]); + if (!type.isSignature()) { + throw SParseException("unexpected non-function type", s); + } + usedType = type.getSignature(); + if (usedType->params != Type::none) { + throw SParseException("block input values are not yet supported", s); + } + i++; + results = s[i]; + id = (*results)[0]->str(); + } + if (id == RESULT) { i++; - return Type(parseResults(results)); + auto type = Type(parseResults(*results)); + if (usedType && usedType->results != type) { + throw SParseException("results do not match type", s); + } + return type; + } + + if (usedType && usedType->results != Type::none) { + throw SParseException("results do not match type", s); } return Type::none; } @@ -2439,7 +2463,7 @@ Expression* SExpressionWasmBuilder::makeLoop(Element& s) { sName = "loop-in"; } ret->name = nameMapper.pushLabelName(sName); - ret->type = parseOptionalResultType(s, i); + ret->type = parseBlockType(s, i); ret->body = makeMaybeBlock(s, i, ret->type); nameMapper.popLabelName(ret->name); ret->finalize(ret->type); @@ -2690,7 +2714,7 @@ Expression* SExpressionWasmBuilder::makeTry(Element& s) { sName = "try"; } ret->name = nameMapper.pushLabelName(sName); - Type type = parseOptionalResultType(s, i); // signature + Type type = parseBlockType(s, i); // signature if (!elementStartsWith(*s[i], "do")) { throw SParseException("try body should start with 'do'", s, *s[i]); diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 1f1141821..1d2363be3 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -26,7 +26,7 @@ void BinaryInstWriter::emitResultType(Type type) { if (type == Type::unreachable) { parent.writeType(Type::none); } else if (type.isTuple()) { - o << S32LEB(parent.getTypeIndex(Signature(Type::none, type))); + o << S32LEB(parent.getSignatureIndex(Signature(Type::none, type))); } else { parent.writeType(type); } diff --git a/test/lit/blocktype.wast b/test/lit/blocktype.wast new file mode 100644 index 000000000..61eba4868 --- /dev/null +++ b/test/lit/blocktype.wast @@ -0,0 +1,99 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: wasm-opt %s -all -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --roundtrip -g -S -o - | filecheck %s --check-prefix=RTRIP + +(module + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $f1 (func (result (ref $f1) (ref $f2)))) + ;; RTRIP: (rec + ;; RTRIP-NEXT: (type $f1 (func (result (ref $f1) (ref $f2)))) + (type $f1 (func (result (ref $f1) (ref $f2)))) + ;; CHECK: (type $f2 (func (result (ref $f2) (ref $f1)))) + ;; RTRIP: (type $f2 (func (result (ref $f2) (ref $f1)))) + (type $f2 (func (result (ref $f2) (ref $f1)))) + ) + + ;; These types will be optimized out. + (type $block1 (func (result (ref $f1) (ref $f2)))) + (type $block2 (func (result (ref $f2) (ref $f1)))) + + ;; CHECK: (func $f1 (type $f1) (result (ref $f1) (ref $f2)) + ;; CHECK-NEXT: (loop $l (type $f1) (result (ref $f1) (ref $f2)) + ;; CHECK-NEXT: (call $f1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; RTRIP: (func $f1 (type $f1) (result (ref $f1) (ref $f2)) + ;; RTRIP-NEXT: (local $0 ((ref $f1) (ref $f2))) + ;; RTRIP-NEXT: (local $1 ((ref $f1) (ref $f2))) + ;; RTRIP-NEXT: (local.set $1 + ;; RTRIP-NEXT: (loop $label$1 (type $f1) (result (ref $f1) (ref $f2)) + ;; RTRIP-NEXT: (local.set $0 + ;; RTRIP-NEXT: (call $f1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.make + ;; RTRIP-NEXT: (tuple.extract 0 + ;; RTRIP-NEXT: (local.get $0) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.extract 1 + ;; RTRIP-NEXT: (local.get $0) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.make + ;; RTRIP-NEXT: (tuple.extract 0 + ;; RTRIP-NEXT: (local.get $1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.extract 1 + ;; RTRIP-NEXT: (local.get $1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + (func $f1 (type $f1) (result (ref $f1) (ref $f2)) + ;; This block will be emitted with type $f1 + (loop $l (type $block1) (result (ref $f1) (ref $f2)) + (call $f1) + ) + ) + + ;; CHECK: (func $f2 (type $f2) (result (ref $f2) (ref $f1)) + ;; CHECK-NEXT: (loop $l (type $f2) (result (ref $f2) (ref $f1)) + ;; CHECK-NEXT: (call $f2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; RTRIP: (func $f2 (type $f2) (result (ref $f2) (ref $f1)) + ;; RTRIP-NEXT: (local $0 ((ref $f2) (ref $f1))) + ;; RTRIP-NEXT: (local $1 ((ref $f2) (ref $f1))) + ;; RTRIP-NEXT: (local.set $1 + ;; RTRIP-NEXT: (loop $label$1 (type $f2) (result (ref $f2) (ref $f1)) + ;; RTRIP-NEXT: (local.set $0 + ;; RTRIP-NEXT: (call $f2) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.make + ;; RTRIP-NEXT: (tuple.extract 0 + ;; RTRIP-NEXT: (local.get $0) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.extract 1 + ;; RTRIP-NEXT: (local.get $0) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.make + ;; RTRIP-NEXT: (tuple.extract 0 + ;; RTRIP-NEXT: (local.get $1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: (tuple.extract 1 + ;; RTRIP-NEXT: (local.get $1) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + ;; RTRIP-NEXT: ) + (func $f2 (type $f2) (result (ref $f2) (ref $f1)) + ;; This block will be emitted with type $f2 + (loop $l (type $block2) (result (ref $f2) (ref $f1)) + (call $f2) + ) + ) +) diff --git a/test/lit/multivalue.wast b/test/lit/multivalue.wast index 0d52f5382..a4b5c6b7e 100644 --- a/test/lit/multivalue.wast +++ b/test/lit/multivalue.wast @@ -320,7 +320,7 @@ ;; CHECK-NEXT: (local $0 (i32 i64)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (block $label$1 (result i32 i64) + ;; CHECK-NEXT: (block $label$1 (type $0) (result i32 i64) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: (i64.const 42) @@ -394,7 +394,7 @@ ;; CHECK: (func $mv-block-break (type $0) (result i32 i64) ;; CHECK-NEXT: (local $0 (i32 i64)) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (block $label$1 (result i32 i64) + ;; CHECK-NEXT: (block $label$1 (type $0) (result i32 i64) ;; CHECK-NEXT: (br $label$1 ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 42) @@ -427,7 +427,7 @@ ;; CHECK-NEXT: (local $0 (i32 i64)) ;; CHECK-NEXT: (local $1 (i32 i64)) ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (block $label$1 (result i32 i64) + ;; CHECK-NEXT: (block $label$1 (type $0) (result i32 i64) ;; CHECK-NEXT: (local.set $0 ;; CHECK-NEXT: (br_if $label$1 ;; CHECK-NEXT: (tuple.make @@ -471,7 +471,7 @@ ;; CHECK: (func $mv-if (type $2) (result i32 i64 externref) ;; CHECK-NEXT: (local $0 (i32 i64 externref)) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (if (result i32 i64 externref) + ;; CHECK-NEXT: (if (type $2) (result i32 i64 externref) ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 42) @@ -516,7 +516,7 @@ ;; CHECK: (func $mv-loop (type $0) (result i32 i64) ;; CHECK-NEXT: (local $0 (i32 i64)) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (loop $label$1 (result i32 i64) + ;; CHECK-NEXT: (loop $label$1 (type $0) (result i32 i64) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 42) ;; CHECK-NEXT: (i64.const 42) @@ -545,9 +545,9 @@ ;; CHECK-NEXT: (local $0 (i32 i64)) ;; CHECK-NEXT: (local $1 (i32 i64)) ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (block $label$1 (result i32 i64) + ;; CHECK-NEXT: (block $label$1 (type $0) (result i32 i64) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (block $label$2 (result i32 i64) + ;; CHECK-NEXT: (block $label$2 (type $0) (result i32 i64) ;; CHECK-NEXT: (br_table $label$1 $label$2 ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 42) diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast index 3706dc61f..5122fc23b 100644 --- a/test/lit/passes/coalesce-locals-gc.wast +++ b/test/lit/passes/coalesce-locals-gc.wast @@ -79,7 +79,7 @@ ) ) - ;; CHECK: (func $nn-dead (type $2) + ;; CHECK: (func $nn-dead (type $3) ;; CHECK-NEXT: (local $0 funcref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $nn-dead) @@ -118,7 +118,7 @@ ) ) - ;; CHECK: (func $nn-dead-nameless (type $2) + ;; CHECK: (func $nn-dead-nameless (type $3) ;; CHECK-NEXT: (local $0 (ref func)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $nn-dead) @@ -149,7 +149,7 @@ ) ) - ;; CHECK: (func $unreachable-get-null (type $2) + ;; CHECK: (func $unreachable-get-null (type $3) ;; CHECK-NEXT: (local $0 anyref) ;; CHECK-NEXT: (local $1 i31ref) ;; CHECK-NEXT: (unreachable) @@ -307,9 +307,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (global.set $nn-tuple-global - ;; CHECK-NEXT: (block (result (ref any) i32) + ;; CHECK-NEXT: (block (type $1) (result (ref any) i32) ;; CHECK-NEXT: (local.set $1 - ;; CHECK-NEXT: (if (result (ref any) i32) + ;; CHECK-NEXT: (if (type $1) (result (ref any) i32) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (ref.as_non_null diff --git a/test/lit/passes/optimize-instructions-multivalue.wast b/test/lit/passes/optimize-instructions-multivalue.wast index 0e7938417..1e456f20f 100644 --- a/test/lit/passes/optimize-instructions-multivalue.wast +++ b/test/lit/passes/optimize-instructions-multivalue.wast @@ -6,7 +6,7 @@ ;; CHECK-NEXT: (local $tuple (i32 i32)) ;; CHECK-NEXT: (local $tuple2 (i32 i32)) ;; CHECK-NEXT: (tuple.extract 0 - ;; CHECK-NEXT: (if (result i32 i32) + ;; CHECK-NEXT: (if (type $2) (result i32 i32) ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: (local.get $tuple) ;; CHECK-NEXT: (local.get $tuple2) diff --git a/test/lit/passes/poppify.wast b/test/lit/passes/poppify.wast index 9432cbd28..4aa44a3d5 100644 --- a/test/lit/passes/poppify.wast +++ b/test/lit/passes/poppify.wast @@ -466,7 +466,7 @@ ) ;; CHECK: (func $break-tuple (type $1) (result i32 i64) - ;; CHECK-NEXT: (block $l (result i32 i64) + ;; CHECK-NEXT: (block $l (type $1) (result i32 i64) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i64.const 1) ;; CHECK-NEXT: (br $l diff --git a/test/lit/passes/remove-unused-brs.wast b/test/lit/passes/remove-unused-brs.wast index 93cf4cbd2..8392dfe86 100644 --- a/test/lit/passes/remove-unused-brs.wast +++ b/test/lit/passes/remove-unused-brs.wast @@ -5,7 +5,7 @@ (module ;; Regression test in which we need to calculate a proper LUB. - ;; CHECK: (func $selectify-fresh-lub (type $2) (param $x i32) (result anyref) + ;; CHECK: (func $selectify-fresh-lub (type $3) (param $x i32) (result anyref) ;; CHECK-NEXT: (select (result i31ref) ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: (ref.i31 @@ -211,7 +211,7 @@ ) ) - ;; CHECK: (func $get-i32 (type $3) (result i32) + ;; CHECK: (func $get-i32 (type $4) (result i32) ;; CHECK-NEXT: (i32.const 400) ;; CHECK-NEXT: ) (func $get-i32 (result i32) @@ -327,7 +327,7 @@ ;; CHECK: (func $restructure-select-no-multivalue (type $1) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $block (result i32 i32) + ;; CHECK-NEXT: (block $block (type $2) (result i32 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (br_if $block ;; CHECK-NEXT: (tuple.make diff --git a/test/lit/passes/roundtrip.wast b/test/lit/passes/roundtrip.wast index f41761c2e..2f3fd4009 100644 --- a/test/lit/passes/roundtrip.wast +++ b/test/lit/passes/roundtrip.wast @@ -8,7 +8,7 @@ ;; CHECK-NEXT: (local $0 (funcref (ref $none))) ;; CHECK-NEXT: (local $1 funcref) ;; CHECK-NEXT: (local.set $0 - ;; CHECK-NEXT: (block $label$1 (result funcref (ref $none)) + ;; CHECK-NEXT: (block $label$1 (type $1) (result funcref (ref $none)) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (ref.null nofunc) ;; CHECK-NEXT: (ref.func $foo) diff --git a/test/lit/passes/tuple-optimization.wast b/test/lit/passes/tuple-optimization.wast index 766f51e81..6884f95c5 100644 --- a/test/lit/passes/tuple-optimization.wast +++ b/test/lit/passes/tuple-optimization.wast @@ -546,7 +546,7 @@ ;; CHECK: (func $set-of-block (type $0) ;; CHECK-NEXT: (local $tuple (i32 i32)) ;; CHECK-NEXT: (local.set $tuple - ;; CHECK-NEXT: (block (result i32 i32) + ;; CHECK-NEXT: (block (type $1) (result i32 i32) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: (i32.const 2) diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast index 7c44fe8e2..34f156a2b 100644 --- a/test/lit/passes/type-merging.wast +++ b/test/lit/passes/type-merging.wast @@ -929,8 +929,6 @@ ;; CHECK: (rec ;; CHECK-NEXT: (type $B (sub (func))) - ;; CHECK: (type $1 (func (result (ref any) (ref $B)))) - ;; CHECK: (type $A (sub (func (result (ref any) (ref $B))))) (type $A (sub (func (result (ref any) (ref $C))))) (type $B (sub (func))) @@ -939,10 +937,8 @@ (type $D (sub final $A (func (result (ref any) (ref $C))))) ) - ;; CHECK: (type $4 (func (result (ref any) (ref $B)))) - ;; CHECK: (func $test (type $D) (result (ref any) (ref $B)) - ;; CHECK-NEXT: (block $l (result (ref any) (ref $B)) + ;; CHECK-NEXT: (block $l (type $A) (result (ref any) (ref $B)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/types-function-references.wast b/test/lit/types-function-references.wast index c5f250f34..9479c93b3 100644 --- a/test/lit/types-function-references.wast +++ b/test/lit/types-function-references.wast @@ -22,22 +22,26 @@ (type $_=>_eqref (func (result eqref))) ;; CHECK-BINARY: (type $i32-i32 (func (param i32) (result i32))) - ;; CHECK-BINARY: (type $3 (func (param (ref $i32-i32)) (result i32))) + ;; CHECK-BINARY: (type $3 (func (result i32 (ref null $mixed_results) f64))) - ;; CHECK-BINARY: (type $4 (func (param (ref null $i32-i32)) (result i32))) + ;; CHECK-BINARY: (type $4 (func (param (ref $i32-i32)) (result i32))) - ;; CHECK-BINARY: (type $5 (func (result i32))) + ;; CHECK-BINARY: (type $5 (func (param (ref null $i32-i32)) (result i32))) + + ;; CHECK-BINARY: (type $6 (func (result i32))) ;; CHECK-BINARY: (type $=>eqref (func (result eqref))) ;; CHECK-BINARY: (type $f64_=>_ref_null<_->_eqref> (func (param f64) (result (ref null $=>eqref)))) ;; CHECK-TEXT: (type $i32-i32 (func (param i32) (result i32))) - ;; CHECK-TEXT: (type $3 (func (param (ref $i32-i32)) (result i32))) + ;; CHECK-TEXT: (type $3 (func (result i32 (ref null $mixed_results) f64))) + + ;; CHECK-TEXT: (type $4 (func (param (ref $i32-i32)) (result i32))) - ;; CHECK-TEXT: (type $4 (func (param (ref null $i32-i32)) (result i32))) + ;; CHECK-TEXT: (type $5 (func (param (ref null $i32-i32)) (result i32))) - ;; CHECK-TEXT: (type $5 (func (result i32))) + ;; CHECK-TEXT: (type $6 (func (result i32))) ;; CHECK-TEXT: (type $=>eqref (func (result eqref))) @@ -51,8 +55,6 @@ (type $i32-i32 (func (param i32) (result i32))) - ;; CHECK-BINARY: (type $9 (func (result i32 (ref null $mixed_results) f64))) - ;; CHECK-BINARY: (type $10 (func (param (ref null $mixed_results)))) ;; CHECK-BINARY: (elem declare func $call-ref $call-ref-more) @@ -62,8 +64,6 @@ ;; CHECK-BINARY-NEXT: (ref.func $call-ref) ;; CHECK-BINARY-NEXT: ) ;; CHECK-BINARY-NEXT: ) - ;; CHECK-TEXT: (type $9 (func (result i32 (ref null $mixed_results) f64))) - ;; CHECK-TEXT: (type $10 (func (param (ref null $mixed_results)))) ;; CHECK-TEXT: (elem declare func $call-ref $call-ref-more) @@ -104,13 +104,13 @@ (func $call-ref-more (param i32) (result i32) (call_ref $i32-i32 (i32.const 42) (ref.func $call-ref-more)) ) - ;; CHECK-BINARY: (func $call_from-param (type $3) (param $f (ref $i32-i32)) (result i32) + ;; CHECK-BINARY: (func $call_from-param (type $4) (param $f (ref $i32-i32)) (result i32) ;; CHECK-BINARY-NEXT: (call_ref $i32-i32 ;; CHECK-BINARY-NEXT: (i32.const 42) ;; CHECK-BINARY-NEXT: (local.get $f) ;; CHECK-BINARY-NEXT: ) ;; CHECK-BINARY-NEXT: ) - ;; CHECK-TEXT: (func $call_from-param (type $3) (param $f (ref $i32-i32)) (result i32) + ;; CHECK-TEXT: (func $call_from-param (type $4) (param $f (ref $i32-i32)) (result i32) ;; CHECK-TEXT-NEXT: (call_ref $i32-i32 ;; CHECK-TEXT-NEXT: (i32.const 42) ;; CHECK-TEXT-NEXT: (local.get $f) @@ -119,13 +119,13 @@ (func $call_from-param (param $f (ref $i32-i32)) (result i32) (call_ref $i32-i32 (i32.const 42) (local.get $f)) ) - ;; CHECK-BINARY: (func $call_from-param-null (type $4) (param $f (ref null $i32-i32)) (result i32) + ;; CHECK-BINARY: (func $call_from-param-null (type $5) (param $f (ref null $i32-i32)) (result i32) ;; CHECK-BINARY-NEXT: (call_ref $i32-i32 ;; CHECK-BINARY-NEXT: (i32.const 42) ;; CHECK-BINARY-NEXT: (local.get $f) ;; CHECK-BINARY-NEXT: ) ;; CHECK-BINARY-NEXT: ) - ;; CHECK-TEXT: (func $call_from-param-null (type $4) (param $f (ref null $i32-i32)) (result i32) + ;; CHECK-TEXT: (func $call_from-param-null (type $5) (param $f (ref null $i32-i32)) (result i32) ;; CHECK-TEXT-NEXT: (call_ref $i32-i32 ;; CHECK-TEXT-NEXT: (i32.const 42) ;; CHECK-TEXT-NEXT: (local.get $f) @@ -134,7 +134,7 @@ (func $call_from-param-null (param $f (ref null $i32-i32)) (result i32) (call_ref $i32-i32 (i32.const 42) (local.get $f)) ) - ;; CHECK-BINARY: (func $call_from-local-null (type $5) (result i32) + ;; CHECK-BINARY: (func $call_from-local-null (type $6) (result i32) ;; CHECK-BINARY-NEXT: (local $f (ref null $i32-i32)) ;; CHECK-BINARY-NEXT: (local.set $f ;; CHECK-BINARY-NEXT: (ref.func $call-ref-more) @@ -144,7 +144,7 @@ ;; CHECK-BINARY-NEXT: (local.get $f) ;; CHECK-BINARY-NEXT: ) ;; CHECK-BINARY-NEXT: ) - ;; CHECK-TEXT: (func $call_from-local-null (type $5) (result i32) + ;; CHECK-TEXT: (func $call_from-local-null (type $6) (result i32) ;; CHECK-TEXT-NEXT: (local $f (ref null $i32-i32)) ;; CHECK-TEXT-NEXT: (local.set $f ;; CHECK-TEXT-NEXT: (ref.func $call-ref-more) @@ -188,7 +188,7 @@ ;; CHECK-BINARY-NEXT: (local $1 (ref null $mixed_results)) ;; CHECK-BINARY-NEXT: (local $2 i32) ;; CHECK-BINARY-NEXT: (local.set $0 - ;; CHECK-BINARY-NEXT: (block $label$1 (result i32 (ref null $mixed_results) f64) + ;; CHECK-BINARY-NEXT: (block $label$1 (type $3) (result i32 (ref null $mixed_results) f64) ;; CHECK-BINARY-NEXT: (unreachable) ;; CHECK-BINARY-NEXT: ) ;; CHECK-BINARY-NEXT: ) @@ -223,7 +223,7 @@ ;; CHECK-TEXT-NEXT: (local $1 (ref null $mixed_results)) ;; CHECK-TEXT-NEXT: (local $2 i32) ;; CHECK-TEXT-NEXT: (local.set $0 - ;; CHECK-TEXT-NEXT: (block $label$1 (result i32 (ref null $mixed_results) f64) + ;; CHECK-TEXT-NEXT: (block $label$1 (type $3) (result i32 (ref null $mixed_results) f64) ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) @@ -380,19 +380,19 @@ ;; CHECK-NODEBUG: (type $2 (func (param i32) (result i32))) -;; CHECK-NODEBUG: (type $3 (func (param (ref $2)) (result i32))) +;; CHECK-NODEBUG: (type $3 (func (result i32 (ref null $0) f64))) -;; CHECK-NODEBUG: (type $4 (func (param (ref null $2)) (result i32))) +;; CHECK-NODEBUG: (type $4 (func (param (ref $2)) (result i32))) -;; CHECK-NODEBUG: (type $5 (func (result i32))) +;; CHECK-NODEBUG: (type $5 (func (param (ref null $2)) (result i32))) -;; CHECK-NODEBUG: (type $6 (func (result eqref))) +;; CHECK-NODEBUG: (type $6 (func (result i32))) -;; CHECK-NODEBUG: (type $7 (func (param f64) (result (ref null $6)))) +;; CHECK-NODEBUG: (type $7 (func (result eqref))) -;; CHECK-NODEBUG: (type $8 (func (result anyref))) +;; CHECK-NODEBUG: (type $8 (func (param f64) (result (ref null $7)))) -;; CHECK-NODEBUG: (type $9 (func (result i32 (ref null $0) f64))) +;; CHECK-NODEBUG: (type $9 (func (result anyref))) ;; CHECK-NODEBUG: (type $10 (func (param (ref null $0)))) @@ -417,21 +417,21 @@ ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG-NEXT: ) -;; CHECK-NODEBUG: (func $3 (type $3) (param $0 (ref $2)) (result i32) +;; CHECK-NODEBUG: (func $3 (type $4) (param $0 (ref $2)) (result i32) ;; CHECK-NODEBUG-NEXT: (call_ref $2 ;; CHECK-NODEBUG-NEXT: (i32.const 42) ;; CHECK-NODEBUG-NEXT: (local.get $0) ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG-NEXT: ) -;; CHECK-NODEBUG: (func $4 (type $4) (param $0 (ref null $2)) (result i32) +;; CHECK-NODEBUG: (func $4 (type $5) (param $0 (ref null $2)) (result i32) ;; CHECK-NODEBUG-NEXT: (call_ref $2 ;; CHECK-NODEBUG-NEXT: (i32.const 42) ;; CHECK-NODEBUG-NEXT: (local.get $0) ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG-NEXT: ) -;; CHECK-NODEBUG: (func $5 (type $5) (result i32) +;; CHECK-NODEBUG: (func $5 (type $6) (result i32) ;; CHECK-NODEBUG-NEXT: (local $0 (ref null $2)) ;; CHECK-NODEBUG-NEXT: (local.set $0 ;; CHECK-NODEBUG-NEXT: (ref.func $2) @@ -442,14 +442,14 @@ ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG-NEXT: ) -;; CHECK-NODEBUG: (func $6 (type $7) (param $0 f64) (result (ref null $6)) +;; CHECK-NODEBUG: (func $6 (type $8) (param $0 f64) (result (ref null $7)) ;; CHECK-NODEBUG-NEXT: (ref.null nofunc) ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG: (func $7 (type $1) ;; CHECK-NODEBUG-NEXT: (local $0 i32) ;; CHECK-NODEBUG-NEXT: (local $1 f64) -;; CHECK-NODEBUG-NEXT: (local $2 (ref null $8)) +;; CHECK-NODEBUG-NEXT: (local $2 (ref null $9)) ;; CHECK-NODEBUG-NEXT: (nop) ;; CHECK-NODEBUG-NEXT: ) @@ -458,7 +458,7 @@ ;; CHECK-NODEBUG-NEXT: (local $1 (ref null $0)) ;; CHECK-NODEBUG-NEXT: (local $2 i32) ;; CHECK-NODEBUG-NEXT: (local.set $0 -;; CHECK-NODEBUG-NEXT: (block $label$1 (result i32 (ref null $0) f64) +;; CHECK-NODEBUG-NEXT: (block $label$1 (type $3) (result i32 (ref null $0) f64) ;; CHECK-NODEBUG-NEXT: (unreachable) ;; CHECK-NODEBUG-NEXT: ) ;; CHECK-NODEBUG-NEXT: ) diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 8ef4f8d07..6b86d3e15 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -738,7 +738,7 @@ ;; CHECK: (func $block-folded (type $void) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block $l (result i32 i32) + ;; CHECK-NEXT: (block $l (type $ret2) (result i32 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (unreachable) @@ -766,7 +766,7 @@ ;; CHECK-NEXT: (local.set $scratch_2 ;; CHECK-NEXT: (block (result i32) ;; CHECK-NEXT: (local.set $scratch_1 - ;; CHECK-NEXT: (block $1 (result i32 i32) + ;; CHECK-NEXT: (block $1 (type $ret2) (result i32 i32) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (block $2 (result i32) ;; CHECK-NEXT: (local.set $scratch @@ -819,8 +819,8 @@ ;; CHECK-NEXT: (local $scratch (i32 i32)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: (local.set $scratch - ;; CHECK-NEXT: (block (result i32 i32) - ;; CHECK-NEXT: (block (result i32 i32) + ;; CHECK-NEXT: (block (type $ret2) (result i32 i32) + ;; CHECK-NEXT: (block (type $ret2) (result i32 i32) ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: (i32.const 1) @@ -1566,7 +1566,7 @@ ) ;; CHECK: (func $br-multivalue (type $7) (result i32 i64) - ;; CHECK-NEXT: (block $label (result i32 i64) + ;; CHECK-NEXT: (block $label (type $7) (result i32 i64) ;; CHECK-NEXT: (br $label ;; CHECK-NEXT: (tuple.make ;; CHECK-NEXT: (i32.const 0) @@ -1582,8 +1582,8 @@ ) ;; CHECK: (func $br-multivalue-drop (type $7) (result i32 i64) - ;; CHECK-NEXT: (block $label (result i32 i64) - ;; CHECK-NEXT: (block (result i32 i64) + ;; CHECK-NEXT: (block $label (type $7) (result i32 i64) + ;; CHECK-NEXT: (block (type $7) (result i32 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (f32.const 0) ;; CHECK-NEXT: ) diff --git a/test/passes/remove-unused-brs_enable-multivalue.txt b/test/passes/remove-unused-brs_enable-multivalue.txt index 0a66153e9..b85f1df8c 100644 --- a/test/passes/remove-unused-brs_enable-multivalue.txt +++ b/test/passes/remove-unused-brs_enable-multivalue.txt @@ -193,17 +193,17 @@ ) ) (func $b14-tuple (result i32 i64) - (if (result i32 i64) + (if (type $5) (result i32 i64) (i32.const 1) - (block $topmost (result i32 i64) - (block $block1 (result i32 i64) + (block $topmost (type $5) (result i32 i64) + (block $block1 (type $5) (result i32 i64) (tuple.make (i32.const 12) (i64.const 12) ) ) ) - (block $block3 (result i32 i64) + (block $block3 (type $5) (result i32 i64) (tuple.make (i32.const 27) (i64.const 27) |