Skip to content

Commit 74e21a6

Browse files
authored
GUFA: Fix indirect return-call subtyping (#8536)
1 parent 9e623c7 commit 74e21a6

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

src/ir/possible-contents.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,11 @@ struct InfoCollector
876876
targetType, [&](HeapType subType, Index depth) {
877877
info.links.push_back({SignatureResultLocation{subType, i},
878878
ExpressionLocation{curr, i}});
879+
if (curr->isReturn) {
880+
// Send the result to the function's results as well.
881+
info.links.push_back({SignatureResultLocation{subType, i},
882+
ResultLocation{getFunction(), i}});
883+
}
879884
});
880885
}
881886
}

test/lit/passes/gufa-funcsub.wast

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,82 @@
370370
)
371371
)
372372

373+
;; Function subtyping in a return_call_indirect.
374+
(module
375+
(rec
376+
;; CHECK: (type $0 (func (result i32)))
377+
378+
;; CHECK: (rec
379+
;; CHECK-NEXT: (type $super (sub (func (result i32))))
380+
(type $super (sub (func (result i32))))
381+
;; CHECK: (type $sub (sub $super (func (result i32))))
382+
(type $sub (sub $super (func (result i32))))
383+
)
384+
385+
;; CHECK: (table $table 44 funcref)
386+
(table $table 44 funcref)
387+
388+
;; CHECK: (elem $table (i32.const 0) $sub)
389+
(elem $table (i32.const 0) $sub)
390+
391+
;; CHECK: (export "call" (func $call))
392+
393+
;; CHECK: (export "call_ref" (func $call_ref))
394+
395+
;; CHECK: (func $sub (type $sub) (result i32)
396+
;; CHECK-NEXT: (i32.const 42)
397+
;; CHECK-NEXT: )
398+
(func $sub (type $sub) (result i32)
399+
(i32.const 42)
400+
)
401+
402+
;; CHECK: (func $do_call (type $0) (result i32)
403+
;; CHECK-NEXT: (return_call_indirect $table (type $super)
404+
;; CHECK-NEXT: (i32.const 0)
405+
;; CHECK-NEXT: )
406+
;; CHECK-NEXT: )
407+
(func $do_call (result i32)
408+
;; Call $sub using type $super. The result, 42, is returned from this
409+
;; function, even though we don't infer an explicit value here (the return-
410+
;; call is unreachable anyhow, and we don't replace an unreachable with a
411+
;; concrete type).
412+
(return_call_indirect $table (type $super)
413+
(i32.const 0)
414+
)
415+
)
416+
417+
;; CHECK: (func $call (type $0) (result i32)
418+
;; CHECK-NEXT: (drop
419+
;; CHECK-NEXT: (call $do_call)
420+
;; CHECK-NEXT: )
421+
;; CHECK-NEXT: (i32.const 42)
422+
;; CHECK-NEXT: )
423+
(func $call (export "call") (result i32)
424+
;; We can infer 42 here.
425+
(call $do_call)
426+
)
427+
428+
;; CHECK: (func $do_call_ref (type $0) (result i32)
429+
;; CHECK-NEXT: (return_call_ref $sub
430+
;; CHECK-NEXT: (ref.func $sub)
431+
;; CHECK-NEXT: )
432+
;; CHECK-NEXT: )
433+
(func $do_call_ref (result i32)
434+
;; As above, with a call_ref.
435+
(return_call_ref $super
436+
(ref.func $sub)
437+
)
438+
)
439+
440+
;; CHECK: (func $call_ref (type $0) (result i32)
441+
;; CHECK-NEXT: (drop
442+
;; CHECK-NEXT: (call $do_call_ref)
443+
;; CHECK-NEXT: )
444+
;; CHECK-NEXT: (i32.const 42)
445+
;; CHECK-NEXT: )
446+
(func $call_ref (export "call_ref") (result i32)
447+
;; We can infer 42 here.
448+
(call $do_call_ref)
449+
)
450+
)
451+

0 commit comments

Comments
 (0)