| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. |
| |
| ;; Test the optimal path of closed-world and traps-never happen, compared to the |
| ;; default of open world with trapping. |
| |
| ;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements --closed-world -tnh -all -S -o - | filecheck %s --check-prefix CLOSED_TNH |
| ;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements -all -S -o - | filecheck %s --check-prefix OPEN_TRAPS |
| |
| ;; A table with a single elem with non-constant offset that we can remove. |
| ;; Usually a non-constant segment suggests it might overlap with others, which |
| ;; causes us to keep all elems, but here there is just one, so we can optimize. |
| ;; We require closed world (to know about which calls can reach it - the only |
| ;; call is to type $func, so elem $elem which contains $other is not needed). |
| ;; We also require traps-never-happen, as an elem with non-constant offset can |
| ;; trap, normally. When both closed world and tnh, we remove elem $elem. |
| (module |
| ;; CLOSED_TNH: (type $func (func)) |
| ;; OPEN_TRAPS: (type $func (func)) |
| (type $func (func)) |
| |
| ;; OPEN_TRAPS: (type $other (func (result i32))) |
| (type $other (func (result i32))) |
| |
| ;; OPEN_TRAPS: (import "a" "b" (global $offset i32)) |
| (import "a" "b" (global $offset i32)) |
| |
| ;; CLOSED_TNH: (table $table 6 6 funcref) |
| ;; OPEN_TRAPS: (table $table 6 6 funcref) |
| (table $table 6 6 funcref) |
| |
| ;; OPEN_TRAPS: (elem $elem (global.get $offset) $other) |
| (elem $elem (global.get $offset) $other) |
| |
| ;; OPEN_TRAPS: (export "export" (func $export)) |
| |
| ;; OPEN_TRAPS: (func $other (type $other) (result i32) |
| ;; OPEN_TRAPS-NEXT: (i32.const 42) |
| ;; OPEN_TRAPS-NEXT: ) |
| (func $other (type $other) (result i32) |
| (i32.const 42) |
| ) |
| |
| ;; CLOSED_TNH: (export "export" (func $export)) |
| |
| ;; CLOSED_TNH: (func $export (type $func) |
| ;; CLOSED_TNH-NEXT: (call_indirect $table (type $func) |
| ;; CLOSED_TNH-NEXT: (i32.const 0) |
| ;; CLOSED_TNH-NEXT: ) |
| ;; CLOSED_TNH-NEXT: ) |
| ;; OPEN_TRAPS: (func $export (type $func) |
| ;; OPEN_TRAPS-NEXT: (call_indirect $table (type $func) |
| ;; OPEN_TRAPS-NEXT: (i32.const 0) |
| ;; OPEN_TRAPS-NEXT: ) |
| ;; OPEN_TRAPS-NEXT: ) |
| (func $export (export "export") |
| ;; Call with type $func, but the table contains $other. |
| (call_indirect $table (type $func) |
| (i32.const 0) |
| ) |
| ) |
| ) |
| |
| ;; As above, but now we have two segments, one constant. We don't know if they |
| ;; overlap, so we normally assume the worst. However, with tnh, we can assume no |
| ;; traps, and remove elem $elem. (We cannot remove elem $second in either case, |
| ;; as it contains a function we have an indirect call for its type.) |
| (module |
| ;; CLOSED_TNH: (type $func (func)) |
| ;; OPEN_TRAPS: (type $func (func)) |
| (type $func (func)) |
| |
| ;; OPEN_TRAPS: (type $other (func (result i32))) |
| (type $other (func (result i32))) |
| |
| ;; OPEN_TRAPS: (import "a" "b" (global $offset i32)) |
| (import "a" "b" (global $offset i32)) |
| |
| ;; CLOSED_TNH: (table $table 6 6 funcref) |
| ;; OPEN_TRAPS: (table $table 6 6 funcref) |
| (table $table 6 6 funcref) |
| |
| ;; OPEN_TRAPS: (elem $elem (global.get $offset) $other) |
| (elem $elem (global.get $offset) $other) |
| |
| ;; CLOSED_TNH: (elem $second (i32.const 0) $export) |
| ;; OPEN_TRAPS: (elem $second (i32.const 0) $export) |
| (elem $second (i32.const 0) $export) |
| |
| ;; OPEN_TRAPS: (export "export" (func $export)) |
| |
| ;; OPEN_TRAPS: (func $other (type $other) (result i32) |
| ;; OPEN_TRAPS-NEXT: (i32.const 42) |
| ;; OPEN_TRAPS-NEXT: ) |
| (func $other (type $other) (result i32) |
| (i32.const 42) |
| ) |
| |
| ;; CLOSED_TNH: (export "export" (func $export)) |
| |
| ;; CLOSED_TNH: (func $export (type $func) |
| ;; CLOSED_TNH-NEXT: (call_indirect $table (type $func) |
| ;; CLOSED_TNH-NEXT: (i32.const 0) |
| ;; CLOSED_TNH-NEXT: ) |
| ;; CLOSED_TNH-NEXT: ) |
| ;; OPEN_TRAPS: (func $export (type $func) |
| ;; OPEN_TRAPS-NEXT: (call_indirect $table (type $func) |
| ;; OPEN_TRAPS-NEXT: (i32.const 0) |
| ;; OPEN_TRAPS-NEXT: ) |
| ;; OPEN_TRAPS-NEXT: ) |
| (func $export (export "export") |
| (call_indirect $table (type $func) |
| (i32.const 0) |
| ) |
| ) |
| ) |
| |