summaryrefslogtreecommitdiff
path: root/test/lit/passes/remove-unused-module-elements_all-features.wast
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit/passes/remove-unused-module-elements_all-features.wast')
-rw-r--r--test/lit/passes/remove-unused-module-elements_all-features.wast195
1 files changed, 167 insertions, 28 deletions
diff --git a/test/lit/passes/remove-unused-module-elements_all-features.wast b/test/lit/passes/remove-unused-module-elements_all-features.wast
index 00a9d8f14..d5c394e30 100644
--- a/test/lit/passes/remove-unused-module-elements_all-features.wast
+++ b/test/lit/passes/remove-unused-module-elements_all-features.wast
@@ -351,63 +351,89 @@
(memory.atomic.notify (i32.const 0) (i32.const 0))
)
)
-(module ;; atomic.fence does not use a memory, so should not keep the memory alive.
+(module ;; atomic.fence and data.drop do not use a memory, so should not keep the memory alive.
(memory $0 (shared 1 1))
+ (data "")
;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (data $0 "")
+
;; CHECK: (export "fake-user" (func $user))
(export "fake-user" $user)
;; CHECK: (func $user (type $none_=>_none)
;; CHECK-NEXT: (atomic.fence)
+ ;; CHECK-NEXT: (data.drop $0)
;; CHECK-NEXT: )
(func $user
(atomic.fence)
+ (data.drop 0)
)
)
(module ;; more use checks
- ;; CHECK: (type $none_=>_i32 (func (result i32)))
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (import "env" "mem" (memory $0 256))
+ (import "env" "mem" (memory $0 256))
+ ;; CHECK: (memory $1 23 256)
+ (memory $1 23 256)
+ (memory $unused 1 1)
- ;; CHECK: (memory $0 23 256)
- (memory $0 23 256)
;; CHECK: (export "user" (func $user))
(export "user" $user)
- ;; CHECK: (func $user (type $none_=>_i32) (result i32)
- ;; CHECK-NEXT: (memory.grow
- ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK: (func $user (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (memory.grow $0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (memory.grow $1
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $user (result i32)
- (memory.grow (i32.const 0))
+ (func $user
+ (drop (memory.grow $0 (i32.const 0)))
+ (drop (memory.grow $1 (i32.const 0)))
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_i32 (func (result i32)))
- ;; CHECK: (import "env" "memory" (memory $0 256))
- (import "env" "memory" (memory $0 256))
+ ;; CHECK: (memory $0 23 256)
+ (memory $0 23 256)
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_i32) (result i32)
- ;; CHECK-NEXT: (memory.grow
- ;; CHECK-NEXT: (i32.const 0)
- ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (memory.size)
;; CHECK-NEXT: )
(func $user (result i32)
- (memory.grow (i32.const 0))
+ (memory.size)
)
)
-(module ;; more use checks
- ;; CHECK: (type $none_=>_i32 (func (result i32)))
+(module ;; memory.copy should keep both memories alive
+ ;; CHECK: (type $none_=>_none (func))
- ;; CHECK: (memory $0 23 256)
- (memory $0 23 256)
+ ;; CHECK: (memory $0 1 1)
+ (memory $0 1 1)
+ ;; CHECK: (memory $1 1 1)
+ (memory $1 1 1)
+ (memory $unused 1 1)
;; CHECK: (export "user" (func $user))
(export "user" $user)
- ;; CHECK: (func $user (type $none_=>_i32) (result i32)
- ;; CHECK-NEXT: (memory.size)
+ ;; CHECK: (func $user (type $none_=>_none)
+ ;; CHECK-NEXT: (memory.copy $0 $1
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $user (result i32)
- (memory.size)
+ (func $user
+ (memory.copy $0 $1
+ (i32.const 0)
+ (i32.const 0)
+ (i32.const 0)
+ )
)
)
(module
@@ -554,15 +580,40 @@
)
)
)
-(module ;; the table is imported - we can't remove it
+(module
+ ;; We import two tables and have an active segment that writes to one of them.
+ ;; We must keep that table and the segment, but we can remove the other table.
;; CHECK: (type $0 (func (param f64) (result f64)))
(type $0 (func (param f64) (result f64)))
- ;; CHECK: (import "env" "table" (table $timport$0 6 6 funcref))
- (import "env" "table" (table 6 6 funcref))
- (elem (i32.const 0) $0)
- ;; CHECK: (elem $0 (i32.const 0) $0)
+ ;; CHECK: (import "env" "written" (table $written 6 6 funcref))
+ (import "env" "written" (table $written 6 6 funcref))
+
+ (import "env" "unwritten" (table $unwritten 6 6 funcref))
+
+ (table $defined-unused 6 6 funcref)
+
+ ;; CHECK: (table $defined-used 6 6 funcref)
+ (table $defined-used 6 6 funcref)
+
+ ;; CHECK: (elem $active1 (table $written) (i32.const 0) func $0)
+ (elem $active1 (table $written) (i32.const 0) $0)
+
+ ;; This empty active segment doesn't keep the unwritten table alive.
+ (elem $active2 (table $unwritten) (i32.const 0))
+
+ (elem $active3 (table $defined-unused) (i32.const 0) $0)
+
+ ;; CHECK: (elem $active4 (table $defined-used) (i32.const 0) func $0)
+ (elem $active4 (table $defined-used) (i32.const 0) $0)
+
+ (elem $active5 (table $defined-used) (i32.const 0))
;; CHECK: (func $0 (type $0) (param $var$0 f64) (result f64)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.get $defined-used
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (if (result f64)
;; CHECK-NEXT: (f64.eq
;; CHECK-NEXT: (f64.const 1)
@@ -573,6 +624,11 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $0 (; 0 ;) (type $0) (param $var$0 f64) (result f64)
+ (drop
+ (table.get $defined-used
+ (i32.const 0)
+ )
+ )
(if (result f64)
(f64.eq
(f64.const 1)
@@ -583,3 +639,86 @@
)
)
)
+(module
+ ;; The same thing works for memories with active segments.
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (import "env" "written" (memory $written 1 1))
+ (import "env" "written" (memory $written 1 1))
+
+ (import "env" "unwritten" (memory $unwritten 1 1))
+
+ (memory $defined-unused 1 1)
+
+ ;; CHECK: (memory $defined-used 1 1)
+ (memory $defined-used 1 1)
+
+ ;; CHECK: (data $active1 (i32.const 0) "foobar")
+ (data $active1 (memory $written) (i32.const 0) "foobar")
+
+ (data $active2 (memory $unwritten) (i32.const 0) "")
+
+ (data $active3 (memory $defined-unused) (i32.const 0) "hello")
+
+ ;; CHECK: (data $active4 (memory $defined-used) (i32.const 0) "hello")
+ (data $active4 (memory $defined-used) (i32.const 0) "hello")
+
+ (data $active5 (memory $defined-used) (i32.const 0) "")
+
+ ;; CHECK: (export "user" (func $user))
+
+ ;; CHECK: (func $user (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load $defined-used
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $user (export "user")
+ (drop
+ (i32.load $defined-used
+ (i32.const 0)
+ )
+ )
+ )
+)
+(module
+ ;; Nothing should break if the unused segments precede the used segments.
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (type $array (array funcref))
+ (type $array (array funcref))
+
+ (memory $mem 1 1)
+ (table $tab 1 1 funcref)
+
+ (data $unused "")
+ (elem $unused func)
+
+ ;; CHECK: (data $used "")
+ (data $used "")
+ ;; CHECK: (elem $used func)
+ (elem $used func)
+
+ ;; CHECK: (export "user" (func $user))
+
+ ;; CHECK: (func $user (type $none_=>_none)
+ ;; CHECK-NEXT: (data.drop $used)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (array.new_elem $array $used
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $user (export "user")
+ (data.drop 1)
+ (drop
+ (array.new_elem $array 1
+ (i32.const 0)
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ )
+)