Skip to content
Open
Show file tree
Hide file tree
Changes from all 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.

(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