diff options
-rw-r--r-- | src/wasm-interpreter.h | 15 | ||||
-rw-r--r-- | test/lit/passes/inlining-optimizing.wast | 41 |
2 files changed, 53 insertions, 3 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 844716f95..42bcbaebc 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1440,9 +1440,18 @@ public: if (cast.originalRef.isFunction()) { // Function casts are simple in that they have no RTT hierarchies; instead // each reference has the canonical RTT for the signature. - // We must have a module in order to perform the cast, to get the type. - assert(module); - auto* func = module->getFunction(cast.originalRef.getFunc()); + // We must have a module in order to perform the cast, to get the type. If + // we do not have one, or if the function is not present (which may happen + // if we are optimizing a function before the entire module is built), + // then this is not something we cannot precompute. + auto* func = module + ? module->getFunctionOrNull(cast.originalRef.getFunc()) + : nullptr; + if (!func) { + cast.outcome = cast.Break; + cast.breaking = NONCONSTANT_FLOW; + return cast; + } seenRtt = Literal(Type(Rtt(0, func->sig))); cast.castRef = Literal(func->name, Type(intendedRtt.type.getHeapType(), NonNullable)); diff --git a/test/lit/passes/inlining-optimizing.wast b/test/lit/passes/inlining-optimizing.wast new file mode 100644 index 000000000..bbbb385f8 --- /dev/null +++ b/test/lit/passes/inlining-optimizing.wast @@ -0,0 +1,41 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s -all --inlining-optimizing -S -o - | filecheck %s + +(module + (type $none_=>_none (func)) + (type $none_=>_i32 (func (result i32))) + ;; CHECK: (func $0 + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $0 + (nop) + ) + ;; CHECK: (func $1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_ref + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.func $0) + ;; CHECK-NEXT: (rtt.canon $none_=>_i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $1 + ;; $0 will be inlined into here. We will then optimize this function - but + ;; we do so *without* optimizing $0 (as inlining-optimizing only optimizes + ;; where it inlines, for efficiency). As part of the optimiziations, we will + ;; try to precompute the cast here, which will try to look up $0. We should + ;; not hit an assertion, rather we should skip precomputing it, the same as if + ;; we were optimizing $1 before $0 were added to the module. + (call $0) + (drop + (call_ref + (ref.cast + (ref.func $0) + (rtt.canon $none_=>_i32) + ) + ) + ) + ) +) + |