blob: 04f0233e66a8515cd8166993e4d75df9b69c0021 [file] [log] [blame] [edit]
;; 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-features -S -o - | filecheck %s
(module
(memory 0)
;; CHECK: (type $0 (func))
;; CHECK: (type $1 (func (param i32)))
;; CHECK: (type $2 (func (param i32) (result i32)))
;; CHECK: (memory $0 0)
;; CHECK: (table $0 1 1 funcref)
;; CHECK: (elem $0 (i32.const 0) $called_indirect)
;; CHECK: (export "memory" (memory $0))
;; CHECK: (export "exported" (func $exported))
;; CHECK: (export "other1" (func $other1))
;; CHECK: (export "other2" (func $other2))
;; CHECK: (start $start)
(start $start)
(type $0 (func))
(type $0-dupe (func))
(type $1 (func (param i32)))
(type $1-dupe (func (param i32)))
(type $2 (func (param i32) (result i32)))
(type $2-dupe (func (param i32) (result i32)))
(type $2-thrupe (func (param i32) (result i32)))
(export "memory" (memory $0))
(export "exported" $exported)
(export "other1" $other1)
(export "other2" $other2)
(table 1 1 funcref)
(elem (i32.const 0) $called_indirect)
;; CHECK: (func $start (type $0)
;; CHECK-NEXT: (call $called0)
;; CHECK-NEXT: )
(func $start (type $0)
(call $called0)
)
;; CHECK: (func $called0 (type $0)
;; CHECK-NEXT: (call $called1)
;; CHECK-NEXT: )
(func $called0 (type $0)
(call $called1)
)
;; CHECK: (func $called1 (type $0)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $called1 (type $0)
(nop)
)
;; CHECK: (func $called_indirect (type $0)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $called_indirect (type $0)
(nop)
)
;; CHECK: (func $exported (type $0)
;; CHECK-NEXT: (call $called2)
;; CHECK-NEXT: )
(func $exported (type $0-dupe)
(call $called2)
)
;; CHECK: (func $called2 (type $0)
;; CHECK-NEXT: (call $called2)
;; CHECK-NEXT: (call $called3)
;; CHECK-NEXT: )
(func $called2 (type $0-dupe)
(call $called2)
(call $called3)
)
;; CHECK: (func $called3 (type $0)
;; CHECK-NEXT: (call $called4)
;; CHECK-NEXT: )
(func $called3 (type $0-dupe)
(call $called4)
)
;; CHECK: (func $called4 (type $0)
;; CHECK-NEXT: (call $called3)
;; CHECK-NEXT: )
(func $called4 (type $0-dupe)
(call $called3)
)
(func $remove0 (type $0-dupe)
(call $remove1)
)
(func $remove1 (type $0-dupe)
(nop)
)
(func $remove2 (type $0-dupe)
(call $remove2)
)
(func $remove3 (type $0)
(call $remove4)
)
(func $remove4 (type $0)
(call $remove3)
)
;; CHECK: (func $other1 (type $1) (param $0 i32)
;; CHECK-NEXT: (call_indirect $0 (type $0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $0 (type $0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $0 (type $0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $0 (type $0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $0 (type $1)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $0 (type $1)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $0 (type $2)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $0 (type $2)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $0 (type $2)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $other1 (type $1) (param i32)
(call_indirect (type $0) (i32.const 0))
(call_indirect (type $0) (i32.const 0))
(call_indirect (type $0-dupe) (i32.const 0))
(call_indirect (type $0-dupe) (i32.const 0))
(call_indirect (type $1) (i32.const 0) (i32.const 0))
(call_indirect (type $1-dupe) (i32.const 0) (i32.const 0))
(drop (call_indirect (type $2) (i32.const 0) (i32.const 0)))
(drop (call_indirect (type $2-dupe) (i32.const 0) (i32.const 0)))
(drop (call_indirect (type $2-thrupe) (i32.const 0) (i32.const 0)))
)
;; CHECK: (func $other2 (type $1) (param $0 i32)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $other2 (type $1-dupe) (param i32)
(unreachable)
)
)
(module ;; remove the table and memory
(import "env" "memory" (memory $0 256))
(import "env" "table" (table 0 funcref))
)
(module ;; remove all tables and the memory
(import "env" "memory" (memory $0 256))
(import "env" "table" (table 0 funcref))
(import "env" "table2" (table $1 1 2 funcref))
(elem (table $1) (offset (i32.const 0)) func)
(elem (table $1) (offset (i32.const 1)) func)
)
(module ;; remove the first table and memory, but not the second one
;; CHECK: (type $none_=>_none (func))
;; CHECK: (import "env" "table2" (table $1 1 1 funcref))
(import "env" "memory" (memory $0 256))
(import "env" "table" (table 0 funcref))
(import "env" "table2" (table $1 1 1 funcref))
(elem (table $1) (offset (i32.const 0)) func)
(elem (table $1) (offset (i32.const 0)) func $f)
;; CHECK: (elem $1 (i32.const 0) $f)
;; CHECK: (func $f (type $none_=>_none)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $f)
)
(module ;; also when not imported
(memory 256)
(table 1 funcref)
)
(module ;; also with multiple tables
(memory 256)
(table $0 1 funcref)
(table $1 1 funcref)
(elem (table $1) (i32.const 0) func)
)
(module ;; but not when exported
;; CHECK: (import "env" "memory" (memory $0 256))
(import "env" "memory" (memory $0 256))
;; CHECK: (import "env" "table" (table $timport$0 1 funcref))
(import "env" "table" (table 1 funcref))
;; CHECK: (export "mem" (memory $0))
(export "mem" (memory 0))
;; CHECK: (export "tab" (table $timport$0))
(export "tab" (table 0))
)
(module ;; and not when there are segments
;; CHECK: (type $none_=>_none (func))
;; CHECK: (import "env" "memory" (memory $0 256))
(import "env" "memory" (memory $0 256))
;; CHECK: (import "env" "table" (table $timport$0 1 funcref))
(import "env" "table" (table 1 funcref))
(data (i32.const 1) "hello, world!")
(elem (i32.const 0) $waka)
;; CHECK: (data $0 (i32.const 1) "hello, world!")
;; CHECK: (elem $0 (i32.const 0) $waka)
;; CHECK: (func $waka (type $none_=>_none)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $waka)
)
(module ;; and not when used
;; CHECK: (type $0 (func))
(type $0 (func))
;; CHECK: (import "env" "memory" (memory $0 256))
(import "env" "memory" (memory $0 256))
;; CHECK: (import "env" "table" (table $timport$0 0 funcref))
(import "env" "table" (table 0 funcref))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $0)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.load
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call_indirect $timport$0 (type $0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user
(drop (i32.load (i32.const 0)))
(call_indirect (type $0) (i32.const 0))
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_none (func))
;; CHECK: (memory $0 (shared 23 256))
(memory $0 (shared 23 256))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_none)
;; CHECK-NEXT: (i32.store
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user
(i32.store (i32.const 0) (i32.const 0))
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_i32 (func (result i32)))
;; CHECK: (memory $0 (shared 23 256))
(memory $0 (shared 23 256))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_i32) (result i32)
;; CHECK-NEXT: (i32.atomic.rmw.add
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user (result i32)
(i32.atomic.rmw.add (i32.const 0) (i32.const 0))
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_i32 (func (result i32)))
;; CHECK: (memory $0 (shared 23 256))
(memory $0 (shared 23 256))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_i32) (result i32)
;; CHECK-NEXT: (i32.atomic.rmw8.cmpxchg_u
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user (result i32)
(i32.atomic.rmw8.cmpxchg_u (i32.const 0) (i32.const 0) (i32.const 0))
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_none (func))
;; CHECK: (memory $0 (shared 23 256))
(memory $0 (shared 23 256))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_none)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (local $1 i64)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (memory.atomic.wait32
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user
(local $0 i32)
(local $1 i64)
(drop
(memory.atomic.wait32
(local.get $0)
(local.get $0)
(local.get $1)
)
)
)
)
(module ;; more use checks
;; CHECK: (type $none_=>_i32 (func (result i32)))
;; CHECK: (memory $0 (shared 23 256))
(memory $0 (shared 23 256))
;; CHECK: (export "user" (func $user))
(export "user" $user)
;; CHECK: (func $user (type $none_=>_i32) (result i32)
;; CHECK-NEXT: (memory.atomic.notify
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $user (result i32)
(memory.atomic.notify (i32.const 0) (i32.const 0))
)
)
(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_=>_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: (export "user" (func $user))
(export "user" $user)
;; 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
(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: (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.size)
;; CHECK-NEXT: )
(func $user (result i32)
(memory.size)
)
)
(module ;; memory.copy should keep both memories alive
;; CHECK: (type $none_=>_none (func))
;; 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_=>_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
(memory.copy $0 $1
(i32.const 0)
(i32.const 0)
(i32.const 0)
)
)
)
(module
;; CHECK: (type $none_=>_none (func))
;; CHECK: (import "env" "memory" (memory $0 256))
(import "env" "memory" (memory $0 256))
;; CHECK: (import "env" "table" (table $timport$0 0 funcref))
(import "env" "table" (table 0 funcref))
;; CHECK: (import "env" "memoryBase" (global $memoryBase i32))
(import "env" "memoryBase" (global $memoryBase i32)) ;; used in init
;; CHECK: (import "env" "tableBase" (global $tableBase i32))
(import "env" "tableBase" (global $tableBase i32)) ;; used in init
(data (global.get $memoryBase) "hello, world!")
(elem (global.get $tableBase) $waka)
;; CHECK: (data $0 (global.get $memoryBase) "hello, world!")
;; CHECK: (elem $0 (global.get $tableBase) $waka)
;; CHECK: (func $waka (type $none_=>_none)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $waka) ;; used in table
)
(module ;; one is exported, and one->two->int global, whose init->imported
;; CHECK: (type $none_=>_i32 (func (result i32)))
;; CHECK: (type $none_=>_none (func))
;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
;; CHECK: (import "env" "imported" (global $imported i32))
(import "env" "imported" (global $imported i32))
;; CHECK: (import "env" "_puts" (func $_puts (type $i32_=>_i32) (param i32) (result i32)))
(import "env" "forgetme" (global $forgetme i32))
(import "env" "_puts" (func $_puts (param i32) (result i32)))
(import "env" "forget_puts" (func $forget_puts (param i32) (result i32)))
;; CHECK: (global $int (mut i32) (global.get $imported))
(global $int (mut i32) (global.get $imported))
;; CHECK: (global $set (mut i32) (i32.const 100))
(global $set (mut i32) (i32.const 100))
(global $forglobal.get (mut i32) (i32.const 500))
;; CHECK: (global $exp_glob i32 (i32.const 600))
(global $exp_glob i32 (i32.const 600))
;; CHECK: (export "one" (func $one))
(export "one" (func $one))
;; CHECK: (export "three" (func $three))
(export "three" (func $three))
;; CHECK: (export "exp_glob" (global $exp_glob))
(export "exp_glob" (global $exp_glob))
(start $starter)
;; CHECK: (func $one (type $none_=>_i32) (result i32)
;; CHECK-NEXT: (call $two)
;; CHECK-NEXT: )
(func $one (result i32)
(call $two)
)
;; CHECK: (func $two (type $none_=>_i32) (result i32)
;; CHECK-NEXT: (global.get $int)
;; CHECK-NEXT: )
(func $two (result i32)
(global.get $int)
)
;; CHECK: (func $three (type $none_=>_none)
;; CHECK-NEXT: (call $four)
;; CHECK-NEXT: )
(func $three
(call $four)
)
;; CHECK: (func $four (type $none_=>_none)
;; CHECK-NEXT: (global.set $set
;; CHECK-NEXT: (i32.const 200)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $_puts
;; CHECK-NEXT: (i32.const 300)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $four
(global.set $set (i32.const 200))
(drop (call $_puts (i32.const 300)))
)
(func $forget_implemented
(nop)
)
(func $starter
(nop)
)
)
(module ;; empty start being removed
(start $starter)
(func $starter
(nop)
)
)
(module ;; non-empty start being kept
;; CHECK: (type $none_=>_none (func))
;; CHECK: (start $starter)
(start $starter)
;; CHECK: (func $starter (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $starter
(drop (i32.const 0))
)
)
(module ;; imported start cannot be removed
;; CHECK: (type $none_=>_none (func))
;; CHECK: (import "env" "start" (func $start (type $none_=>_none)))
(import "env" "start" (func $start))
;; CHECK: (start $start)
(start $start)
)
(module ;; the function and the table can be removed
(type $0 (func (param f64) (result f64)))
(table 6 6 funcref)
(func $0 (; 0 ;) (type $0) (param $var$0 f64) (result f64)
(if (result f64)
(f64.eq
(f64.const 1)
(f64.const 1)
)
(f64.const 1)
(f64.const 0)
)
)
)
(module ;; the function uses the table, but all are removeable
(type $0 (func (param f64) (result f64)))
(table 6 6 funcref)
(func $0 (; 0 ;) (type $0) (param $var$0 f64) (result f64)
(if (result f64)
(f64.eq
(f64.const 1)
(f64.const 1)
)
(call_indirect (type $0) (f64.const 1) (i32.const 0))
(f64.const 0)
)
)
)
(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" "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)
;; CHECK-NEXT: (f64.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (f64.const 1)
;; CHECK-NEXT: (f64.const 0)
;; 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)
(f64.const 1)
)
(f64.const 1)
(f64.const 0)
)
)
)
(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)
)
)
)
)
;; SIMD operations can keep memories alive
(module
;; CHECK: (type $none_=>_none (func))
;; CHECK: (memory $A 1 1)
(memory $A 1 1)
;; CHECK: (memory $B 1 1)
(memory $B 1 1)
(memory $C-unused 1 1)
(func "func"
(drop
(v128.load64_splat $A
(i32.const 0)
)
)
(drop
(v128.load16_lane $B 0
(i32.const 0)
(v128.const i32x4 0 0 0 0)
)
)
)
)
;; CHECK: (export "func" (func $0))
;; CHECK: (func $0 (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (v128.load64_splat $A
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (v128.load16_lane $B 0
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )