| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. |
| ;; RUN: foreach %s %t wasm-opt -all --dae2 -S -o - | filecheck %s |
| |
| (module |
| ;; CHECK: (type $f (func (param i32))) |
| (type $f (func (param i32))) |
| ;; CHECK: (type $no-funcs (func (param i64))) |
| (type $no-funcs (func (param i64))) |
| |
| ;; CHECK: (type $2 (func)) |
| |
| ;; CHECK: (type $3 (func (param i32 i64 (ref $no-funcs)))) |
| |
| ;; CHECK: (table $t 1 1 funcref) |
| (table $t funcref (elem $referenced)) |
| |
| ;; CHECK: (elem $implicit-elem (i32.const 0) $referenced) |
| |
| ;; CHECK: (func $referenced (type $f) (param $unused i32) |
| ;; CHECK-NEXT: (nop) |
| ;; CHECK-NEXT: ) |
| (func $referenced (type $f) (param $unused i32) |
| ;; Even though the parameter is not used in any use of this function type, |
| ;; we cannot optimize indirect calls in an open world. |
| (nop) |
| ) |
| |
| ;; CHECK: (func $not-referenced (type $2) |
| ;; CHECK-NEXT: (local $unused i32) |
| ;; CHECK-NEXT: (nop) |
| ;; CHECK-NEXT: ) |
| (func $not-referenced (type $f) (param $unused i32) |
| ;; Non-referenced functions with the same types can still be optimized. |
| (nop) |
| ) |
| |
| ;; CHECK: (func $caller (type $3) (param $i32 i32) (param $i64 i64) (param $func (ref $no-funcs)) |
| ;; CHECK-NEXT: (call_indirect $t (type $f) |
| ;; CHECK-NEXT: (local.get $i32) |
| ;; CHECK-NEXT: (i32.const 0) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (call_ref $f |
| ;; CHECK-NEXT: (local.get $i32) |
| ;; CHECK-NEXT: (ref.func $referenced) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (call_ref $no-funcs |
| ;; CHECK-NEXT: (local.get $i64) |
| ;; CHECK-NEXT: (local.get $func) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| (func $caller (param $i32 i32) (param $i64 i64) (param $func (ref $no-funcs)) |
| ;; Since the param remains used, we should not optimize indirect calls or |
| ;; call_refs and we should not optimize out the forwarded params. |
| (call_indirect (type $f) |
| (local.get $i32) |
| (i32.const 0) |
| ) |
| (call_ref $f |
| (local.get $i32) |
| (ref.func $referenced) |
| ) |
| ;; Even function types with no functions cannot be optimized because in |
| ;; an open world there might be external functions with the type. |
| (call_ref $no-funcs |
| (local.get $i64) |
| (local.get $func) |
| ) |
| ) |
| ) |
| |
| (module |
| ;; CHECK: (type $f (func (param i32 i64))) |
| (type $f (func (param i32 i64))) |
| ;; CHECK: (type $1 (func)) |
| |
| ;; CHECK: (func $test (type $1) |
| ;; CHECK-NEXT: (local $f (ref null $f)) |
| ;; CHECK-NEXT: (call_ref $f |
| ;; CHECK-NEXT: (i32.const 0) |
| ;; CHECK-NEXT: (i64.const 1) |
| ;; CHECK-NEXT: (local.get $f) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| (func $test |
| ;; There is no function with type $f, so we can normally remove all its |
| ;; parameters. In an open world, however, a function of type $f might come |
| ;; in from the outside, so we cannot optimize. |
| (local $f (ref null $f)) |
| (call_ref $f |
| (i32.const 0) |
| (i64.const 1) |
| (local.get $f) |
| ) |
| ) |
| ) |