-
Notifications
You must be signed in to change notification settings - Fork 831
RemoveUnusedModuleElements: Do not remove unused-but-trapping segments #6242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
01ab947
start
kripken 2bbf621
work
kripken 0c8a66d
fix
kripken 61fdd00
test
kripken 42abeac
work
kripken 5b80fa4
work
kripken 29b5170
work
kripken 06f39d7
fix
kripken 1a28be2
test
kripken 80d1eb1
test
kripken b064b59
test
kripken c4b899a
test
kripken f5e0681
test
kripken f28d884
format
kripken 9b2ae95
siml
kripken 154785e
siml
kripken 8573500
siml
kripken 3973ceb
siml
kripken 4cf8e39
siml
kripken 64d3586
siml
kripken 52fbfb9
siml
kripken 506a1bb
siml
kripken f869759
Add testcase for multiple memories, one removable and one not
kripken 34a991a
improve testcase slightly
kripken File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. | ||
| ;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up. | ||
|
|
||
| ;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements -all -S -o - | filecheck %s | ||
| ;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements -tnh -all -S -o - | filecheck %s --check-prefix=T_N_H | ||
|
|
||
| ;; The segments here will trap during startup as they are out of bounds. We | ||
| ;; can only remove such segments if we assume TrapsNeverHappen. | ||
| ;; | ||
| ;; The passive segments, however, can be removed: they do nothing during | ||
| ;; startup, and have no uses. | ||
| (module | ||
| ;; CHECK: (memory $0 16 17 shared) | ||
| (memory $0 16 17 shared) | ||
|
|
||
| ;; CHECK: (data $0 (i32.const -1) "") | ||
| (data $0 (i32.const -1) "") | ||
|
|
||
| (data $1 "") | ||
|
|
||
| ;; CHECK: (table $0 1 1 funcref) | ||
| (table $0 1 1 funcref) | ||
|
|
||
| ;; CHECK: (elem $0 (i32.const -1)) | ||
| (elem $0 (i32.const -1)) | ||
|
|
||
| (elem $1 func) | ||
| ) | ||
|
|
||
| ;; Some segments can be removed: any segment that writes to address 131072 or | ||
| ;; higher will trap, and must be kept (unless TNH). Only the $bad segment | ||
| ;; should remain for that reason, however, it keeps the memory alive which | ||
| ;; keeps the $ok* segments alive too. | ||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const 131071) "ab") | ||
| (data $bad (i32.const 131071) "ab") | ||
| ) | ||
|
|
||
| ;; The following modules have variations on the bad segment. | ||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const 131072) "a") | ||
| (data $bad (i32.const 131072) "a") | ||
| ) | ||
|
|
||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const 9999999) "a") | ||
| (data $bad (i32.const 9999999) "a") | ||
| ) | ||
|
|
||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const -2) "a") | ||
| (data $bad (i32.const 4294967294) "a") | ||
| ) | ||
|
|
||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const -6) "abcdefghijklmnop_overflow") | ||
| (data $bad (i32.const 4294967290) "abcdefghijklmnop_overflow") | ||
| ) | ||
|
|
||
| (module | ||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (i32.const -2) "a") | ||
| (data $bad (i32.const -2) "a") | ||
| ) | ||
|
|
||
| ;; An imported global is an unknown offset, so it might trap. | ||
| (module | ||
| ;; CHECK: (import "a" "b" (global $imported i32)) | ||
| (import "a" "b" (global $imported i32)) | ||
|
|
||
| ;; CHECK: (memory $0 2 2) | ||
| (memory $0 2 2) | ||
|
|
||
| ;; CHECK: (data $ok1 (i32.const 0) "a") | ||
| (data $ok1 (i32.const 0) "a") | ||
| ;; CHECK: (data $ok2 (i32.const 1000) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| ;; CHECK: (data $ok3 (i32.const 131071) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ;; CHECK: (data $bad (global.get $imported) "a") | ||
| (data $bad (global.get $imported) "a") | ||
| ) | ||
|
|
||
| ;; Finally, a module with no bad segments. We can remove all the contents. | ||
| (module | ||
| (memory $0 2 2) | ||
|
|
||
| (data $ok1 (i32.const 0) "a") | ||
| (data $ok2 (i32.const 1000) "a") | ||
| (data $ok3 (i32.const 131071) "a") | ||
| ) | ||
|
|
||
| ;; Similar testing for element segments. One bad segment keeps it all alive | ||
| ;; here. | ||
| (module | ||
| (table 10 10 funcref) | ||
|
|
||
| ;; CHECK: (type $0 (func)) | ||
|
|
||
| ;; CHECK: (table $0 10 10 funcref) | ||
|
|
||
| ;; CHECK: (elem $ok1 (i32.const 0) $func) | ||
| (elem $ok1 (i32.const 0) $func) | ||
| ;; CHECK: (elem $ok2 (i32.const 8) $func $func) | ||
| (elem $ok2 (i32.const 8) $func $func) | ||
| ;; CHECK: (elem $ok3 (i32.const 9) $func) | ||
| (elem $ok3 (i32.const 9) $func) | ||
| ;; CHECK: (elem $bad (i32.const 10) $func) | ||
| (elem $bad (i32.const 10) $func) | ||
|
|
||
| ;; CHECK: (func $func (type $0) | ||
| ;; CHECK-NEXT: (nop) | ||
| ;; CHECK-NEXT: ) | ||
| ;; T_N_H: (type $0 (func)) | ||
|
|
||
| ;; T_N_H: (func $func (type $0) | ||
| ;; T_N_H-NEXT: (nop) | ||
| ;; T_N_H-NEXT: ) | ||
| (func $func) | ||
| ) | ||
|
|
||
| ;; A different bad segment. | ||
| (module | ||
| (table 10 10 funcref) | ||
|
|
||
| ;; CHECK: (type $0 (func)) | ||
|
|
||
| ;; CHECK: (table $0 10 10 funcref) | ||
|
|
||
| ;; CHECK: (elem $ok1 (i32.const 0) $func) | ||
| (elem $ok1 (i32.const 0) $func) | ||
| ;; CHECK: (elem $ok2 (i32.const 8) $func $func) | ||
| (elem $ok2 (i32.const 8) $func $func) | ||
| ;; CHECK: (elem $ok3 (i32.const 9) $func) | ||
| (elem $ok3 (i32.const 9) $func) | ||
| ;; CHECK: (elem $bad (i32.const 9) $func $func) | ||
| (elem $bad (i32.const 9) $func $func) | ||
|
|
||
| ;; CHECK: (func $func (type $0) | ||
| ;; CHECK-NEXT: (nop) | ||
| ;; CHECK-NEXT: ) | ||
| ;; T_N_H: (type $0 (func)) | ||
|
|
||
| ;; T_N_H: (func $func (type $0) | ||
| ;; T_N_H-NEXT: (nop) | ||
| ;; T_N_H-NEXT: ) | ||
| (func $func) | ||
| ) | ||
|
|
||
| ;; No bad segments: all element segments vanish. TODO: the function could too | ||
| (module | ||
| (table 10 10 funcref) | ||
|
|
||
| (elem $ok1 (i32.const 0) $func) | ||
| (elem $ok2 (i32.const 8) $func $func) | ||
| (elem $ok3 (i32.const 9) $func) | ||
|
|
||
| ;; CHECK: (type $0 (func)) | ||
|
|
||
| ;; CHECK: (func $func (type $0) | ||
| ;; CHECK-NEXT: (nop) | ||
| ;; CHECK-NEXT: ) | ||
| ;; T_N_H: (type $0 (func)) | ||
|
|
||
| ;; T_N_H: (func $func (type $0) | ||
| ;; T_N_H-NEXT: (nop) | ||
| ;; T_N_H-NEXT: ) | ||
| (func $func) | ||
| ) | ||
|
|
||
| ;; Multiple memories. One can be removed, the other remains due to a trapping | ||
| ;; segment. | ||
| (module | ||
| ;; CHECK: (memory $small 1 1) | ||
| (memory $small 1 1) | ||
|
|
||
| (memory $big 2 2) | ||
|
|
||
| ;; CHECK: (data $a (i32.const 100000) "ab") | ||
| (data $a (memory $small) (i32.const 100000) "ab") ;; fits in $big; not $small | ||
|
|
||
| (data $b (memory $big) (i32.const 100000) "cd") | ||
| ) | ||
|
|
||
| ;; Reverse order of memories. | ||
| (module | ||
| (memory $big 2 2) | ||
|
|
||
| ;; CHECK: (memory $small 1 1) | ||
| (memory $small 1 1) | ||
|
|
||
| ;; CHECK: (data $a (i32.const 100000) "ab") | ||
| (data $a (memory $small) (i32.const 100000) "ab") ;; fits in $big; not $small | ||
|
|
||
| (data $b (memory $big) (i32.const 100000) "cd") | ||
| ) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be interesting to test where the bad segment writes to a different memory than some other good segments, which could still be removed.