blob: 4b78a73ffe03ccf40684b61f95fa72f46e3bffdb [file] [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 --directize --all-features -S -o - | filecheck %s --check-prefix=CHECK
;; An initial value in a table. Rather than a null for uninitialized elements,
;; which traps, we know what is called here.
(module
;; CHECK: (type $func (func (result i32)))
(type $func (func (result i32)))
;; CHECK: (type $1 (func))
;; CHECK: (table $table 1 1 funcref (ref.func $func))
(table $table 1 1 funcref (ref.func $func))
;; CHECK: (export "caller" (func $caller))
;; CHECK: (func $caller (type $1)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $table (type $func)
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller (export "caller")
;; This can be optimized to a call to $func.
(drop
(call_indirect $table (type $func)
(i32.const 0)
)
)
;; This is out of bounds, and traps.
(drop
(call_indirect $table (type $func)
(i32.const 999)
)
)
;; This is an unknown index, which we do not optimize.
(drop
(call_indirect $table (type $func)
(i32.eqz
(i32.const 1)
)
)
)
)
;; CHECK: (func $func (type $func) (result i32)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $func (type $func) (result i32)
(i32.const 0)
)
)
;; As above, but the initializer is a global.get, so we cannot infer a direct
;; call.
;; TODO: the pass could propagate global.gets from tables where possible
(module
;; CHECK: (type $func (func (result i32)))
(type $func (func (result i32)))
;; CHECK: (type $1 (func))
;; CHECK: (import "a" "b" (global $import funcref))
(import "a" "b" (global $import funcref))
;; CHECK: (table $table 1 1 funcref (global.get $import))
(table $table 1 1 funcref (global.get $import)) ;; this changed
;; CHECK: (export "caller" (func $caller))
;; CHECK: (func $caller (type $1)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $table (type $func)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call_indirect $table (type $func)
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller (export "caller")
;; This cannot be optimized to a call to $func.
(drop
(call_indirect $table (type $func)
(i32.const 0)
)
)
;; As before, this is out of bounds, and traps.
(drop
(call_indirect $table (type $func)
(i32.const 999)
)
)
;; As before, this is an unknown index, which we do not optimize.
(drop
(call_indirect $table (type $func)
(i32.eqz
(i32.const 1)
)
)
)
)
;; CHECK: (func $func (type $func) (result i32)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $func (type $func) (result i32)
(i32.const 0)
)
)
;; As above, but there are additional element segments.
(module
;; CHECK: (type $func (func (result i32)))
(type $func (func (result i32)))
;; CHECK: (type $1 (func))
;; CHECK: (table $table 2 2 funcref (ref.func $func))
(table $table 2 2 funcref (ref.func $func))
;; CHECK: (elem $elem (i32.const 1) $other)
(elem $elem (table $table) (i32.const 1) func $other)
;; CHECK: (export "caller" (func $caller))
;; CHECK: (func $caller (type $1)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller (export "caller")
;; This can be optimized to a call to $func, using the default
(drop
(call_indirect $table (type $func)
(i32.const 0)
)
)
;; This can be optimized to a call to $other, using the elem.
(drop
(call_indirect $table (type $func)
(i32.const 1)
)
)
;; This is out of bounds, and traps.
(drop
(call_indirect $table (type $func)
(i32.const 999)
)
)
)
;; CHECK: (func $func (type $func) (result i32)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $func (type $func) (result i32)
(i32.const 0)
)
;; CHECK: (func $other (type $func) (result i32)
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
(func $other (type $func) (result i32)
(i32.const 1)
)
)