diff options
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-iit.wast | 18 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 185 |
2 files changed, 202 insertions, 1 deletions
diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast index 10bbbfc4a..5409e14c4 100644 --- a/test/lit/passes/optimize-instructions-gc-iit.wast +++ b/test/lit/passes/optimize-instructions-gc-iit.wast @@ -136,4 +136,22 @@ ) ) ) + + ;; CHECK: (func $ref-eq-ref-cast (param $x eqref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-ref-cast (param $x eqref) + ;; we can look through a ref.cast if we ignore traps + (drop + (ref.eq + (local.get $x) + (ref.cast + (local.get $x) + (rtt.canon $parent) + ) + ) + ) + ) ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index b00d08193..33f7bef78 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. -;; RUN: wasm-opt %s --optimize-instructions --enable-reference-types --enable-gc -S -o - \ +;; RUN: wasm-opt %s --remove-unused-names --optimize-instructions --enable-reference-types --enable-gc -S -o - \ ;; RUN: | filecheck %s (module @@ -533,4 +533,187 @@ ) ) ) + + ;; CHECK: (func $get-eqref (result eqref) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $get-eqref (result eqref) + (unreachable) + ) + + ;; CHECK: (func $ref-eq (param $x eqref) (param $y eqref) + ;; CHECK-NEXT: (local $lx eqref) + ;; CHECK-NEXT: (local $ly eqref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $lx + ;; CHECK-NEXT: (call $get-eqref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq (param $x eqref) (param $y eqref) + (local $lx eqref) + (local $ly eqref) + ;; identical parameters are equal + (drop + (ref.eq + (local.get $x) + (local.get $x) + ) + ) + ;; different ones might not be + (drop + (ref.eq + (local.get $x) + (local.get $y) + ) + ) + ;; identical locals are + (local.set $lx + (call $get-eqref) + ) + (drop + (ref.eq + (local.get $lx) + (local.get $lx) + ) + ) + ;; fallthroughs work ok (but we need --remove-unused-names so that we can + ;; trivially tell that there are no breaks) + (drop + (ref.eq + (block (result eqref) + (nop) + (local.get $x) + ) + (block (result eqref) + (nop) + (drop + (i32.const 10) + ) + (nop) + (local.get $x) + ) + ) + ) + ) + + (func $nothing) + + ;; CHECK: (func $ref-eq-corner-cases (param $x eqref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result eqref) + ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result eqref) + ;; CHECK-NEXT: (call $nothing) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (struct.new_default_with_rtt $struct + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.new_default_with_rtt $struct + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-corner-cases (param $x eqref) + ;; side effects prevent optimization + (drop + (ref.eq + (block (result eqref) + (call $nothing) + (local.get $x) + ) + (block (result eqref) + (call $nothing) + (local.get $x) + ) + ) + ) + ;; allocation prevents optimization + (drop + (ref.eq + (struct.new_default_with_rtt $struct + (rtt.canon $struct) + ) + (struct.new_default_with_rtt $struct + (rtt.canon $struct) + ) + ) + ) + ;; but irrelevant allocations do not prevent optimization + (drop + (ref.eq + (block (result eqref) + ;; an allocation that does not trouble us + (drop + (struct.new_default_with_rtt $struct + (rtt.canon $struct) + ) + ) + (local.get $x) + ) + (block (result eqref) + (drop + (struct.new_default_with_rtt $struct + (rtt.canon $struct) + ) + ) + ;; add a nop to make the two inputs to ref.eq not structurally equal, + ;; but in a way that does not matter (since only the value falling + ;; out does) + (nop) + (local.get $x) + ) + ) + ) + ) + + ;; CHECK: (func $ref-eq-ref-cast (param $x eqref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-ref-cast (param $x eqref) + ;; it is almost valid to look through a cast, except that it might trap so + ;; there is a side effect + (drop + (ref.eq + (local.get $x) + (ref.cast + (local.get $x) + (rtt.canon $struct) + ) + ) + ) + ) ) |