Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/fuzz_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2525,7 +2525,7 @@ def handle(self, wasm):
TrapsNeverHappen(),
CtorEval(),
Merge(),
# Split(), # https://github.com/WebAssembly/binaryen/issues/8510
Split(),
RoundtripText(),
ClusterFuzz(),
Two(),
Expand Down
264 changes: 126 additions & 138 deletions src/ir/module-splitting.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are some edge cases that I feel easy to miss, because now we specially handle the active table and the base global in setupTablePatching

;; We need to disable reference-types to reuse the existing table as the active
;; table
;; RUN: wasm-split %s --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm
;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY

;; This tests the case when an existing table is used as the active table, and
;; the active table and its base global already has existing uses in the
;; secondary module.

(module
;; PRIMARY: (type $0 (func))
;; SECONDARY: (type $0 (func))
(type $0 (func))
(global $base (import "env" "base") i32)
;; PRIMARY: (import "env" "base" (global $base i32))

;; PRIMARY: (import "placeholder.deferred" "1" (func $placeholder_1))

;; PRIMARY: (table $table 2 funcref)
(table $table 1 funcref)
(elem (global.get $base) $keep)
;; PRIMARY: (elem $0 (global.get $base) $keep $placeholder_1)

;; PRIMARY: (export "table" (table $table))

;; PRIMARY: (export "global" (global $base))

;; PRIMARY: (export "keep" (func $keep))

;; PRIMARY: (func $keep
;; PRIMARY-NEXT: (call_indirect (type $0)
;; PRIMARY-NEXT: (i32.add
;; PRIMARY-NEXT: (global.get $base)
;; PRIMARY-NEXT: (i32.const 1)
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )
(func $keep
(call $split)
)
;; SECONDARY: (import "primary" "table" (table $table 1 funcref))

;; SECONDARY: (import "primary" "global" (global $base i32))

;; SECONDARY: (import "primary" "keep" (func $keep))

;; SECONDARY: (elem $0 (global.get $base) $keep $split)

;; SECONDARY: (func $split
;; SECONDARY-NEXT: (drop
;; SECONDARY-NEXT: (global.get $base)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: (call_indirect (type $0)
;; SECONDARY-NEXT: (i32.const 0)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: )
(func $split
(drop (global.get $base))
(call_indirect (type $0) (i32.const 0))
)
)
43 changes: 0 additions & 43 deletions test/lit/wasm-split/global-funcref.wast

This file was deleted.

45 changes: 45 additions & 0 deletions test/lit/wasm-split/global-reffunc.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
;; RUN: wasm-split %s -all -g -o1 %t.1.wasm -o2 %t.2.wasm --keep-funcs=keep
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was renamed from global-funcref.wast (but Github fails to recognize it) and expectation rewritten

;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY

;; When a split global ($a here)'s initializer contains a ref.func of a split
;; function, we should NOT create any trampolines, and the split global should
;; direclty refer to the function.
Comment thread
aheejin marked this conversation as resolved.
Outdated

(module
(global $a funcref (ref.func $split))
(global $b funcref (ref.func $keep))

(func $keep)

(func $split
(drop
(global.get $a)
)
(drop
(global.get $b)
)
)
)

;; PRIMARY: (module
;; PRIMARY-NEXT: (type $0 (func))
;; PRIMARY-NEXT: (export "keep" (func $keep))
;; PRIMARY-NEXT: (func $keep
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )

;; SECONDARY: (module
;; SECONDARY-NEXT: (type $0 (func))
;; SECONDARY-NEXT: (import "primary" "keep" (func $keep (exact)))
;; SECONDARY-NEXT: (global $a funcref (ref.func $split))
;; SECONDARY-NEXT: (global $b funcref (ref.func $keep))
;; SECONDARY-NEXT: (func $split
;; SECONDARY-NEXT: (drop
;; SECONDARY-NEXT: (global.get $a)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: (drop
;; SECONDARY-NEXT: (global.get $b)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: )
52 changes: 52 additions & 0 deletions test/lit/wasm-split/global-reffunc2.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
;; RUN: wasm-split %s -all -g -o1 %t.1.wasm -o2 %t.2.wasm --split-funcs=split1,split2
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the test reduced from #8510

;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY

;; Global $g1 is used (exported) in the primary module so it can't move, and
;; global $g2 is only used in the secondary module so it will move there.

(module
(global $g1 funcref (ref.func $split1))
(global $g2 funcref (ref.func $split2))
(export "g1" (global $g1))

(func $split1
(unreachable)
)

(func $split2
(drop
(global.get $g2)
)
)
)

;; PRIMARY: (module
;; PRIMARY-NEXT: (type $0 (func))
;; PRIMARY-NEXT: (import "placeholder.deferred" "0" (func $placeholder_0))
;; PRIMARY-NEXT: (global $g1 funcref (ref.func $trampoline_split1))
;; PRIMARY-NEXT: (table $0 1 funcref)
;; PRIMARY-NEXT: (elem $0 (i32.const 0) $placeholder_0)
;; PRIMARY-NEXT: (export "g1" (global $g1))
;; PRIMARY-NEXT: (export "table" (table $0))
;; PRIMARY-NEXT: (func $trampoline_split1
;; PRIMARY-NEXT: (call_indirect (type $0)
;; PRIMARY-NEXT: (i32.const 0)
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )

;; SECONDARY: (module
;; SECONDARY-NEXT: (type $0 (func))
;; SECONDARY-NEXT: (import "primary" "table" (table $timport$0 1 funcref))
;; SECONDARY-NEXT: (global $g2 funcref (ref.func $split2))
;; SECONDARY-NEXT: (elem $0 (i32.const 0) $split1)
;; SECONDARY-NEXT: (func $split1
;; SECONDARY-NEXT: (unreachable)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: (func $split2
;; SECONDARY-NEXT: (drop
;; SECONDARY-NEXT: (global.get $g2)
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: )
;; SECONDARY-NEXT: )
6 changes: 3 additions & 3 deletions test/lit/wasm-split/ref.func.wast
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@

;; SECONDARY: (import "primary" "prime" (func $prime (exact (type $0))))

;; SECONDARY: (elem $0 (i32.const 0) $second-in-table $second)
;; SECONDARY: (elem $0 (i32.const 0) $second $second-in-table)

;; SECONDARY: (elem declare func $prime)

Expand Down Expand Up @@ -109,13 +109,13 @@
;; (but we will get a placeholder, as all split-out functions do).
)
)
;; PRIMARY: (func $trampoline_second-in-table (type $0)
;; PRIMARY: (func $trampoline_second (type $0)
;; PRIMARY-NEXT: (call_indirect $1 (type $0)
;; PRIMARY-NEXT: (i32.const 0)
;; PRIMARY-NEXT: )
;; PRIMARY-NEXT: )

;; PRIMARY: (func $trampoline_second (type $0)
;; PRIMARY: (func $trampoline_second-in-table (type $0)
;; PRIMARY-NEXT: (call_indirect $1 (type $0)
;; PRIMARY-NEXT: (i32.const 1)
;; PRIMARY-NEXT: )
Expand Down
8 changes: 4 additions & 4 deletions test/lit/wasm-split/split-module-items.wast
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@
;; PRIMARY: (tag $keep-tag (type $1) (param i32))
;; PRIMARY-NEXT: (tag $shared-tag (type $1) (param i32))

;; PRIMARY: (export "keep" (func $keep))
;; PRIMARY-NEXT: (export "memory" (memory $shared-memory))
;; PRIMARY: (export "memory" (memory $shared-memory))
;; PRIMARY-NEXT: (export "table" (table $shared-table))
;; PRIMARY-NEXT: (export "table_3" (table $2))
;; PRIMARY-NEXT: (export "global" (global $shared-global))
;; PRIMARY-NEXT: (export "tag" (tag $shared-tag))
;; PRIMARY-NEXT: (export "keep" (func $keep))
;; PRIMARY-NEXT: (export "table_5" (table $2))

;; SECONDARY: (import "primary" "memory" (memory $shared-memory 1 1))
;; SECONDARY-NEXT: (import "primary" "table_3" (table $timport$0 1 funcref))
;; SECONDARY-NEXT: (import "primary" "table" (table $shared-table 1 1 funcref))
;; SECONDARY-NEXT: (import "primary" "table_5" (table $timport$1 1 funcref))
;; SECONDARY-NEXT: (import "primary" "global" (global $shared-global i32))
;; SECONDARY-NEXT: (import "primary" "keep" (func $keep (exact (param i32) (result i32))))
;; SECONDARY-NEXT: (import "primary" "tag" (tag $shared-tag (type $1) (param i32)))
Expand Down
Loading